Skip to content
Snippets Groups Projects
Commit bcb21d55 authored by Jörn Künsemöller's avatar Jörn Künsemöller Committed by Jorrit Schaap
Browse files

TMSS-162: Add log filtering by subtask, only log updates that affect state and...

TMSS-162: Add log filtering by subtask, only log updates that affect state and add  functional test for log behavior
parent b7be0e1f
No related branches found
No related tags found
1 merge request!124Resolve TMSS-178
......@@ -181,6 +181,12 @@ class Subtask(BasicCommon):
class SubtaskStateLog(BasicCommon):
"""
History of state changes on subtasks
This is now a very specific solution and based on what SOS communicated is what they are regularly interested in.
Maybe one or two additional log tables for other models are benefitial and should be added at some point.
Note that we could of course also log on the db level and there is also a variety of audit middlewares for Django
available to keep track of changes more generally: https://djangopackages.org/grids/g/model-audit/
This seems a bit overkill at the moment and we have to manage access to those logs etc., this needs tbd.
"""
user = ForeignKey(User, null=False, editable=False, on_delete=PROTECT, help_text='The user who changed the state of the subtask.')
user_identifier = CharField(null=False, editable=False, max_length=128, help_text='The ID of the user who changed the state of the subtask.')
......
......@@ -172,7 +172,11 @@ class SubtaskSerializerJSONeditorOnline(RelationalHyperlinkedModelSerializer):
# todo: Shall we use one of the default templates for the init?
logger.warning('Could not determine schema, hence no fancy JSON form. Expected for list view.')
# Intercept updates to also create a log entry
def update(self, instance, validated_data):
if instance.state is not None \
and validated_data.get('state') is not None \
and instance.state != validated_data.get('state'):
user = self.context.get('request').user
log_entry = models.SubtaskStateLog(user=user,
user_identifier=user.email,
......@@ -180,8 +184,7 @@ class SubtaskSerializerJSONeditorOnline(RelationalHyperlinkedModelSerializer):
old_state=instance.state,
new_state=validated_data.get('state'))
log_entry.save()
super().update(instance, validated_data)
return instance
return super().update(instance, validated_data)
class Meta:
model = models.Subtask
......
......@@ -43,6 +43,17 @@ class SubtaskStateViewSet(LOFARViewSet):
class SubtaskStateLogViewSet(LOFARViewSet):
def get_queryset(self):
queryset = models.SubtaskStateLog.objects.all()
# query by subtask
subtask = self.request.query_params.get('subtask', None)
if subtask is not None:
return queryset.filter(subtask=subtask)
return queryset
queryset = models.SubtaskStateLog.objects.all()
serializer_class = serializers.SubtaskStateLogSerializer
......
......@@ -378,6 +378,31 @@ class SubtaskTestCase(unittest.TestCase):
self.assertTrue("ProtectedError" in str(response.content))
GET_and_assert_expected_response(self, specifications_template_url, 200, stt_test_data)
def test_subtask_state_log_records(self):
st_test_data = test_data_creator.Subtask()
# POST new item, verify
r_dict = POST_and_assert_expected_response(self, BASE_URL + '/subtask/', st_test_data, 201, st_test_data)
url = r_dict['url']
GET_and_assert_expected_response(self, url, 200, st_test_data)
# Verify state log count is zero
segments = url.split('/')
identifier = ''
while identifier == '':
identifier = segments.pop()
GET_and_assert_expected_response(self, BASE_URL + '/subtask_state_log/?subtask=' + identifier, 200, {"count":0})
# PATCH item with something else than state and verify no log record is created
test_patch = {"specifications_doc": {"somespec": "somevalue"}}
PATCH_and_assert_expected_response(self, url, test_patch, 200, test_patch)
GET_and_assert_expected_response(self, BASE_URL + '/subtask_state_log/?subtask=' + identifier, 200, {"count": 0})
# PATCH item with state update and verify log record is created
test_patch = {"state": BASE_URL + "/subtask_state/finishing/"}
PATCH_and_assert_expected_response(self, url, test_patch, 200, test_patch)
GET_and_assert_expected_response(self, BASE_URL + '/subtask_state_log/?subtask=' + identifier, 200, {"count": 1})
class DataproductTestCase(unittest.TestCase):
@classmethod
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment