Skip to content

Commit

Permalink
Included test showing replaced attachment functionality
Browse files Browse the repository at this point in the history
Moved soft delete action to the instance model
Restructured how we call the soft_delete action when editing submissions
  • Loading branch information
WinnyTroy committed Feb 17, 2020
1 parent 101f22a commit 9d7bc33
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 16 deletions.
13 changes: 0 additions & 13 deletions onadata/apps/logger/models/attachment.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,16 +90,3 @@ def file_hash(self):
def filename(self):
if self.media_file:
return os.path.basename(self.media_file.name)

@classmethod
def soft_delete(self, instance, user=None):
"""
Soft deletes an attachment by adding a deleted_at timestamp.
"""
if instance:
queryset = self.__class__.objects.filter(
name__in=self.get_expexted_media())
kwargs = {'deleted_at': timezone.now()}
if user:
kwargs.update({'deleted_by': user})
queryset.update(**kwargs)
12 changes: 12 additions & 0 deletions onadata/apps/logger/models/instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"""
import math
from datetime import datetime
from django.db.models import Q

from future.utils import python_2_unicode_compatible

Expand Down Expand Up @@ -586,6 +587,17 @@ def set_deleted(self, deleted_at=timezone.now(), user=None):
self.xform.submission_count(force_update=True)
self.parsed_instance.save()

def soft_delete_attachments(self, user=None):
"""
Soft deletes an attachment by adding a deleted_at timestamp.
"""
queryset = self.attachments.filter(
~Q(name__in=self.get_expected_media()))
kwargs = {'deleted_at': timezone.now()}
if user:
kwargs.update({'deleted_by': user})
queryset.update(**kwargs)


def post_save_submission(sender, instance=None, created=False, **kwargs):
if ASYNC_POST_SUBMISSION_PROCESSING_ENABLED:
Expand Down
82 changes: 82 additions & 0 deletions onadata/libs/tests/utils/test_logger_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from io import BytesIO

from django.conf import settings
from mock import patch

from pyxform.tests_v1.pyxform_test_case import PyxformTestCase

Expand Down Expand Up @@ -236,6 +237,87 @@ def test_attachment_tracking_for_nested_repeats(self):
self.assertEquals(instance2.json[MEDIA_ALL_RECEIVED],
instance2.media_all_received)

def test_replaced_attachments_not_tracked(self):
"""
Test that when a submission with an attachments is made,
and later edited, whereby the attachment is replaced,
the replaced attachment is no longer tracked for that
submission
"""
md = """
| survey | | | |
| | type | name | label |
| | begin repeat | images | Photos |
| | image | image1 | Photo |
| | end repeat | | |
"""
self._create_user_and_login()
self.xform = self._publish_markdown(md, self.user)

xml_string = """
<data id="{}">
<meta>
<instanceID>uuid:UJ5jz4EszdgH8uhy8nss1AsKaqBPO5VN7</instanceID>
</meta>
<images>
<image1>1300221157303.jpg</image1>
</images>
</data>
""".format(self.xform.id_string)
file_path = "{}/apps/logger/tests/Health_2011_03_13."\
"xml_2011-03-15_20-30-28/1300221157303"\
".jpg".format(settings.PROJECT_ROOT)
media_file = django_file(
path=file_path, field_name="image1", content_type="image/jpeg")
instance = create_instance(
self.user.username,
BytesIO(xml_string.strip().encode('utf-8')),
media_files=[media_file])
self.assertTrue(instance.json[MEDIA_ALL_RECEIVED])
self.assertEquals(instance.json[TOTAL_MEDIA], 1)
self.assertEquals(instance.json[MEDIA_COUNT], 1)
self.assertEquals(instance.json[TOTAL_MEDIA], instance.total_media)
self.assertEquals(instance.json[MEDIA_COUNT], instance.media_count)
self.assertEquals(instance.json[MEDIA_ALL_RECEIVED],
instance.media_all_received)
patch_value = 'onadata.apps.logger.models.Instance.get_expected_media'
with patch(patch_value) as get_expected_media:
get_expected_media.return_value = ['1300375832136.jpg']
updated_xml_string = """
<data id="{}">
<meta>
<instanceID>uuid:UJ5jz4EszdgH8uhy8nss1AsKaqBPO5VN7</instanceID>
</meta>
<images>
<image1>1300375832136.jpg</image1>
</images>
</data>
""".format(self.xform.id_string)
file2_path = "{}/apps/logger/tests/Water_2011_03_17_2011"\
"-03-17_16-29-59/1300375832136.jpg".format(
settings.PROJECT_ROOT)
media2_file = django_file(
path=file2_path,
field_name="image1",
content_type="image/jpeg")
create_instance(
self.user.username,
BytesIO(updated_xml_string.strip().encode('utf-8')),
media_files=[media2_file])

instance2 = Instance.objects.get(pk=instance.pk)
self.assertTrue(instance2.json[MEDIA_ALL_RECEIVED])
# Test that only one attachment is recognised for this submission
self.assertEquals(instance2.json[TOTAL_MEDIA], 1)
self.assertEquals(instance2.json[MEDIA_COUNT], 1)
self.assertEquals(
instance2.json[TOTAL_MEDIA], instance2.total_media)
self.assertEquals(
instance2.json[MEDIA_COUNT], instance2.media_count)
self.assertEquals(
instance2.json[MEDIA_ALL_RECEIVED],
instance2.media_all_received)

def test_attachment_tracking_duplicate(self):
"""
Test that duplicate attachments does not affect if all attachments were
Expand Down
4 changes: 1 addition & 3 deletions onadata/libs/utils/logger_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,9 +242,7 @@ def save_attachments(xform, instance, media_files, remove_deleted_media=False):
name=filename,
extension=extension)
if remove_deleted_media:
Attachment.soft_delete(
instance.attachments.filter(
~Q(name__in=instance.get_expected_media())))
instance.soft_delete_attachments()

update_attachment_tracking(instance)

Expand Down

0 comments on commit 9d7bc33

Please sign in to comment.