Skip to content

Commit d19c80a

Browse files
committed
Track granular form updates
Signed-off-by: Kipchirchir Sigei <[email protected]>
1 parent 05deef8 commit d19c80a

File tree

6 files changed

+89
-34
lines changed

6 files changed

+89
-34
lines changed

onadata/apps/api/tests/viewsets/test_xform_viewset.py

+37-3
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@
6060
from onadata.apps.logger.xform_instance_parser import XLSFormError
6161
from onadata.apps.main.models import MetaData
6262
from onadata.apps.messaging.constants import (
63-
FORM_UPDATED, XFORM, PROJECT, FORM_DELETED, FORM_CREATED
63+
FORM_UPDATED, XFORM, PROJECT, FORM_DELETED, FORM_CREATED,
64+
FORM_RENAMED, FORM_ACTIVE
6465
)
6566
from onadata.apps.viewer.models import Export
6667
from onadata.apps.viewer.models.export import ExportTypeError
@@ -1351,7 +1352,7 @@ def test_publish_xlsform(self, mock_send_message):
13511352
self.assertTrue(mock_send_message.called)
13521353
mock_send_message.assert_called_with(
13531354
instance_id=xform.id,
1354-
target_id=xform.project.pk,
1355+
target_id=xform.pk,
13551356
target_type=XFORM,
13561357
user=request.user,
13571358
message_verb=FORM_CREATED
@@ -1789,7 +1790,8 @@ def test_publish_invalid_xls_form_no_choices(self):
17891790
)
17901791
self.assertEqual(response.data.get("text"), error_msg)
17911792

1792-
def test_partial_update(self):
1793+
@patch("onadata.apps.api.viewsets.xform_viewset.send_message")
1794+
def test_partial_update(self, mock_send_message):
17931795
with HTTMock(enketo_mock):
17941796
self._publish_xls_form_to_project()
17951797
view = XFormViewSet.as_view({"patch": "partial_update"})
@@ -1813,6 +1815,38 @@ def test_partial_update(self):
18131815
request = self.factory.patch("/", data=data, **self.extra)
18141816
response = view(request, pk=self.xform.id)
18151817
self.assertEqual(response.status_code, 200)
1818+
1819+
# send messages upon form update
1820+
self.assertTrue(mock_send_message.called)
1821+
1822+
# check calls to send_message triggered by patch request
1823+
mock_calls = mock_send_message.call_args_list
1824+
args, kwargs = mock_calls[0]
1825+
# test form rename message
1826+
message_kwargs = {
1827+
"instance_id": self.xform.id,
1828+
"target_id": self.xform.id,
1829+
"target_type": XFORM,
1830+
"user": self.xform.user,
1831+
"message_verb": FORM_RENAMED,
1832+
"custom_message": {
1833+
"old_title": "transportation_2011_07_25",
1834+
"new_title": "Hello & World!"
1835+
}
1836+
}
1837+
self.assertEqual(kwargs, message_kwargs)
1838+
1839+
# test form status message
1840+
args, kwargs = mock_calls[1]
1841+
message_kwargs = {
1842+
"instance_id": self.xform.id,
1843+
"target_id": self.xform.id,
1844+
"target_type": XFORM,
1845+
"user": self.xform.user,
1846+
"message_verb": FORM_ACTIVE,
1847+
}
1848+
self.assertEqual(kwargs, message_kwargs)
1849+
18161850
xform_old_hash = self.xform.hash
18171851
self.xform.refresh_from_db()
18181852
self.assertTrue(self.xform.downloadable)

onadata/apps/api/viewsets/project_viewset.py

+8-17
Original file line numberDiff line numberDiff line change
@@ -229,14 +229,6 @@ def share(self, request, *args, **kwargs):
229229
DEFAULT_FROM_EMAIL,
230230
(user.email,),
231231
)
232-
# send notification upon sharing project with multiple users
233-
send_message(
234-
instance_id=self.object.pk,
235-
target_id=self.object.pk,
236-
target_type=PROJECT,
237-
user=user,
238-
message_verb=message_verb
239-
)
240232
else:
241233
if email_msg:
242234
# send email if email_msg is present in payload
@@ -246,20 +238,19 @@ def share(self, request, *args, **kwargs):
246238
DEFAULT_FROM_EMAIL,
247239
(user.email,),
248240
)
249-
# send notification upon sharing project with single user
250-
send_message(
251-
instance_id=self.object.pk,
252-
target_id=self.object.pk,
253-
target_type=PROJECT,
254-
user=user,
255-
message_verb=message_verb,
256-
)
257-
258241
else:
259242
return Response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST)
260243

261244
# clear cache
262245
safe_delete(f"{PROJ_OWNER_CACHE}{self.object.pk}")
246+
# send message upon sharing/unsharing project with user
247+
send_message(
248+
instance_id=self.object.pk,
249+
target_id=self.object.pk,
250+
target_type=PROJECT,
251+
user=user,
252+
message_verb=message_verb,
253+
)
263254

264255
return Response(status=status.HTTP_204_NO_CONTENT)
265256

onadata/apps/api/viewsets/xform_viewset.py

+30-10
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,15 @@
5353
from onadata.apps.logger.models.xform_version import XFormVersion
5454
from onadata.apps.logger.xform_instance_parser import XLSFormError
5555
from onadata.apps.messaging.constants import (
56-
FORM_UPDATED, EXPORT_CREATED, XFORM,
57-
FORM_DELETED, FORM_CREATED, PROJECT
56+
FORM_UPDATED,
57+
EXPORT_CREATED,
58+
XFORM,
59+
FORM_DELETED,
60+
FORM_CREATED,
61+
PROJECT,
62+
FORM_ACTIVE,
63+
FORM_INACTIVE,
64+
FORM_RENAMED
5865
)
5966
from onadata.apps.messaging.serializers import send_message
6067
from onadata.apps.viewer.models.export import Export
@@ -84,7 +91,7 @@
8491
response_for_format,
8592
)
8693
from onadata.libs.utils.cache_tools import PROJ_OWNER_CACHE, safe_delete
87-
from onadata.libs.utils.common_tools import json_stream
94+
from onadata.libs.utils.common_tools import json_stream, str_to_bool
8895
from onadata.libs.utils.csv_import import (
8996
get_async_csv_submission_status,
9097
submission_xls_to_csv,
@@ -436,11 +443,7 @@ def create_async(self, request, *args, **kwargs):
436443
owner.id,
437444
{"name": fname, "path": xls_file_path},
438445
)
439-
resp.update(
440-
{
441-
"job_uuid": survey.task_id
442-
}
443-
)
446+
resp.update({"job_uuid": survey.task_id})
444447
resp_code = status.HTTP_202_ACCEPTED
445448

446449
# send form creation notification
@@ -844,14 +847,31 @@ def partial_update(self, request, *args, **kwargs):
844847

845848
try:
846849
# send notification for each form activity
847-
if request.POST.get("title") or request.POST.get("title"):
850+
if request.POST.get("title"):
848851
# send form update notification
849852
send_message(
850853
instance_id=self.object.pk,
851854
target_id=self.object.pk,
852855
target_type=XFORM,
853856
user=request.user or owner,
854-
message_verb=FORM_UPDATED,
857+
message_verb=FORM_RENAMED,
858+
custom_message={
859+
"old_title": self.object.title,
860+
"new_title": request.POST.get("title"),
861+
},
862+
)
863+
if request.POST.get("downloadable"):
864+
downloadable = request.POST.get("downloadable")
865+
message_verb = (
866+
FORM_ACTIVE if str_to_bool(downloadable) else FORM_INACTIVE
867+
)
868+
# send form status notification
869+
send_message(
870+
instance_id=self.object.pk,
871+
target_id=self.object.pk,
872+
target_type=XFORM,
873+
user=request.user or owner,
874+
message_verb=message_verb,
855875
)
856876
return super().partial_update(request, *args, **kwargs)
857877
except XLSFormError as e:

onadata/apps/messaging/constants.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@
3535
FORM_UPDATED = "form_updated"
3636
FORM_CREATED = "form_created"
3737
FORM_DELETED = "form_deleted"
38+
FORM_INACTIVE = "form_inactive"
39+
FORM_ACTIVE = "form_active"
40+
FORM_RENAMED = "form_renamed"
3841
EXPORT_CREATED = "export_created"
3942
EXPORT_DELETED = "export_deleted"
4043
PERMISSION_GRANTED = "permission_granted"
@@ -44,7 +47,7 @@
4447
SUBMISSION_DELETED, FORM_UPDATED, FORM_CREATED, FORM_DELETED,
4548
EXPORT_CREATED, EXPORT_DELETED, PROJECT_EDITED, PROJECT_SHARED,
4649
PROJECT_CREATED, USER_ADDED_TO_PROJECT, USER_REMOVED_FROM_PROJECT,
47-
PROJECT_DELETED
50+
PROJECT_DELETED, FORM_INACTIVE, FORM_ACTIVE
4851
]
4952
VERB_TOPIC_DICT = {
5053
SUBMISSION_CREATED: "submission/created",
@@ -54,6 +57,9 @@
5457
FORM_UPDATED: "form/updated",
5558
FORM_CREATED: "form/created",
5659
FORM_DELETED: "form/deleted",
60+
FORM_ACTIVE: "form/active",
61+
FORM_RENAMED: "form/renamed",
62+
FORM_INACTIVE: "form/inactive",
5763
EXPORT_CREATED: "export/created",
5864
EXPORT_DELETED: "export/deleted",
5965
PROJECT_CREATED: "project/created",

onadata/apps/messaging/serializers.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
from django.utils.translation import gettext as _
1818
from rest_framework import exceptions, serializers
1919

20-
from onadata.apps.logger.models import Instance
2120
from onadata.apps.messaging.constants import MESSAGE, MESSAGE_VERBS
2221
from onadata.apps.messaging.utils import TargetDoesNotExist, get_target
2322

@@ -146,6 +145,7 @@ def create(self, validated_data):
146145
return instance
147146

148147

148+
# pylint: disable=too-many-arguments
149149
def send_message(
150150
instance_id: Union[list, int],
151151
target_id: int,

onadata/apps/messaging/tests/test_utils.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
Tests messaging app utils
33
"""
44
import json
5+
from mock import patch
6+
57
from django.http.request import HttpRequest
68
from django.test.utils import override_settings
7-
from unittest.mock import patch
9+
810

911
from onadata.apps.main.tests.test_base import TestBase
1012
from onadata.apps.messaging.serializers import send_message
@@ -39,6 +41,9 @@ def is_valid():
3941

4042
@patch('onadata.apps.messaging.serializers.MessageSerializer')
4143
def test_custom_message(self, message_serializer_mock):
44+
"""
45+
Test custom_message passed into send_message function
46+
"""
4247
def is_valid():
4348
return True
4449
message_serializer_mock.is_valid.side_effect = is_valid
@@ -73,4 +78,3 @@ def is_valid():
7378
message_serializer_mock.called_with(
7479
data=data, context={"request": request}
7580
)
76-

0 commit comments

Comments
 (0)