Skip to content

Commit cf34fb7

Browse files
committed
BUG: Fixed key errors in plot card view.
Happened when surface has a successful analysis although all analyses for the related measurement fail. Closes #739.
1 parent 9955526 commit cf34fb7

File tree

3 files changed

+87
-19
lines changed

3 files changed

+87
-19
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog for *TopoBank*
22

3+
## 0.16.1 (not published yet)
4+
5+
- BUG: Missing manifest entry problem during installation
6+
fixed by using another package for fontawesone 5
7+
icons (#740)
8+
- BUG: Fixes error messages in special cases of successful
9+
surface analysis but no successful analysis for
10+
measurements (#739)
11+
312
## 0.16.0 (2021-10-18)
413

514
- ENH: Enhanced search by supporting "weblike" search

topobank/analysis/tests/test_cards.py

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
import pytest
22

33
from django.shortcuts import reverse
4+
from django.contrib.contenttypes.models import ContentType
45

5-
from topobank.manager.tests.utils import Topography1DFactory, UserFactory
6+
from topobank.manager.tests.utils import Topography1DFactory, UserFactory, SurfaceFactory
67
from topobank.manager.utils import subjects_to_json
7-
from .utils import AnalysisFunctionFactory
8+
from topobank.manager.models import Analysis, Topography, Surface
9+
10+
from .utils import AnalysisFunctionFactory, TopographyAnalysisFactory, SurfaceAnalysisFactory,\
11+
AnalysisFunctionImplementationFactory
812
from ..views import card_view_class, SimpleCardView, PlotCardView, PowerSpectrumCardView
913

1014

@@ -84,6 +88,52 @@ def test_card_templates_for_power_spectrum(client, mocker, handle_usage_statisti
8488
assert response.template_name == ['analysis/powerspectrum_card_detail.html']
8589

8690

91+
@pytest.mark.django_db
92+
def test_plot_card_if_no_successful_topo_analysis(client, handle_usage_statistics):
93+
#
94+
# Create database objects
95+
#
96+
password = "secret"
97+
user = UserFactory(password=password)
98+
topography_ct = ContentType.objects.get_for_model(Topography)
99+
surface_ct = ContentType.objects.get_for_model(Surface)
100+
func1 = AnalysisFunctionFactory(card_view_flavor='power spectrum')
101+
AnalysisFunctionImplementationFactory(function=func1, subject_type=topography_ct)
102+
AnalysisFunctionImplementationFactory(function=func1, subject_type=surface_ct)
103+
104+
surf = SurfaceFactory(creator=user)
105+
topo = Topography1DFactory(surface=surf) # also generates the surface
106+
107+
# There is a successful surface analysis, but no successful topography analysis
108+
SurfaceAnalysisFactory(task_state='su', subject_id=topo.surface.id,
109+
subject_type_id=surface_ct.id, function=func1, users=[user])
110+
111+
# add a failed analysis for the topography
112+
TopographyAnalysisFactory(task_state='fa', subject_id=topo.id,
113+
subject_type_id=topography_ct.id, function=func1, users=[user])
114+
115+
116+
assert Analysis.objects.filter(function=func1, subject_id=topo.id, subject_type_id=topography_ct.id,
117+
task_state='su').count() == 0
118+
assert Analysis.objects.filter(function=func1, subject_id=topo.id, subject_type_id=topography_ct.id,
119+
task_state='fa').count() == 1
120+
assert Analysis.objects.filter(function=func1, subject_id=topo.surface.id, subject_type_id=surface_ct.id,
121+
task_state='su').count() == 1
122+
123+
# login and request plot card view
124+
assert client.login(username=user.username, password=password)
125+
126+
response = client.post(reverse('analysis:card'), data={
127+
'function_id': func1.id,
128+
'card_id': 'card',
129+
'template_flavor': 'list',
130+
'subjects_ids_json': subjects_to_json([topo, topo.surface]), # also request results for surface here
131+
}, HTTP_X_REQUESTED_WITH='XMLHttpRequest') # we need an AJAX request
132+
133+
# should return without errors
134+
assert response.status_code == 200
135+
136+
87137
def test_card_view_class():
88138
assert card_view_class('simple') == SimpleCardView
89139
assert card_view_class('plot') == PlotCardView

topobank/analysis/views.py

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -354,18 +354,6 @@ def get_context_data(self, **kwargs):
354354

355355
analyses_success = context['analyses_success']
356356

357-
if len(analyses_success) == 0:
358-
#
359-
# Prepare plot, controls, and table with special values..
360-
#
361-
context.update(
362-
dict(plot_script="",
363-
plot_div="No successfully finished analyses available",
364-
special_values=[],
365-
topography_colors=json.dumps(list()),
366-
series_dashes=json.dumps(list())))
367-
return context
368-
369357
#
370358
# order analyses such that surface analyses are coming last (plotted on top)
371359
#
@@ -378,6 +366,23 @@ def get_context_data(self, **kwargs):
378366
# only show average for surface if more than one topography
379367
analyses_success_list.append(surface_analysis)
380368

369+
# Special case: It can happen that there is one surface with a successful analysis
370+
# but the only measurement's analysis has no success. In this case there is also
371+
# no successful analysis to display because the surface has only one measurement.
372+
373+
if len(analyses_success_list) == 0:
374+
#
375+
# Prepare plot, controls, and table with special values..
376+
#
377+
context.update(
378+
dict(plot_script="",
379+
plot_div="No successfully finished analyses available",
380+
special_values=[],
381+
topography_colors=json.dumps(list()),
382+
series_dashes=json.dumps(list())))
383+
return context
384+
385+
381386
#
382387
# Build order of subjects such that surfaces are first (used for checkbox on subjects)
383388
#
@@ -407,6 +412,7 @@ def get_context_data(self, **kwargs):
407412
num_surface_subjects = len(subject_checkbox_groups[surface_ct])
408413
else:
409414
num_surface_subjects = 0
415+
has_at_least_one_topography_subject = topography_ct in subject_checkbox_groups.keys()
410416

411417
#
412418
# Use first analysis to determine some properties for the whole plot
@@ -736,11 +742,14 @@ def get_axis_type(key):
736742
else:
737743
surface_btn_group = Div(visible=False)
738744

739-
topography_btn_group = CheckboxGroup(
740-
labels=subject_checkbox_groups[topography_ct],
741-
css_classes=["topobank-subject-checkbox", "topobank-topography-checkbox"],
742-
visible=False,
743-
active=list(range(len(subject_checkbox_groups[topography_ct]))))
745+
if has_at_least_one_topography_subject:
746+
topography_btn_group = CheckboxGroup(
747+
labels=subject_checkbox_groups[topography_ct],
748+
css_classes=["topobank-subject-checkbox", "topobank-topography-checkbox"],
749+
visible=False,
750+
active=list(range(len(subject_checkbox_groups[topography_ct]))))
751+
else:
752+
topography_btn_group = Div(visible=False)
744753

745754
subject_select_all_btn = Button(label="Select all",
746755
width_policy='min',

0 commit comments

Comments
 (0)