Repository: akvo/akvo-rsr

Issue:
Indicator update user should not change when update rejected or approved



Discussion:

Resolving patch:
diff --git a/akvo/rest/views/indicator_period_data.py b/akvo/rest/views/indicator_period_data.py
--- a/akvo/rest/views/indicator_period_data.py
+++ b/akvo/rest/views/indicator_period_data.py
@@ -107,7 +107,9 @@ def perform_update(self, serializer):
                 for dsg in serializer._disaggregations_data
             ]
         user = self.request.user
-        serializer.save(user=user)
+        status = data.get('status', None)
+        if status != 'R' and status != 'A':
+            serializer.save(user=user)
         log_data = {'audit_trail': True, 'data': data}
         LogEntry.objects.log_action(
             user_id=user.id,


Test patch:
diff --git a/akvo/rsr/tests/rest/test_indicator_period_data.py b/akvo/rsr/tests/rest/test_indicator_period_data.py
--- a/akvo/rsr/tests/rest/test_indicator_period_data.py
+++ b/akvo/rsr/tests/rest/test_indicator_period_data.py
@@ -1303,8 +1303,8 @@ def test_create_qualitative_update(self):
 
     def test_modify_update(self):
         # Given
-        username, password = 'test@akvo.org', 'password'
-        org, user = create_org_user(username, password)
+        org, user = create_org_user('test-user@akvo.org', 'password')
+        updater = self.create_user('test-updater@akvo.org', 'password', is_admin=True)
         project = ProjectFixtureBuilder()\
             .with_partner(org, Partnership.IATI_REPORTING_ORGANISATION)\
             .with_disaggregations({
@@ -1333,7 +1333,7 @@ def test_modify_update(self):
         first_disaggregation_id = update.disaggregations.first().id
         first_comment_id = update.comments.first().id
         # When
-        self.c.login(username=username, password=password)
+        self.c.login(username=updater.email, password='password')
         url = '/rest/v1/indicator_period_data_framework/{}/?format=json'
         data = {
             "id": update.id,
@@ -1365,7 +1365,7 @@ def test_modify_update(self):
         }
         self.c.patch(url.format(update.id), data=json.dumps(data), content_type='application/json')
         # Then
-        entry = self.find_audit_trails(user, update.id).first()
+        entry = self.find_audit_trails(updater, update.id).first()
         actual = json.loads(entry.change_message)['data']
         expected = {
             'value': 10.0,
@@ -1377,8 +1377,74 @@ def test_modify_update(self):
             'comments': [{'id': first_comment_id, 'comment': 'changed'}, {'comment': 'new comment'}]
         }
         self.assertEqual(expected, actual)
-        self.assertEqual(user.id, entry.user.id)
+        self.assertEqual(updater.id, entry.user.id)
         self.assertEqual(CHANGE, entry.action_flag)
+        update.refresh_from_db()
+        self.assertEqual(update.user, updater)
+
+    def test_reject_update_should_not_change_update_user(self):
+        # Given
+        org, user = create_org_user('test-user@akvo.org', 'password')
+        admin = self.create_user('test-admin@akvo.org', 'password', is_admin=True)
+        project = ProjectFixtureBuilder()\
+            .with_partner(org, Partnership.IATI_REPORTING_ORGANISATION)\
+            .with_results([{
+                'title': 'Result  #1',
+                'indicators': [{
+                    'title': 'Indicator #1',
+                    'periods': [{
+                        'period_start': date(2010, 1, 1),
+                        'period_end': date(2010, 12, 31),
+                    }]
+                }]
+            }]).build()
+        period = project.get_period(period_start=date(2010, 1, 1))
+        update = period.add_update(
+            user,
+            value=4,
+            status='P',
+            comments=['a comment']
+        )
+        # When
+        self.c.login(username=admin.email, password='password')
+        url = '/rest/v1/indicator_period_data_framework/{}/?format=json'
+        data = {'status': 'R', 'review_note': 'test'}
+        self.c.patch(url.format(update.id), data=json.dumps(data), content_type='application/json')
+        # Then
+        update.refresh_from_db()
+        self.assertEqual(update.user, user)
+
+    def test_approve_update_should_not_change_update_user(self):
+        # Given
+        org, user = create_org_user('test-user@akvo.org', 'password')
+        admin = self.create_user('test-admin@akvo.org', 'password', is_admin=True)
+        project = ProjectFixtureBuilder()\
+            .with_partner(org, Partnership.IATI_REPORTING_ORGANISATION)\
+            .with_results([{
+                'title': 'Result  #1',
+                'indicators': [{
+                    'title': 'Indicator #1',
+                    'periods': [{
+                        'period_start': date(2010, 1, 1),
+                        'period_end': date(2010, 12, 31),
+                    }]
+                }]
+            }]).build()
+        period = project.get_period(period_start=date(2010, 1, 1))
+        update = period.add_update(
+            user,
+            value=4,
+            status='P',
+            comments=['a comment']
+        )
+        # When
+        self.c.login(username=admin.email, password='password')
+        url = '/rest/v1/indicator_period_data_framework/{}/?format=json'
+        data = {'status': 'A'}
+        self.c.patch(url.format(update.id), data=json.dumps(data), content_type='application/json')
+        # Then
+        update.refresh_from_db()
+        self.assertEqual(update.user, user)
 
     def test_remove_update(self):
         # Given