Exemplo n.º 1
0
    def test_get_rrule_end(self):
        """
        Test that get_rrule_end returns the rrule end correctly
        """
        # when until is provided
        # pylint: disable=line-too-long
        rule1 = "DTSTART:20180501T210000Z RRULE:FREQ=YEARLY;BYDAY=SU;BYSETPOS=1;BYMONTH=1;UNTIL=20480521T210000Z"  # noqa
        end1 = get_rrule_end(rrulestr(rule1))
        # must be timezone aware
        self.assertTrue(timezone.is_aware(end1))
        # must be 21 may 2018
        self.assertEqual(2048, end1.year)
        self.assertEqual(5, end1.month)
        self.assertEqual(21, end1.day)

        # when count is provided instead
        rule2 = "RRULE:FREQ=DAILY;COUNT=5"
        end2 = get_rrule_end(rrulestr(rule2))
        # must be timezone aware
        self.assertTrue(timezone.is_aware(end2))
        # must be 4 days from now (5 occurrences with today as the first)
        now = timezone.now().astimezone(pytz.timezone("Africa/Nairobi"))
        then = now + timedelta(days=4)
        self.assertEqual(then.year, end2.year)
        self.assertEqual(then.month, end2.month)
        self.assertEqual(then.day, end2.day)
Exemplo n.º 2
0
    def test_get_start_end_from_timing_rules(self):
        """
        Test get_start_end_from_timing_rules
        """
        zero = ['invalid']
        one = [None]
        two = []
        three = [None, 'RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5']
        four = [
            'RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5',
            'RRULE:FREQ=DAILY;INTERVAL=10;COUNT=17',
            'DTSTART:20170521T210000Z RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5'
        ]

        self.assertEqual((None, None), get_start_end_from_timing_rules(zero))
        self.assertEqual((None, None), get_start_end_from_timing_rules(one))
        self.assertEqual((None, None), get_start_end_from_timing_rules(two))
        self.assertEqual(
            (get_rrule_start(rrulestr('RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5')),
             get_rrule_end(rrulestr('RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5'))),
            get_start_end_from_timing_rules(three))
        self.assertEqual(
            (get_rrule_start(
                rrulestr('DTSTART:20170521T210000Z RRULE:FREQ=DAILY;COUNT=5')),
             get_rrule_end(rrulestr('RRULE:FREQ=DAILY;INTERVAL=10;COUNT=17'))),
            get_start_end_from_timing_rules(four))
Exemplo n.º 3
0
def get_start_end_from_timing_rules(timing_rules: list):
    """
    Get the start and end times from timing rules

    Will return the very very first start
    and the very very last end from the provided timing_rules
    """
    start, end = None, None
    start_list = []
    end_list = []

    # remove obviously invalid
    timing_rules = [x for x in timing_rules if x]

    for timing_rule in timing_rules:
        try:
            start_list.append(get_rrule_start(rrulestr(timing_rule)))
        except ValueError:
            pass

        try:
            end_list.append(get_rrule_end(rrulestr(timing_rule)))
        except ValueError:
            pass

    if start_list:
        start = min(start_list)

    if end_list:
        end = max(end_list)

    return (start, end)
Exemplo n.º 4
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())))
Exemplo n.º 5
0
    def validate(self, attrs):
        """
        Object level validation method for TaskSerializer
        """
        if not self.instance:
            # this is a new object

            # get start from input
            start_from_input = attrs.get('start')

            # get timing rules from task locations
            tasklocation_timing_rules = []
            for location_input in attrs.get('locations_input', []):
                tasklocation_timing_rules.append(location_input['timing_rule'])

            # get start and end from timing rules
            timing_rule = attrs.get('timing_rule')
            if timing_rule is not None:
                timing_rule_start = get_rrule_start(rrulestr(timing_rule))
                timing_rule_end = get_rrule_end(rrulestr(timing_rule))
            else:
                timing_rule_start = None
                timing_rule_end = None

            if not start_from_input:
                # start was not input by user, we try and generate it from
                # timing rules
                if not timing_rule_start:
                    # we cannot determine a start time
                    raise serializers.ValidationError({
                        'timing_rule':
                        MISSING_START_DATE,
                        'start':
                        MISSING_START_DATE
                    })

                attrs['start'] = timing_rule_start

            # get end
            attrs['end'] = attrs.get('end', timing_rule_end)

        # If end date is present we validate that it is greater than start_date
        if attrs.get('end') is not None:
            # If end date is lesser than the start date raise an error
            the_start = attrs.get('start')
            if the_start is None and self.instance is not None:
                the_start = self.instance.start

            if not the_start:
                raise serializers.ValidationError(
                    {'start': INVALID_START_DATE})

            if attrs['end'] < the_start:
                raise serializers.ValidationError({'end': INVALID_END_DATE})

        # If start date is present and this is an existing object, we validate
        # that the start date is not greater than the existing end date
        if attrs.get('start') is not None and self.instance is not None\
                and self.instance.end is not None and attrs.get('start') >\
                self.instance.end:
            raise serializers.ValidationError({'start': INVALID_START_DATE})

        return super(TaskSerializer, self).validate(attrs)
Exemplo n.º 6
0
    def validate(self, attrs):
        """
        Object level validation method for TaskSerializer
        """
        if not self.instance:
            # this is a new object

            # get start from input
            start_from_input = attrs.get("start")

            # get timing rules from task locations
            tasklocation_timing_rules = []
            for location_input in attrs.get("locations_input", []):
                tasklocation_timing_rules.append(location_input["timing_rule"])

            # get start and end from timing rules
            timing_rule = attrs.get("timing_rule")
            if timing_rule is not None:
                timing_rule_start = get_rrule_start(rrulestr(timing_rule))
                timing_rule_end = get_rrule_end(rrulestr(timing_rule))
            else:
                timing_rule_start = None
                timing_rule_end = None

            if not start_from_input:
                # start was not input by user, we try and generate it from
                # timing rules
                if not timing_rule_start:
                    # we cannot determine a start time
                    raise serializers.ValidationError(
                        {"timing_rule": MISSING_START_DATE, "start": MISSING_START_DATE}
                    )

                attrs["start"] = timing_rule_start

            # get end
            attrs["end"] = attrs.get("end", timing_rule_end)

        # If end date is present we validate that it is greater than start_date
        if attrs.get("end") is not None:
            # If end date is lesser than the start date raise an error
            the_start = attrs.get("start")
            if the_start is None and self.instance is not None:
                the_start = self.instance.start

            if not the_start:
                raise serializers.ValidationError({"start": INVALID_START_DATE})

            if attrs["end"] < the_start:
                raise serializers.ValidationError({"end": INVALID_END_DATE})

        # If start date is present and this is an existing object, we validate
        # that the start date is not greater than the existing end date
        if (  # pylint: disable=bad-continuation
            attrs.get("start") is not None
            and self.instance is not None
            and self.instance.end is not None
            and attrs.get("start") > self.instance.end
        ):
            raise serializers.ValidationError({"start": INVALID_START_DATE})

        return super(TaskSerializer, self).validate(attrs)
Exemplo n.º 7
0
    def test_create_task(self):
        """
        Test that the serializer can create Task objects
        """
        mocked_target_object = mommy.make('tasking.Task')

        rule1 = mommy.make('tasking.SegmentRule')
        rule2 = mommy.make('tasking.SegmentRule')

        rrule = 'DTSTART:20180521T210000Z RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5'

        data = {
            'name': 'Cow price',
            'description': 'Some description',
            'total_submission_target': 10,
            'timing_rule': rrule,
            'target_content_type': self.task_type.id,
            'target_id': mocked_target_object.id,
            'estimated_time': 'P4DT1H15M20S',
        }

        data_with_segment_rules = data.copy()
        data_with_segment_rules['segment_rules'] = [rule1.id, rule2.id]

        serializer_instance = TaskSerializer(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'

        # 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(set([rule1.id, rule2.id]),
                         set(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)

        # Add a submission to task and assert it changes.
        mocked_submission = mommy.make('tasking.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))

        expected_fields = [
            'id', 'created', 'modified', 'name', 'parent', 'description',
            'start', 'end', 'timing_rule', 'estimated_time',
            'total_submission_target', 'user_submission_target', 'status',
            'submission_count', 'target_content_type', 'target_id',
            'segment_rules', 'locations', 'task_locations'
        ]
        self.assertEqual(set(expected_fields),
                         set(list(serializer_instance.data.keys())))
Exemplo n.º 8
0
    def test_create_task(self):
        """
        Test that the serializer can create Task objects
        """
        mocked_target_object = mommy.make("tasking.Task")

        rule1 = mommy.make("tasking.SegmentRule")
        rule2 = mommy.make("tasking.SegmentRule")

        rrule = "DTSTART:20180521T210000Z RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5"

        data = {
            "name": "Cow price",
            "description": "Some description",
            "total_submission_target": 10,
            "timing_rule": rrule,
            "target_content_type": self.task_type.id,
            "target_id": mocked_target_object.id,
            "estimated_time": "P4DT1H15M20S",
        }

        data_with_segment_rules = data.copy()
        data_with_segment_rules["segment_rules"] = [rule1.id, rule2.id]

        serializer_instance = TaskSerializer(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"

        # 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(set([rule1.id, rule2.id]),
                         set(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)

        # Add a submission to task and assert it changes.
        mocked_submission = mommy.make("tasking.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))

        expected_fields = [
            "id",
            "created",
            "modified",
            "name",
            "parent",
            "description",
            "start",
            "end",
            "timing_rule",
            "estimated_time",
            "total_submission_target",
            "user_submission_target",
            "status",
            "submission_count",
            "target_content_type",
            "target_id",
            "segment_rules",
            "locations",
            "task_locations",
        ]
        self.assertEqual(set(expected_fields),
                         set(list(serializer_instance.data.keys())))