def setUp(self): super().setUp() self.factory = APIRequestFactory() try: self.task = Task.objects.get(id=2001) except Task.DoesNotExist: task = mommy.make('main.Task', name='Quest') task.id = 2001 task.save(force_insert=True) self.task = task try: self.location = Location.objects.get(id=3001) except Location.DoesNotExist: location = mommy.make('main.Location', name='Voi') location.id = 3001 location.save(force_insert=True) self.location = location self.coco_user = mommy.make('auth.User', first_name='Coco', id=1001) mommy.make( 'main.Submission', task=self.task, location=self.location, user=self.coco_user, bounty=mommy.make( 'main.Bounty', task=task, amount=Money('50', 'KES')), submission_time=parser.parse("2018-09-04T03:39:29+00:00"), id=555 ) mommy.make( 'main.Submission', task=self.task, location=self.location, user=self.coco_user, bounty=mommy.make( 'main.Bounty', task=task, amount=Money('50', 'KES')), submission_time=parser.parse("2018-09-04T03:39:29+00:00"), id=666 ) self.data = Submission.objects.filter(id__in=[555, 666])
def test_serializer_create_bounty(self): """ Test that serializer can create a bounty """ mocked_task = mommy.make('main.Task') task = OrderedDict( type='Task', # Needs to be a string so as to not cause a conflict on # Dict assertation after serialization id=f'{mocked_task.id}') data = {"task": task, "amount": '5400.00'} serializer_instance = BountySerializer(data=data) self.assertTrue(serializer_instance.is_valid()) bounty = serializer_instance.save() # Serializer Changes the amount data['amount'] = '5400.00 KES' self.assertDictContainsSubset(data, serializer_instance.data) self.assertEqual(bounty.task, mocked_task) self.assertEqual(bounty.amount, Money('5400', 'KES')) expected_fields = ['task', 'id', 'amount', 'modified', 'created'] self.assertEqual(set(expected_fields), set(list(serializer_instance.data.keys())))
def test_delete_instance(self): """ Test delete_instance """ instance = mommy.make('ona.Instance') task = mommy.make('main.Task', name='Quest') location = mommy.make('main.Location', name='Voi') user = mommy.make('auth.User', first_name='Coco') bounty = mommy.make( 'main.Bounty', task=task, amount=Money('50', 'KES')) submission = mommy.make( 'main.Submission', task=task, location=location, user=user, submission_time=parse("2018-09-04T00:00:00+00:00"), status=Submission.APPROVED, target_object_id=instance.id, target_content_type=self.instance_type ) delete_instance(instance=instance) # the instance and submission were deleted self.assertFalse(Instance.objects.filter(id=instance.id).exists()) self.assertFalse(Submission.objects.filter(id=submission.id).exists()) # these other models were not deleted self.assertTrue(Bounty.objects.filter(id=bounty.id).exists()) self.assertTrue(Location.objects.filter(id=location.id).exists()) self.assertTrue(User.objects.filter(id=user.id).exists()) self.assertTrue(Task.objects.filter(id=task.id).exists())
def test_method_create_bounty(self): """ Test create_bounty """ Bounty.objects.all().delete() bounty = create_bounty(task=mommy.make('main.Task'), amount=Money('5400', 'KES')) self.assertEqual(bounty, Bounty.objects.first())
def setUp(self): super().setUp() self.factory = APIRequestFactory() self.expected = b"id,user,user_id,task,task_id,location,location_id,submission_time,approved,status,comments,amount,currency,phone_number,payment_number\r\n888,Coco,1377,Quest,2001,Voi,1000,2018-09-04T00:00:00+00:00,True,a,,50.00,KES,,\r\n999,Coco,1377,Quest,2001,Voi,1000,2018-09-04T00:00:00+00:00,True,a,,50.00,KES,,\r\n" # noqa # make two submissions that work with self.expected try: self.task = Task.objects.get(id=2001) except Task.DoesNotExist: task = mommy.make('main.Task', name='Quest') task.id = 2001 task.save(force_insert=True) self.task = task try: self.location = Location.objects.get(id=1000) except Location.DoesNotExist: location = mommy.make('main.Location', name='Voi') location.id = 1000 location.save(force_insert=True) self.location = location self.coco_user = mommy.make('auth.User', first_name='Coco', id=1377) mommy.make('main.Submission', task=self.task, location=self.location, user=self.coco_user, bounty=mommy.make('main.Bounty', task=self.task, amount=Money('50', 'KES')), submission_time=parse("2018-09-04T00:00:00+00:00"), status=Submission.APPROVED, id=888) mommy.make('main.Submission', task=self.task, location=self.location, user=self.coco_user, bounty=mommy.make('main.Bounty', task=self.task, amount=Money('50', 'KES')), submission_time=parse("2018-09-04T00:00:00+00:00"), status=Submission.APPROVED, id=999)
def test_delete_instance_atomic(self): """ Test delete_instance is atomic """ instance = mommy.make('ona.Instance') task = mommy.make('main.Task', name='Quest') location = mommy.make('main.Location', name='Voi') user = mommy.make('auth.User', first_name='Coco') bounty = mommy.make( 'main.Bounty', task=task, amount=Money('50', 'KES')) submission = mommy.make( 'main.Submission', task=task, location=location, user=user, submission_time=parse("2018-09-04T00:00:00+00:00"), status=Submission.APPROVED, target_object_id=instance.id, target_content_type=self.instance_type ) with patch('kaznet.apps.main.models.Submission.delete') as mock: # we want a database-level error to happen when we attempt to # delete a submission mock.side_effect = IntegrityError # this is necessary so that this test does not fail here with self.assertRaises(IntegrityError): delete_instance(instance=instance) # nothing was deleted self.assertTrue(Instance.objects.filter(id=instance.id).exists()) self.assertTrue(Submission.objects.filter(id=submission.id).exists()) self.assertTrue(Bounty.objects.filter(id=bounty.id).exists()) self.assertTrue(Location.objects.filter(id=location.id).exists()) self.assertTrue(User.objects.filter(id=user.id).exists()) self.assertTrue(Task.objects.filter(id=task.id).exists()) with patch('kaznet.apps.ona.models.Instance.delete') as mock: # we want a database-level error to happen when we attempt to # delete an instance mock.side_effect = IntegrityError # this is necessary so that this test does not fail here with self.assertRaises(IntegrityError): delete_instance(instance=instance) # STILL nothing was deleted self.assertTrue(Instance.objects.filter(id=instance.id).exists()) self.assertTrue(Submission.objects.filter(id=submission.id).exists()) self.assertTrue(Bounty.objects.filter(id=bounty.id).exists()) self.assertTrue(Location.objects.filter(id=location.id).exists()) self.assertTrue(User.objects.filter(id=user.id).exists()) self.assertTrue(Task.objects.filter(id=task.id).exists())
def test_delete_project(self): """ Test delete_xform """ project = mommy.make('ona.Project') xform = mommy.make('ona.XForm', project=project) xform2 = mommy.make('ona.XForm', ona_project_id=project.ona_pk) instance = mommy.make('ona.Instance', xform=xform) task = mommy.make( 'main.Task', name='Quest', target_object_id=xform.id, target_content_type=self.xform_type, status=Task.ACTIVE ) location = mommy.make('main.Location', name='Voi') user = mommy.make('auth.User', first_name='Coco') bounty = mommy.make( 'main.Bounty', task=task, amount=Money('50', 'KES')) submission = mommy.make( 'main.Submission', task=task, location=location, user=user, submission_time=parse("2018-09-04T00:00:00+00:00"), status=Submission.APPROVED, target_object_id=instance.id, target_content_type=self.instance_type ) delete_project(project=project) # the Project, XForm, Instance and Submission were deleted self.assertFalse(Project.objects.filter(id=project.id).exists()) self.assertFalse(XForm.objects.filter(id=xform.id).exists()) self.assertFalse(XForm.objects.filter(id=xform2.id).exists()) self.assertFalse(Instance.objects.filter(id=instance.id).exists()) self.assertFalse(Submission.objects.filter(id=submission.id).exists()) # these other models were not deleted self.assertTrue(Bounty.objects.filter(id=bounty.id).exists()) self.assertTrue(Location.objects.filter(id=location.id).exists()) self.assertTrue(User.objects.filter(id=user.id).exists()) self.assertTrue(Task.objects.filter(id=task.id).exists()) # the task is now draft task.refresh_from_db() self.assertEqual(Task.DRAFT, task.status)
def test_create_task(self): """ Test that the serializer can create Task objects """ mocked_target_object = mommy.make( 'ona.XForm', title='Coconut', id_string='coconut828', version='v828', json=dict( owner="mosh", owner_url="http://example.com/mosh" ), ) rule1 = mommy.make('main.SegmentRule') rule2 = mommy.make('main.SegmentRule') rrule = 'DTSTART:20180521T210000Z RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5' data = { "type": "Task", 'name': 'Cow price', 'description': 'Some description', 'total_submission_target': 10, 'timing_rule': rrule, 'target_content_type': self.xform_type.id, 'target_id': mocked_target_object.id, 'estimated_time': 'P4DT1H15M20S', } data_with_segment_rules = data.copy() segment_rules = [ { "type": "SegmentRule", "id": rule1.id }, { "type": "SegmentRule", "id": rule2.id } ] data_with_segment_rules['segment_rules'] = segment_rules serializer_instance = KaznetTaskSerializer( data=data_with_segment_rules) self.assertTrue(serializer_instance.is_valid()) task = serializer_instance.save() # the start and end fields are going to be from the timing rule start = get_rrule_start(rrulestr(rrule)) end = get_rrule_end(rrulestr(rrule)) # Change estimated time to DD HH:MM:SS format since Serializer # Changes it to such data['estimated_time'] = '4 01:15:20' # 'type' is not returns data.pop('type') # the order of segment_rules may have changed so a dict comparison # may fail, we use `data` that does not include segment rules self.assertDictContainsSubset(data, serializer_instance.data) # we test that we do have our segment rules self.assertEqual(2, len(serializer_instance.data['segment_rules'])) # we test that submissions are equal to 0 self.assertEqual(serializer_instance.data['submission_count'], 0) self.assertEqual(task.submissions, 0) # we test that rejectedsubmissions are equal to 0 self.assertEqual( serializer_instance.data['rejected_submissions_count'], 0) self.assertEqual(task.rejected_submissions_count, 0) # we test that pending submissions are equal to 0 self.assertEqual( serializer_instance.data['pending_submissions_count'], 0) self.assertEqual(task.pending_submissions_count, 0) # we test that approved submissions are equal to 0 self.assertEqual( serializer_instance.data['approved_submissions_count'], 0) self.assertEqual(task.approved_submissions_count, 0) # we test that total_bounty_payout is 0 self.assertEqual( serializer_instance.data['total_bounty_payout'], '0 KES') self.assertEqual(task.total_bounty_payout, Money(0, 'KES')) # Add a submission to task and assert it changes. mocked_submission = mommy.make('main.Submission', task=task) self.assertTrue(mocked_submission.task, task) self.assertEqual(task.submissions, 1) self.assertEqual('Cow price', task.name) self.assertEqual('Some description', task.description) self.assertEqual(start, task.start) self.assertEqual(end, task.end) self.assertEqual(10, task.total_submission_target) # assert that the ISO 8601 String was converted to accurately self.assertEqual(task.estimated_time, timedelta(4, 4520)) # test that the segment rules for the task are as we expect self.assertEqual(rule1, task.segment_rules.get(id=rule1.id)) self.assertEqual(rule2, task.segment_rules.get(id=rule2.id)) # check that you get XForm stuff self.assertEqual( serializer_instance.data['xform_title'], mocked_target_object.title) self.assertEqual( serializer_instance.data['xform_id_string'], mocked_target_object.id_string) self.assertEqual( serializer_instance.data['xform_version'], mocked_target_object.version) self.assertEqual( serializer_instance.data['xform_owner'], mocked_target_object.json.get('owner')) self.assertEqual( serializer_instance.data['xform_owner_url'], mocked_target_object.json.get('owner_url')) # test no bounty was created since amount wasn't passed # pylint: disable=no-member self.assertEqual(Bounty.objects.all().count(), 0) expected_fields = [ 'id', 'created', 'created_by', 'created_by_name', 'modified', 'name', 'client_name', 'parent', 'description', 'xform_title', 'xform_id_string', 'approved_submissions_count', 'pending_submissions_count', 'required_expertise_display', 'rejected_submissions_count', 'total_bounty_payout', 'current_bounty_amount', 'bounty', 'start', 'required_expertise', 'client', 'end', 'status_display', 'timing_rule', 'estimated_time', 'total_submission_target', 'user_submission_target', 'status', 'submission_count', 'target_content_type', 'target_id', 'segment_rules', 'locations', 'task_locations', 'xform_ona_id', 'xform_project_id', 'xform_version', 'xform_owner', 'xform_owner_url', ] self.assertEqual(set(expected_fields), set(list(serializer_instance.data.keys())))
def test_create_task_with_bounty(self): """ Test that a bounty is created if Task is passed into KaznetTaskSerializer """ mocked_target_object = mommy.make('ona.XForm') rrule = 'DTSTART:20180521T210000Z RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5' initial_data = { "type": "Task", 'name': 'Cow price', 'description': 'Some description', 'total_submission_target': 10, 'timing_rule': rrule, 'target_content_type': self.xform_type.id, 'target_id': mocked_target_object.id, 'estimated_time': 'P4DT1H15M20S', 'amount': '5400' } with self.settings(KAZNET_DEFAULT_CURRENCY='KES'): serializer_instance = KaznetTaskSerializer( data=initial_data) self.assertTrue(serializer_instance.is_valid()) # No Bounty In System Yet # pylint: disable=no-member self.assertEqual(Bounty.objects.all().count(), 0) task = serializer_instance.save() # Bounty should have been created since amount is Present self.assertEqual(Bounty.objects.all().count(), 1) bounty = Bounty.objects.get(task=task) self.assertEqual(task.bounty, bounty) self.assertEqual(task, bounty.task) updated_data = { 'name': 'Spaceship Price', 'description': 'To the moon and back', 'timing_rule': rrule, 'target_content_type': self.xform_type.id, 'target_id': mocked_target_object.id, 'amount': '10000000' } # If amount changes in Task update create a new Bounty serializer_instance = KaznetTaskSerializer( instance=task, data=updated_data) self.assertTrue(serializer_instance.is_valid()) task = serializer_instance.save() # Retrieve Created Bounty bounty2 = Bounty.objects.get( amount=Money('10000000.00', 'KES')) self.assertEqual(bounty2.task, task) self.assertEqual(task.bounty, bounty2) # Keeps track of previous bounties self.assertEqual(bounty.task, task) self.assertEqual(Bounty.objects.all().count(), 2) # Test doesn't create a new Bounty if Amount hasnt changed updated_data = { 'name': 'Space Price', 'description': 'To the Infinity', 'timing_rule': rrule, 'target_content_type': self.xform_type.id, 'target_id': mocked_target_object.id, 'amount': '10000000' } # If amount changes in Task update create a new Bounty serializer_instance = KaznetTaskSerializer( instance=task, data=updated_data) self.assertTrue(serializer_instance.is_valid()) # No new Bounty Created self.assertEqual(Bounty.objects.all().count(), 2)
def to_internal_value(self, data): """ Custom to_internal_value for SerializableAmountField """ return Money(data, settings.KAZNET_DEFAULT_CURRENCY)
def test_delete_project_atomic(self): """ Test delete_project is atomic """ project = mommy.make('ona.Project') xform = mommy.make('ona.XForm', project=project) xform2 = mommy.make('ona.XForm', ona_project_id=project.ona_pk) instance = mommy.make('ona.Instance', xform=xform) task = mommy.make( 'main.Task', name='Quest', target_object_id=xform.id, target_content_type=self.xform_type, status=Task.ACTIVE ) location = mommy.make('main.Location', name='Voi') user = mommy.make('auth.User', first_name='Coco') bounty = mommy.make( 'main.Bounty', task=task, amount=Money('50', 'KES')) submission = mommy.make( 'main.Submission', task=task, location=location, user=user, submission_time=parse("2018-09-04T00:00:00+00:00"), status=Submission.APPROVED, target_object_id=instance.id, target_content_type=self.instance_type ) with patch('kaznet.apps.ona.models.Project.delete') as mock: # we want a database-level error to happen when we attempt to # delete a project mock.side_effect = IntegrityError # this is necessary so that this test does not fail here with self.assertRaises(IntegrityError): delete_project(project=project) # nothing deleted self.assertTrue(Project.objects.filter(id=project.id).exists()) self.assertTrue(XForm.objects.filter(id=xform.id).exists()) self.assertTrue(XForm.objects.filter(id=xform2.id).exists()) self.assertTrue(Instance.objects.filter(id=instance.id).exists()) self.assertTrue(Submission.objects.filter(id=submission.id).exists()) self.assertTrue(Bounty.objects.filter(id=bounty.id).exists()) self.assertTrue(Location.objects.filter(id=location.id).exists()) self.assertTrue(User.objects.filter(id=user.id).exists()) self.assertTrue(Task.objects.filter(id=task.id).exists()) # the task status did not change task.refresh_from_db() self.assertEqual(Task.ACTIVE, task.status) with patch('kaznet.apps.ona.utils.delete_xform') as mock: # we want a database-level error to happen when we attempt to # delete an xform, instance or submission mock.side_effect = IntegrityError # this is necessary so that this test does not fail here with self.assertRaises(IntegrityError): delete_project(project=project) # nothing deleted self.assertTrue(Project.objects.filter(id=project.id).exists()) self.assertTrue(XForm.objects.filter(id=xform.id).exists()) self.assertTrue(XForm.objects.filter(id=xform2.id).exists()) self.assertTrue(Instance.objects.filter(id=instance.id).exists()) self.assertTrue(Submission.objects.filter(id=submission.id).exists()) self.assertTrue(Bounty.objects.filter(id=bounty.id).exists()) self.assertTrue(Location.objects.filter(id=location.id).exists()) self.assertTrue(User.objects.filter(id=user.id).exists()) self.assertTrue(Task.objects.filter(id=task.id).exists()) # the task status did not change task.refresh_from_db() self.assertEqual(Task.ACTIVE, task.status) with patch('kaznet.apps.ona.utils.delete_instance') as mock: # we want a database-level error to happen when we attempt to # delete an instance or a submission mock.side_effect = IntegrityError # this is necessary so that this test does not fail here with self.assertRaises(IntegrityError): delete_project(project=project) # nothing deleted self.assertTrue(Project.objects.filter(id=project.id).exists()) self.assertTrue(XForm.objects.filter(id=xform.id).exists()) self.assertTrue(XForm.objects.filter(id=xform2.id).exists()) self.assertTrue(Instance.objects.filter(id=instance.id).exists()) self.assertTrue(Submission.objects.filter(id=submission.id).exists()) self.assertTrue(Bounty.objects.filter(id=bounty.id).exists()) self.assertTrue(Location.objects.filter(id=location.id).exists()) self.assertTrue(User.objects.filter(id=user.id).exists()) self.assertTrue(Task.objects.filter(id=task.id).exists()) # the task status did not change task.refresh_from_db() self.assertEqual(Task.ACTIVE, task.status)