Esempio n. 1
0
    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])
Esempio n. 2
0
    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())))
Esempio n. 3
0
    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())
Esempio n. 4
0
 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())
Esempio n. 5
0
    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)
Esempio n. 6
0
    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())
Esempio n. 7
0
    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)
Esempio n. 8
0
    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())))
Esempio n. 9
0
    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)
Esempio n. 10
0
 def to_internal_value(self, data):
     """
     Custom to_internal_value for SerializableAmountField
     """
     return Money(data, settings.KAZNET_DEFAULT_CURRENCY)
Esempio n. 11
0
    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)