Skip to content

Commit a0e0cdc

Browse files
committed
Added observation_flags in annotations
1 parent 5f68568 commit a0e0cdc

File tree

4 files changed

+90
-20
lines changed

4 files changed

+90
-20
lines changed

api/serializers.py

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,29 @@ def to_internal_value(self, data):
831831
class Meta:
832832
fields = ("sex", "is_blood_fed", "is_gravid")
833833

834+
class ObservationFlagsSerializer(serializers.ModelSerializer):
835+
is_favourite = WritableSerializerMethodField(
836+
field_class=serializers.BooleanField,
837+
default=False,
838+
)
839+
is_visible = WritableSerializerMethodField(
840+
field_class=serializers.BooleanField,
841+
default=True,
842+
)
843+
844+
def get_is_favourite(self, obj) -> bool:
845+
return obj.is_favourite
846+
847+
def get_is_visible(self, obj) -> bool:
848+
return obj.status != ExpertReportAnnotation.STATUS_HIDDEN
849+
850+
class Meta:
851+
model = ExpertReportAnnotation
852+
fields = (
853+
"is_favourite",
854+
"is_visible"
855+
)
856+
834857
user_hidden_obj = serializers.HiddenField(default=serializers.CurrentUserDefault())
835858

836859
user = SimpleAnnotatorUserSerializer(read_only=True)
@@ -842,6 +865,7 @@ class Meta:
842865
best_photo = SimplePhotoSerializer(read_only=True, allow_null=True)
843866
tags = TagListSerializerField(required=False, allow_empty=True)
844867
type = serializers.SerializerMethodField()
868+
observation_flags = ObservationFlagsSerializer(source='*', required=False)
845869

846870
is_flagged = WritableSerializerMethodField(
847871
field_class=serializers.BooleanField,
@@ -853,11 +877,6 @@ class Meta:
853877
default=False,
854878
)
855879

856-
is_favourite = WritableSerializerMethodField(
857-
field_class=serializers.BooleanField,
858-
default=False,
859-
)
860-
861880
def get_type(self, obj) -> Literal['short', 'long']:
862881
return 'short' if obj.simplified_annotation else 'long'
863882

@@ -867,9 +886,6 @@ def get_is_flagged(self, obj) -> bool:
867886
def get_is_decisive(self, obj) -> bool:
868887
return obj.validation_complete_executive or obj.revise
869888

870-
def get_is_favourite(self, obj) -> bool:
871-
return obj.is_favourite
872-
873889
def validate(self, data):
874890
data['user'] = data.pop('user_hidden_obj')
875891
data['validation_complete'] = True
@@ -886,11 +902,15 @@ def validate(self, data):
886902
raise serializers.ValidationError("The photo does not does not exist or does not belong to the observation.")
887903

888904
is_flagged = data.pop("is_flagged")
889-
if is_flagged:
890-
data["status"] = ExpertReportAnnotation.STATUS_FLAGGED
891-
elif not data.get("status", None):
892-
# Only set to PUBLIC if not set to HIDDEN
893-
data["status"] = ExpertReportAnnotation.STATUS_PUBLIC
905+
is_visible = data.pop("is_visible", self.ObservationFlagsSerializer().fields['is_visible'].default)
906+
# Only if status not set yet (for example classification None sets it to hidden).
907+
if not data.get("status", None):
908+
if not is_visible:
909+
data["status"] = ExpertReportAnnotation.STATUS_HIDDEN
910+
elif is_flagged:
911+
data["status"] = ExpertReportAnnotation.STATUS_FLAGGED
912+
else:
913+
data["status"] = ExpertReportAnnotation.STATUS_PUBLIC
894914

895915
data['validation_complete_executive'] = data.pop("is_decisive")
896916

@@ -951,7 +971,7 @@ class Meta:
951971
"type",
952972
"is_flagged",
953973
"is_decisive",
954-
"is_favourite",
974+
"observation_flags",
955975
"tags",
956976
"created_at",
957977
"updated_at",

api/tests/integration/identification_tasks/annotations/create.tavern.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,9 @@ stages:
9292
type: !anystr
9393
is_flagged: false
9494
is_decisive: false
95-
is_favourite: false
95+
observation_flags:
96+
is_favourite: false
97+
is_visible: true
9698
tags: !anylist
9799
created_at: !re_fullmatch \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{6}Z
98100
updated_at: !re_fullmatch \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{6}Z
@@ -156,7 +158,9 @@ stages:
156158
type: !anystr
157159
is_flagged: false
158160
is_decisive: false
159-
is_favourite: false
161+
observation_flags:
162+
is_favourite: false
163+
is_visible: true
160164
tags: !anylist
161165
created_at: !re_fullmatch \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{6}Z
162166
updated_at: !re_fullmatch \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{6}Z

api/tests/integration/identification_tasks/annotations/schema.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ variables:
2222
type: !anystr
2323
is_flagged: !anybool
2424
is_decisive: !anybool
25-
is_favourite: !anybool
25+
observation_flags:
26+
is_favourite: !anybool
27+
is_visible: !anybool
2628
created_at: !re_fullmatch \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{6}Z
2729
updated_at: !re_fullmatch \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{6}Z
2830
tags: !anylist

api/tests/test_views.py

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -796,21 +796,61 @@ def test_is_flagged_sets_status_to_flagged(self, api_client, endpoint, common_po
796796
annotation = ExpertReportAnnotation.objects.get(pk=response.data['id'])
797797
assert annotation.status == expected_result
798798

799+
def test_empty_observation_flags(self, api_client, endpoint, common_post_data, with_add_permission):
800+
post_data = common_post_data
801+
# Ensure observation_flags is not set
802+
post_data.pop('observation_flags', None)
803+
804+
response = api_client.post(
805+
endpoint,
806+
data=post_data,
807+
format='json'
808+
)
809+
assert response.status_code == status.HTTP_201_CREATED
810+
811+
assert response.data['observation_flags']['is_favourite'] == False
812+
assert response.data['observation_flags']['is_visible'] == True
813+
814+
@pytest.mark.parametrize(
815+
"is_visible, expected_result",
816+
[
817+
(True, ExpertReportAnnotation.STATUS_PUBLIC),
818+
(False, ExpertReportAnnotation.STATUS_HIDDEN),
819+
]
820+
)
821+
def test_is_visible_sets_status_to_public(self, api_client, endpoint, common_post_data, with_add_permission, is_visible, expected_result):
822+
post_data = common_post_data
823+
post_data['observation_flags'] = {
824+
'is_visible': is_visible
825+
}
826+
827+
response = api_client.post(
828+
endpoint,
829+
data=post_data,
830+
format='json'
831+
)
832+
assert response.status_code == status.HTTP_201_CREATED
833+
834+
annotation = ExpertReportAnnotation.objects.get(pk=response.data['id'])
835+
assert annotation.status == expected_result
836+
799837
@pytest.mark.parametrize(
800838
"is_favourite",
801839
[True, False]
802840
)
803841
def test_is_favourite_creates_FavoritedReports(self, api_client, endpoint, common_post_data, with_add_permission, is_favourite):
804842
post_data = common_post_data
805-
post_data['is_favourite'] = is_favourite
843+
post_data['observation_flags'] = {
844+
'is_favourite': is_favourite
845+
}
806846

807847
response = api_client.post(
808848
endpoint,
809849
data=post_data,
810850
format='json'
811851
)
812852
assert response.status_code == status.HTTP_201_CREATED
813-
assert response.data['is_favourite'] == is_favourite
853+
assert response.data['observation_flags']['is_favourite'] == is_favourite
814854

815855
annotation = ExpertReportAnnotation.objects.get(pk=response.data['id'])
816856
assert annotation.is_favourite == is_favourite
@@ -834,7 +874,7 @@ def test_is_favourite_does_nothing_if_already_exists_FavoritedReports(self, api_
834874
format='json'
835875
)
836876
assert response.status_code == status.HTTP_201_CREATED
837-
assert response.data['is_favourite'] is True
877+
assert response.data['observation_flags']['is_favourite'] is True
838878

839879
annotation = ExpertReportAnnotation.objects.get(pk=response.data['id'])
840880
assert annotation.is_favourite
@@ -905,6 +945,10 @@ def test_POST_always_saves_validation_complete_True(self, pre_assign, api_client
905945
def test_classification_null_shoud_set_status_to_hidden(self, api_client, endpoint, common_post_data, with_add_permission):
906946
post_data = common_post_data
907947
post_data['classification'] = None
948+
# NOTE: force is_visible. Should set to hidden anyways.
949+
post_data['observation_flags'] = {
950+
"is_visible": True
951+
}
908952

909953
response = api_client.post(
910954
endpoint,

0 commit comments

Comments
 (0)