Ejemplo n.º 1
0
    def test_supervisor_from_awc_owner(self):
        for cls in (CaseAlertScheduleInstance, CaseTimedScheduleInstance):
            with create_case(self.domain, 'person', owner_id=self.awc1.location_id) as case:
                self.assertEqual(
                    cls(
                        domain=self.domain,
                        case_id=case.case_id,
                        recipient_type='CustomRecipient',
                        recipient_id='ICDS_SUPERVISOR_FROM_AWC_OWNER'
                    ).recipient,
                    self.ls1
                )

            with create_case(self.domain, 'person', owner_id=self.awc2.location_id) as case:
                self.assertIsNone(
                    cls(
                        domain=self.domain,
                        case_id=case.case_id,
                        recipient_type='CustomRecipient',
                        recipient_id='ICDS_SUPERVISOR_FROM_AWC_OWNER'
                    ).recipient
                )

            with create_case(self.domain, 'person') as case:
                self.assertIsNone(
                    cls(
                        domain=self.domain,
                        case_id=case.case_id,
                        recipient_type='CustomRecipient',
                        recipient_id='ICDS_SUPERVISOR_FROM_AWC_OWNER'
                    ).recipient
                )
Ejemplo n.º 2
0
    def test_parent_case_recipient(self):
        with create_case(self.domain, 'person') as child, create_case(self.domain, 'person') as parent:
            instance = CaseTimedScheduleInstance(domain=self.domain, case_id=child.case_id,
                recipient_type=CaseScheduleInstanceMixin.RECIPIENT_TYPE_PARENT_CASE)
            self.assertIsNone(instance.recipient)

            set_parent_case(self.domain, child, parent, relationship='child', identifier='parent')
            instance = CaseTimedScheduleInstance(domain=self.domain, case_id=child.case_id,
                recipient_type=CaseScheduleInstanceMixin.RECIPIENT_TYPE_PARENT_CASE)
            self.assertEqual(instance.recipient.case_id, parent.case_id)
Ejemplo n.º 3
0
    def test_case_group_recipient_with_user_data_filter(self):
        # The user data filter should have no effect here because all
        # the recipients are cases.

        schedule = TimedSchedule.create_simple_daily_schedule(
            self.domain,
            TimedEvent(time=time(9, 0)),
            SMSContent(message={'en': 'Hello'})
        )
        schedule.user_data_filter = {'role': ['nurse']}
        schedule.save()

        with create_case(self.domain, 'person') as case:
            case_group = CommCareCaseGroup(domain=self.domain, cases=[case.case_id])
            case_group.save()
            self.addCleanup(case_group.delete)

            instance = CaseTimedScheduleInstance(
                domain=self.domain,
                timed_schedule_id=schedule.schedule_id,
                recipient_type=ScheduleInstance.RECIPIENT_TYPE_CASE_GROUP,
                recipient_id=case_group.get_id,
            )
            recipients = list(instance.expand_recipients())
            self.assertEqual(len(recipients), 1)
            self.assertEqual(recipients[0].case_id, case.case_id)
Ejemplo n.º 4
0
    def test_child_case_recipient(self):
        with create_case(self.domain, 'person') as child_1, \
                create_case(self.domain, 'person') as child_2, \
                create_case(self.domain, 'person') as parent:

            instance = CaseTimedScheduleInstance(domain=self.domain, case_id=parent.case_id,
                recipient_type=CaseScheduleInstanceMixin.RECIPIENT_TYPE_ALL_CHILD_CASES)
            self.assertIsInstance(instance.recipient, list)
            self.assertEqual(len(instance.recipient), 0)

            set_parent_case(self.domain, child_1, parent, relationship='child', identifier='parent')
            set_parent_case(self.domain, child_2, parent, relationship='child', identifier='parent')

            instance = CaseTimedScheduleInstance(domain=self.domain, case_id=parent.case_id,
                recipient_type=CaseScheduleInstanceMixin.RECIPIENT_TYPE_ALL_CHILD_CASES)

            self.assertIsInstance(instance.recipient, list)
            self.assertEqual(len(instance.recipient), 2)
            self.assertItemsEqual([c.case_id for c in instance.recipient], [child_1.case_id, child_2.case_id])
Ejemplo n.º 5
0
def create_user_case(user):
    """
    Returns a context manager that yields the user case and
    deletes it on exit.
    """
    return create_case(
        user.domain,
        USERCASE_TYPE,
        owner_id=user.get_id,
        external_id=user.get_id,
        update={'hq_user_id': user.get_id},
    )
Ejemplo n.º 6
0
    def test_get_anchor_date(self):
        with create_case(self.domain, 'person') as case:
            helper = self.get_helper(case)
            with self.assertRaises(VisitSchedulerIntegrationHelper.
                                   VisitSchedulerIntegrationException):
                helper.get_anchor_date('add')

            update_case(self.domain,
                        case.case_id,
                        case_properties={'add': '2017-08-01'})
            case = CaseAccessors(self.domain).get_case(case.case_id)
            helper = self.get_helper(case)
            self.assertEqual(helper.get_anchor_date('add'), date(2017, 8, 1))
Ejemplo n.º 7
0
    def test_username_case_property_recipient(self):
        # test valid username
        with create_case(self.domain,
                         'person',
                         owner_id=self.city_location.location_id,
                         update={'recipient': 'mobile'}) as case:
            instance = CaseTimedScheduleInstance(
                domain=self.domain,
                case_id=case.case_id,
                recipient_type=CaseScheduleInstanceMixin.
                RECIPIENT_TYPE_CASE_PROPERTY_USER,
                recipient_id='recipient')
            self.assertEqual(instance.recipient.get_id,
                             self.full_mobile_user.get_id)

        # test invalid username
        with create_case(self.domain,
                         'person',
                         owner_id=self.city_location.location_id,
                         update={'recipient': 'mobile10'}) as case:
            instance = CaseTimedScheduleInstance(
                domain=self.domain,
                case_id=case.case_id,
                recipient_type=CaseScheduleInstanceMixin.
                RECIPIENT_TYPE_CASE_PROPERTY_USER,
                recipient_id='recipient')
            self.assertIsNone(instance.recipient)

        # test no username
        with create_case(self.domain,
                         'person',
                         owner_id=self.city_location.location_id) as case:
            instance = CaseTimedScheduleInstance(
                domain=self.domain,
                case_id=case.case_id,
                recipient_type=CaseScheduleInstanceMixin.
                RECIPIENT_TYPE_CASE_PROPERTY_USER,
                recipient_id='recipient')
            self.assertIsNone(instance.recipient)
Ejemplo n.º 8
0
    def test_email_case_property_recipient(self):
        with create_case(self.domain,
                         'person',
                         owner_id=self.city_location.location_id,
                         update={'recipient': '*****@*****.**'}) as case:
            instance = CaseTimedScheduleInstance(
                domain=self.domain,
                case_id=case.case_id,
                recipient_type=CaseScheduleInstanceMixin.
                RECIPIENT_TYPE_CASE_PROPERTY_EMAIL,
                recipient_id='recipient')
            self.assertEqual(instance.recipient.get_email(), '*****@*****.**')

        with create_case(self.domain,
                         'person',
                         owner_id=self.city_location.location_id) as case:
            instance = CaseTimedScheduleInstance(
                domain=self.domain,
                case_id=case.case_id,
                recipient_type=CaseScheduleInstanceMixin.
                RECIPIENT_TYPE_CASE_PROPERTY_EMAIL,
                recipient_id='recipient')
            self.assertIsNone(instance.recipient.get_email())
Ejemplo n.º 9
0
    def test_when_delegate_exists(self):
        rule = create_empty_rule(self.domain,
                                 AutomaticUpdateRule.WORKFLOW_CASE_UPDATE)
        rule.add_action(CustomActionDefinition,
                        name='ICDS_ESCALATE_TECH_ISSUE')

        with create_case(
                self.domain,
                'tech_issue',
                case_name='New Issue',
                update={
                    'ticket_level': 'block',
                    'touch_case_date': '2017-06-01',
                    'block_location_id': 'block_id',
                    'district_location_id': 'district_id',
                    'state_location_id': 'state_id',
                },
        ) as tech_issue:
            result = rule.run_actions_when_case_matches(tech_issue)
            self.assertEqual(result.num_updates, 1)
            self.assertEqual(result.num_creates, 1)
            self.assertEqual(result.num_related_updates, 0)

            tech_issue = CaseAccessors(self.domain).get_case(
                tech_issue.case_id)
            subcases = tech_issue.get_subcases(index_identifier='parent')
            self.assertEqual(len(subcases), 1)
            [tech_issue_delegate] = subcases
            self.assertEqual(
                tech_issue_delegate.get_case_property('change_in_level'), '1')

            update_case(self.domain,
                        tech_issue.case_id,
                        case_properties={'ticket_level': 'block'})
            tech_issue = CaseAccessors(self.domain).get_case(
                tech_issue.case_id)

            result = rule.run_actions_when_case_matches(tech_issue)
            self.assertEqual(result.num_updates, 1)
            self.assertEqual(result.num_creates, 0)
            self.assertEqual(result.num_related_updates, 1)

            tech_issue = CaseAccessors(self.domain).get_case(
                tech_issue.case_id)
            subcases = tech_issue.get_subcases(index_identifier='parent')
            self.assertEqual(len(subcases), 1)
            [tech_issue_delegate] = subcases
            self.assertEqual(
                tech_issue_delegate.get_case_property('change_in_level'), '2')
Ejemplo n.º 10
0
    def test_specific_case_recipient(self):
        with create_case(self.domain, 'person') as case:
            instance = ScheduleInstance(
                domain=self.domain,
                recipient_type=ScheduleInstance.RECIPIENT_TYPE_CASE,
                recipient_id=case.case_id,
            )
            self.assertEqual(instance.recipient.case_id, case.case_id)

        instance = ScheduleInstance(
            domain=self.domain,
            recipient_type=ScheduleInstance.RECIPIENT_TYPE_CASE,
            recipient_id='id-does-not-exist',
        )
        self.assertIsNone(instance.recipient)
Ejemplo n.º 11
0
    def test_no_further_escalation(self):
        rule = create_empty_rule(self.domain,
                                 AutomaticUpdateRule.WORKFLOW_CASE_UPDATE)
        rule.add_action(CustomActionDefinition,
                        name='ICDS_ESCALATE_TECH_ISSUE')

        with create_case(
                self.domain,
                'tech_issue',
                case_name='New Issue',
                update={'ticket_level': 'state'},
        ) as tech_issue:
            result = rule.run_actions_when_case_matches(tech_issue)
            self.assertEqual(result.num_updates, 0)
            self.assertEqual(result.num_creates, 0)
Ejemplo n.º 12
0
    def test_specific_case_recipient(self):
        with create_case(self.domain, 'person') as case:
            instance = ScheduleInstance(
                domain=self.domain,
                recipient_type=ScheduleInstance.RECIPIENT_TYPE_CASE,
                recipient_id=case.case_id,
            )
            self.assertEqual(instance.recipient.case_id, case.case_id)

        instance = ScheduleInstance(
            domain=self.domain,
            recipient_type=ScheduleInstance.RECIPIENT_TYPE_CASE,
            recipient_id='id-does-not-exist',
        )
        self.assertIsNone(instance.recipient)
Ejemplo n.º 13
0
    def test_owner_recipient(self):
        with create_case(self.domain, 'person', owner_id=self.city_location.location_id) as case:
            instance = CaseTimedScheduleInstance(domain=self.domain, case_id=case.case_id, recipient_type='Owner')
            self.assertTrue(isinstance(instance.recipient, SQLLocation))
            self.assertEqual(instance.recipient.location_id, self.city_location.location_id)

        with create_case(self.domain, 'person', owner_id=self.group.get_id) as case:
            instance = CaseTimedScheduleInstance(domain=self.domain, case_id=case.case_id, recipient_type='Owner')
            self.assertTrue(isinstance(instance.recipient, Group))
            self.assertEqual(instance.recipient.get_id, self.group.get_id)

        with create_case(self.domain, 'person', owner_id=self.mobile_user.get_id) as case:
            instance = CaseTimedScheduleInstance(domain=self.domain, case_id=case.case_id, recipient_type='Owner')
            self.assertTrue(isinstance(instance.recipient, CommCareUser))
            self.assertEqual(instance.recipient.get_id, self.mobile_user.get_id)

        with create_case(self.domain, 'person', owner_id=self.web_user.get_id) as case:
            instance = CaseTimedScheduleInstance(domain=self.domain, case_id=case.case_id, recipient_type='Owner')
            self.assertTrue(isinstance(instance.recipient, WebUser))
            self.assertEqual(instance.recipient.get_id, self.web_user.get_id)

        with create_case(self.domain, 'person') as case:
            instance = CaseTimedScheduleInstance(domain=self.domain, case_id=case.case_id, recipient_type='Owner')
            self.assertIsNone(instance.recipient)
Ejemplo n.º 14
0
    def test_owner_recipient(self):
        with create_case(self.domain, 'person', owner_id=self.city_location.location_id) as case:
            instance = CaseTimedScheduleInstance(domain=self.domain, case_id=case.case_id, recipient_type='Owner')
            self.assertTrue(isinstance(instance.recipient, SQLLocation))
            self.assertEqual(instance.recipient.location_id, self.city_location.location_id)

        with create_case(self.domain, 'person', owner_id=self.group.get_id) as case:
            instance = CaseTimedScheduleInstance(domain=self.domain, case_id=case.case_id, recipient_type='Owner')
            self.assertTrue(isinstance(instance.recipient, Group))
            self.assertEqual(instance.recipient.get_id, self.group.get_id)

        with create_case(self.domain, 'person', owner_id=self.mobile_user.get_id) as case:
            instance = CaseTimedScheduleInstance(domain=self.domain, case_id=case.case_id, recipient_type='Owner')
            self.assertTrue(isinstance(instance.recipient, CommCareUser))
            self.assertEqual(instance.recipient.get_id, self.mobile_user.get_id)

        with create_case(self.domain, 'person', owner_id=self.web_user.get_id) as case:
            instance = CaseTimedScheduleInstance(domain=self.domain, case_id=case.case_id, recipient_type='Owner')
            self.assertTrue(isinstance(instance.recipient, WebUser))
            self.assertEqual(instance.recipient.get_id, self.web_user.get_id)

        with create_case(self.domain, 'person') as case:
            instance = CaseTimedScheduleInstance(domain=self.domain, case_id=case.case_id, recipient_type='Owner')
            self.assertIsNone(instance.recipient)
    def test_get_visit(self):
        with create_case(self.domain, 'person') as case:
            helper = self.get_helper(case, visit_number=1)
            self.assertEqual(
                helper.get_visit(self.form).to_json(),
                self.form.schedule.visits[1].to_json()
            )

            # Repeat visits aren't supported
            helper = self.get_helper(case, visit_number=2)
            with self.assertRaises(VisitSchedulerIntegrationHelper.VisitSchedulerIntegrationException):
                helper.get_visit(self.form)

            # Index out of range
            helper = self.get_helper(case, visit_number=999)
            with self.assertRaises(VisitSchedulerIntegrationHelper.VisitSchedulerIntegrationException):
                helper.get_visit(self.form)
Ejemplo n.º 16
0
    def _test_auto_escalation(self, from_level, to_level):
        rule = create_empty_rule(self.domain,
                                 AutomaticUpdateRule.WORKFLOW_CASE_UPDATE)
        rule.add_action(CustomActionDefinition,
                        name='ICDS_ESCALATE_TECH_ISSUE')

        with create_case(
                self.domain,
                'tech_issue',
                case_name='New Issue',
                update={
                    'ticket_level': from_level,
                    'touch_case_date': '2017-06-01',
                    'block_location_id': 'block_id',
                    'district_location_id': 'district_id',
                    'state_location_id': 'state_id',
                },
        ) as tech_issue:
            properties = tech_issue.to_json()
            self.assertEqual(properties.get('ticket_level'), from_level)
            self.assertEqual(properties.get('touch_case_date'), '2017-06-01')
            self.assertIsNone(properties.get('change_in_level'))

            result = rule.run_actions_when_case_matches(tech_issue)
            self.assertEqual(result.num_updates, 1)
            self.assertEqual(result.num_creates, 1)

            tech_issue = CaseAccessors(self.domain).get_case(
                tech_issue.case_id)
            properties = tech_issue.to_json()
            self.assertEqual(properties.get('ticket_level'), to_level)
            self.assertEqual(properties.get('touch_case_date'),
                             self.todays_date)
            self.assertEqual(properties.get('change_in_level'), '1')

            subcases = tech_issue.get_subcases(index_identifier='parent')
            self.assertEqual(len(subcases), 1)
            [tech_issue_delegate] = subcases

            self.assertEqual(tech_issue_delegate.type, 'tech_issue_delegate')
            self.assertEqual(tech_issue_delegate.name, tech_issue.name)
            self.assertEqual(
                tech_issue_delegate.owner_id,
                tech_issue.get_case_property('%s_location_id' % to_level))
            self.assertEqual(
                tech_issue_delegate.get_case_property('change_in_level'), '1')
Ejemplo n.º 17
0
    def test_when_delegate_exists(self):
        rule = create_empty_rule(self.domain,
                                 AutomaticUpdateRule.WORKFLOW_CASE_UPDATE)

        with create_case(
                self.domain,
                'tech_issue',
                case_name='New Issue',
                update={
                    'ticket_level': 'block',
                    'touch_case_date': '2017-06-01',
                    'block_location_id': 'block_id',
                    'district_location_id': 'district_id',
                    'state_location_id': 'state_id',
                },
        ) as tech_issue:
            result = escalate_tech_issue(tech_issue, rule)
            self.assertEqual(result.num_updates, 1)
            self.assertEqual(result.num_creates, 1)
            self.assertEqual(result.num_related_updates, 0)

            tech_issue = CaseAccessors(self.domain).get_case(
                tech_issue.case_id)
            subcases = tech_issue.get_subcases(index_identifier='parent')
            self.assertEqual(len(subcases), 1)
            [tech_issue_delegate] = subcases
            self.assertEqual(
                tech_issue_delegate.get_case_property('change_in_level'), '1')
            self.assertEqual(tech_issue_delegate.owner_id, 'district_id')

            tech_issue = CaseAccessors(self.domain).get_case(
                tech_issue.case_id)
            result = escalate_tech_issue(tech_issue, rule)
            self.assertEqual(result.num_updates, 1)
            self.assertEqual(result.num_creates, 0)
            self.assertEqual(result.num_related_updates, 1)

            tech_issue = CaseAccessors(self.domain).get_case(
                tech_issue.case_id)
            subcases = tech_issue.get_subcases(index_identifier='parent')
            self.assertEqual(len(subcases), 1)
            [tech_issue_delegate] = subcases
            self.assertEqual(
                tech_issue_delegate.get_case_property('change_in_level'), '2')
            self.assertEqual(tech_issue_delegate.owner_id, 'state_id')
    def test_calculate_window_date(self):
        with create_case(self.domain, 'person') as case:
            helper = self.get_helper(case, window_position=VISIT_WINDOW_START)
            self.assertEqual(
                helper.calculate_window_date(self.form.schedule.visits[1], date(2017, 8, 1)),
                date(2017, 7, 30)
            )

            helper = self.get_helper(case, window_position=VISIT_WINDOW_DUE_DATE)
            self.assertEqual(
                helper.calculate_window_date(self.form.schedule.visits[1], date(2017, 8, 1)),
                date(2017, 8, 1)
            )

            helper = self.get_helper(case, window_position=VISIT_WINDOW_END)
            self.assertEqual(
                helper.calculate_window_date(self.form.schedule.visits[1], date(2017, 8, 1)),
                date(2017, 8, 4)
            )
Ejemplo n.º 19
0
    def test_ignoring_entries(self):
        with create_case(self.domain, 'person') as case:
            update_case(self.domain, case.case_id,
                case_properties={'contact_phone_number': '12345', 'contact_phone_number_is_verified': '1'})

            self.assertPhoneEntryCount(1)
            self.assertPhoneEntryCount(1, only_count_two_way=True)

            with patch('corehq.apps.sms.tasks.use_phone_entries') as patch1, \
                    patch('corehq.messaging.tasks.use_phone_entries') as patch2, \
                    patch('corehq.messaging.scheduling.models.abstract.use_phone_entries') as patch3:

                patch1.return_value = patch2.return_value = patch3.return_value = False
                update_case(self.domain, case.case_id, case_properties={'contact_phone_number': '23456'})
                case = CaseAccessors(self.domain).get_case(case.case_id)

                self.assertPhoneEntryCount(1)
                self.assertPhoneEntryCount(1, only_count_two_way=True)
                self.assertTwoWayEntry(PhoneNumber.objects.get(owner_id=case.case_id), '12345')
                self.assertEqual(Content.get_two_way_entry_or_phone_number(case), '23456')
Ejemplo n.º 20
0
    def test_ignoring_entries(self):
        with create_case(self.domain, 'person') as case:
            update_case(self.domain, case.case_id,
                case_properties={'contact_phone_number': '12345', 'contact_phone_number_is_verified': '1'})

            self.assertPhoneEntryCount(1)
            self.assertPhoneEntryCount(1, only_count_two_way=True)

            with patch('corehq.apps.sms.tasks.use_phone_entries') as patch1, \
                    patch('corehq.messaging.tasks.use_phone_entries') as patch2, \
                    patch('corehq.messaging.scheduling.models.abstract.use_phone_entries') as patch3:

                patch1.return_value = patch2.return_value = patch3.return_value = False
                update_case(self.domain, case.case_id, case_properties={'contact_phone_number': '23456'})
                case = CaseAccessors(self.domain).get_case(case.case_id)

                self.assertPhoneEntryCount(1)
                self.assertPhoneEntryCount(1, only_count_two_way=True)
                self.assertTwoWayEntry(PhoneNumber.objects.get(owner_id=case.case_id), '12345')
                self.assertEqual(Content.get_two_way_entry_or_phone_number(case), '23456')
Ejemplo n.º 21
0
    def test_ignoring_entries(self):
        with create_case(self.domain, 'person') as case:
            update_case(self.domain,
                        case.case_id,
                        case_properties={
                            'contact_phone_number': '12345',
                            'contact_phone_number_is_verified': '1'
                        })

            self.assertPhoneEntryCount(1)
            self.assertPhoneEntryCount(1, only_count_two_way=True)

            with override_settings(USE_PHONE_ENTRIES=False):
                update_case(self.domain,
                            case.case_id,
                            case_properties={'contact_phone_number': '23456'})
                case = CaseAccessors(self.domain).get_case(case.case_id)

                self.assertPhoneEntryCount(1)
                self.assertPhoneEntryCount(1, only_count_two_way=True)
                self.assertTwoWayEntry(
                    PhoneNumber.objects.get(owner_id=case.case_id), '12345')
                self.assertEqual(
                    Content.get_two_way_entry_or_phone_number(case), '23456')
Ejemplo n.º 22
0
 def create_user_case(self, user):
     create_case_kwargs = {
         'external_id': user.get_id,
         'update': {'hq_user_id': user.get_id},
     }
     return create_case(self.domain, 'commcare-user', **create_case_kwargs)
Ejemplo n.º 23
0
 def create_user_case(self, user):
     create_case_kwargs = {
         'external_id': user.get_id,
         'update': {'hq_user_id': user.get_id},
     }
     return create_case(self.domain, 'commcare-user', **create_case_kwargs)
Ejemplo n.º 24
0
 def test_case_recipient(self):
     with create_case(self.domain, 'person') as case:
         instance = CaseTimedScheduleInstance(domain=self.domain, case_id=case.case_id, recipient_type='Self')
         self.assertTrue(is_commcarecase(instance.recipient))
         self.assertEqual(instance.recipient.case_id, case.case_id)
Ejemplo n.º 25
0
    def test_timed_schedule_instance_creation(self, utcnow_patch):
        schedule = TimedSchedule.create_simple_daily_schedule(
            self.domain, time(9, 0), SMSContent(message={'en': 'Hello'}))

        rule = create_empty_rule(self.domain,
                                 AutomaticUpdateRule.WORKFLOW_SCHEDULING)

        rule.add_criteria(
            MatchPropertyDefinition,
            property_name='start_sending',
            property_value='Y',
            match_type=MatchPropertyDefinition.MATCH_EQUAL,
        )

        rule.add_action(CreateScheduleInstanceActionDefinition,
                        timed_schedule_id=schedule.schedule_id,
                        recipients=(('CommCareUser', self.user.get_id), ))

        AutomaticUpdateRule.clear_caches(
            self.domain, AutomaticUpdateRule.WORKFLOW_SCHEDULING)

        utcnow_patch.return_value = datetime(2017, 5, 1, 7, 0)
        with create_case(self.domain, 'person') as case:
            # Rule does not match, no instances created
            instances = get_case_timed_schedule_instances_for_schedule(
                case.case_id, schedule)
            self.assertEqual(instances.count(), 0)

            # Make the rule match. On the first iteration, the instance is created. On the second,
            # no new instance is created since it already exists.
            for minute in [1, 2]:
                utcnow_patch.return_value = datetime(2017, 5, 1, 7, minute)
                update_case(self.domain,
                            case.case_id,
                            case_properties={'start_sending': 'Y'})

                instances = get_case_timed_schedule_instances_for_schedule(
                    case.case_id, schedule)
                self.assertEqual(instances.count(), 1)

                self.assertEqual(instances[0].case_id, case.case_id)
                self.assertEqual(instances[0].rule_id, rule.pk)
                self.assertEqual(instances[0].timed_schedule_id,
                                 schedule.schedule_id)
                self.assertEqual(instances[0].start_date, date(2017, 5, 1))
                self.assertEqual(instances[0].domain, self.domain)
                self.assertEqual(instances[0].recipient_type, 'CommCareUser')
                self.assertEqual(instances[0].recipient_id, self.user.get_id)
                self.assertEqual(instances[0].current_event_num, 0)
                self.assertEqual(instances[0].schedule_iteration_num, 1)
                self.assertEqual(instances[0].next_event_due,
                                 datetime(2017, 5, 1, 13, 0))
                self.assertTrue(instances[0].active)

            # Make the rule not match. Instance should no longer exist.
            utcnow_patch.return_value = datetime(2017, 5, 1, 7, 3)
            update_case(self.domain,
                        case.case_id,
                        case_properties={'start_sending': 'N'})
            instances = get_case_timed_schedule_instances_for_schedule(
                case.case_id, schedule)
            self.assertEqual(instances.count(), 0)
    def test_visit_scheduler_integration(self, utcnow_patch, module_and_form_patch):
        schedule = TimedSchedule.create_simple_daily_schedule(
            self.domain,
            TimedEvent(time=time(9, 0)),
            SMSContent(message={'en': 'Hello'}),
            total_iterations=1,
        )

        rule = create_empty_rule(self.domain, AutomaticUpdateRule.WORKFLOW_SCHEDULING)

        _, definition = rule.add_action(
            CreateScheduleInstanceActionDefinition,
            timed_schedule_id=schedule.schedule_id,
            recipients=(('CommCareUser', self.user.get_id),)
        )

        module, form = get_visit_scheduler_module_and_form_for_test()

        definition.set_scheduler_module_info(CreateScheduleInstanceActionDefinition.SchedulerModuleInfo(
            enabled=True,
            app_id='n/a for test',
            form_unique_id=form.unique_id,
            visit_number=1,
            window_position=VISIT_WINDOW_START,
        ))

        definition.save()

        AutomaticUpdateRule.clear_caches(self.domain, AutomaticUpdateRule.WORKFLOW_SCHEDULING)

        utcnow_patch.return_value = datetime(2017, 8, 1, 7, 0)
        module_and_form_patch.return_value = module, form

        with create_case(self.domain, 'person') as case:
            # Schedule phase does not match, nothing is scheduled
            instances = get_case_timed_schedule_instances_for_schedule(case.case_id, schedule)
            self.assertEqual(instances.count(), 0)

            update_case(self.domain, case.case_id,
                case_properties={'add': '2017-08-01', 'current_schedule_phase': '2'})

            instances = get_case_timed_schedule_instances_for_schedule(case.case_id, schedule)
            self.assertEqual(instances.count(), 1)

            self.assertEqual(instances[0].case_id, case.case_id)
            self.assertEqual(instances[0].rule_id, rule.pk)
            self.assertEqual(instances[0].timed_schedule_id, schedule.schedule_id)
            self.assertEqual(instances[0].start_date, date(2017, 8, 6))
            self.assertEqual(instances[0].domain, self.domain)
            self.assertEqual(instances[0].recipient_type, 'CommCareUser')
            self.assertEqual(instances[0].recipient_id, self.user.get_id)
            self.assertEqual(instances[0].current_event_num, 0)
            self.assertEqual(instances[0].schedule_iteration_num, 1)
            self.assertEqual(instances[0].next_event_due, datetime(2017, 8, 6, 13, 0))
            self.assertTrue(instances[0].active)

            # If the anchor date gets updated (due to correction, for example), the schedule recalculates
            update_case(self.domain, case.case_id, case_properties={'add': '2017-08-10'})
            instances = get_case_timed_schedule_instances_for_schedule(case.case_id, schedule)
            self.assertEqual(instances.count(), 1)

            self.assertEqual(instances[0].case_id, case.case_id)
            self.assertEqual(instances[0].rule_id, rule.pk)
            self.assertEqual(instances[0].timed_schedule_id, schedule.schedule_id)
            self.assertEqual(instances[0].start_date, date(2017, 8, 15))
            self.assertEqual(instances[0].domain, self.domain)
            self.assertEqual(instances[0].recipient_type, 'CommCareUser')
            self.assertEqual(instances[0].recipient_id, self.user.get_id)
            self.assertEqual(instances[0].current_event_num, 0)
            self.assertEqual(instances[0].schedule_iteration_num, 1)
            self.assertEqual(instances[0].next_event_due, datetime(2017, 8, 15, 13, 0))
            self.assertTrue(instances[0].active)

            # If the anchor date is in the past, the schedule instance is deactivated
            update_case(self.domain, case.case_id, case_properties={'add': '2017-07-01'})
            instances = get_case_timed_schedule_instances_for_schedule(case.case_id, schedule)
            self.assertEqual(instances.count(), 1)

            self.assertEqual(instances[0].case_id, case.case_id)
            self.assertEqual(instances[0].rule_id, rule.pk)
            self.assertEqual(instances[0].timed_schedule_id, schedule.schedule_id)
            self.assertEqual(instances[0].start_date, date(2017, 7, 6))
            self.assertEqual(instances[0].domain, self.domain)
            self.assertEqual(instances[0].recipient_type, 'CommCareUser')
            self.assertEqual(instances[0].recipient_id, self.user.get_id)
            self.assertEqual(instances[0].current_event_num, 0)
            self.assertEqual(instances[0].schedule_iteration_num, 2)
            self.assertEqual(instances[0].next_event_due, datetime(2017, 7, 7, 13, 0))
            self.assertFalse(instances[0].active)

            # If the anchor date is reset, the schedule instance is reactivated
            update_case(self.domain, case.case_id, case_properties={'add': '2017-08-01'})
            instances = get_case_timed_schedule_instances_for_schedule(case.case_id, schedule)
            self.assertEqual(instances.count(), 1)

            self.assertEqual(instances[0].case_id, case.case_id)
            self.assertEqual(instances[0].rule_id, rule.pk)
            self.assertEqual(instances[0].timed_schedule_id, schedule.schedule_id)
            self.assertEqual(instances[0].start_date, date(2017, 8, 6))
            self.assertEqual(instances[0].domain, self.domain)
            self.assertEqual(instances[0].recipient_type, 'CommCareUser')
            self.assertEqual(instances[0].recipient_id, self.user.get_id)
            self.assertEqual(instances[0].current_event_num, 0)
            self.assertEqual(instances[0].schedule_iteration_num, 1)
            self.assertEqual(instances[0].next_event_due, datetime(2017, 8, 6, 13, 0))
            self.assertTrue(instances[0].active)

            # Making an arbitrary update doesn't cause any recalculating to happen
            with patch('corehq.messaging.scheduling.scheduling_partitioned.models.AbstractTimedScheduleInstance.recalculate_schedule') as recalculate_patch:
                update_case(self.domain, case.case_id, case_properties={'new_property': 'new value'})
                self.assertEqual(recalculate_patch.call_count, 0)

            instances = get_case_timed_schedule_instances_for_schedule(case.case_id, schedule)
            self.assertEqual(instances.count(), 1)

            self.assertEqual(instances[0].case_id, case.case_id)
            self.assertEqual(instances[0].rule_id, rule.pk)
            self.assertEqual(instances[0].timed_schedule_id, schedule.schedule_id)
            self.assertEqual(instances[0].start_date, date(2017, 8, 6))
            self.assertEqual(instances[0].domain, self.domain)
            self.assertEqual(instances[0].recipient_type, 'CommCareUser')
            self.assertEqual(instances[0].recipient_id, self.user.get_id)
            self.assertEqual(instances[0].current_event_num, 0)
            self.assertEqual(instances[0].schedule_iteration_num, 1)
            self.assertEqual(instances[0].next_event_due, datetime(2017, 8, 6, 13, 0))
            self.assertTrue(instances[0].active)

            # Terminate the schedule, no more schedule instances should be scheduled
            update_case(self.domain, case.case_id, case_properties={'current_schedule_phase': '-1'})
            instances = get_case_timed_schedule_instances_for_schedule(case.case_id, schedule)
            self.assertEqual(instances.count(), 0)
 def test_get_visit_scheduler_form_phase(self):
     with create_case(self.domain, 'person') as case:
         phase_num, phase = self.get_helper(case).get_visit_scheduler_form_phase(self.module)
         self.assertEqual(phase_num, 2)
         self.assertEqual(phase.to_json(), self.module.schedule_phases[1].to_json())
    def test_alert_schedule_reset(self, utcnow_patch):
        schedule = AlertSchedule.create_simple_alert(
            self.domain,
            SMSContent(message={'en': 'Hello'})
        )

        rule = create_empty_rule(self.domain, AutomaticUpdateRule.WORKFLOW_SCHEDULING)

        rule.add_criteria(
            MatchPropertyDefinition,
            property_name='start_sending',
            property_value='Y',
            match_type=MatchPropertyDefinition.MATCH_EQUAL,
        )

        rule.add_action(
            CreateScheduleInstanceActionDefinition,
            alert_schedule_id=schedule.schedule_id,
            recipients=(('CommCareUser', self.user.get_id),),
            reset_case_property_name='reset_property',
        )

        AutomaticUpdateRule.clear_caches(self.domain, AutomaticUpdateRule.WORKFLOW_SCHEDULING)

        utcnow_patch.return_value = datetime(2017, 5, 1, 7, 0)
        with create_case(self.domain, 'person') as case:
            # Rule does not match, no instances created
            instances = get_case_alert_schedule_instances_for_schedule(case.case_id, schedule)
            self.assertEqual(instances.count(), 0)

            # Make the rule match. On the first iteration, the instance is created. On the second,
            # nothing is changed.
            for minute in (1, 2):
                utcnow_patch.return_value = datetime(2017, 5, 1, 7, minute)
                update_case(self.domain, case.case_id,
                    case_properties={'start_sending': 'Y', 'reset_property': 'a'})

                instances = get_case_alert_schedule_instances_for_schedule(case.case_id, schedule)
                self.assertEqual(instances.count(), 1)

                self.assertEqual(instances[0].case_id, case.case_id)
                self.assertEqual(instances[0].rule_id, rule.pk)
                self.assertEqual(instances[0].alert_schedule_id, schedule.schedule_id)
                self.assertEqual(instances[0].domain, self.domain)
                self.assertEqual(instances[0].recipient_type, 'CommCareUser')
                self.assertEqual(instances[0].recipient_id, self.user.get_id)
                self.assertEqual(instances[0].current_event_num, 0)
                self.assertEqual(instances[0].schedule_iteration_num, 1)
                self.assertEqual(instances[0].next_event_due, datetime(2017, 5, 1, 7, 1))
                self.assertEqual(instances[0].last_reset_case_property_value, 'a')
                self.assertTrue(instances[0].active)

            # Update the reset property, and the instance is reset.
            utcnow_patch.return_value = datetime(2017, 6, 1, 7, 0)
            update_case(self.domain, case.case_id, case_properties={'reset_property': 'b'})

            instances = get_case_alert_schedule_instances_for_schedule(case.case_id, schedule)
            self.assertEqual(instances.count(), 1)

            self.assertEqual(instances[0].case_id, case.case_id)
            self.assertEqual(instances[0].rule_id, rule.pk)
            self.assertEqual(instances[0].alert_schedule_id, schedule.schedule_id)
            self.assertEqual(instances[0].domain, self.domain)
            self.assertEqual(instances[0].recipient_type, 'CommCareUser')
            self.assertEqual(instances[0].recipient_id, self.user.get_id)
            self.assertEqual(instances[0].current_event_num, 0)
            self.assertEqual(instances[0].schedule_iteration_num, 1)
            self.assertEqual(instances[0].next_event_due, datetime(2017, 6, 1, 7, 0))
            self.assertEqual(instances[0].last_reset_case_property_value, 'b')
            self.assertTrue(instances[0].active)
    def test_timed_schedule_case_property_timed_event(self, utcnow_patch):
        schedule = TimedSchedule.create_simple_daily_schedule(
            self.domain,
            CasePropertyTimedEvent(case_property_name='reminder_time'),
            SMSContent(message={'en': 'Hello'})
        )

        rule = create_empty_rule(self.domain, AutomaticUpdateRule.WORKFLOW_SCHEDULING)

        rule.add_criteria(
            MatchPropertyDefinition,
            property_name='start_sending',
            property_value='Y',
            match_type=MatchPropertyDefinition.MATCH_EQUAL,
        )

        rule.add_action(
            CreateScheduleInstanceActionDefinition,
            timed_schedule_id=schedule.schedule_id,
            recipients=(('CommCareUser', self.user.get_id),),
        )

        AutomaticUpdateRule.clear_caches(self.domain, AutomaticUpdateRule.WORKFLOW_SCHEDULING)

        utcnow_patch.return_value = datetime(2017, 5, 1, 7, 0)
        with create_case(self.domain, 'person') as case:
            # Rule does not match, no instances created
            instances = get_case_timed_schedule_instances_for_schedule(case.case_id, schedule)
            self.assertEqual(instances.count(), 0)

            # Make the rule match, but don't give a preferred time. Default scheduling time is used.
            update_case(self.domain, case.case_id, case_properties={'start_sending': 'Y'})
            instances = get_case_timed_schedule_instances_for_schedule(case.case_id, schedule)
            self.assertEqual(instances.count(), 1)

            self.assertEqual(instances[0].case_id, case.case_id)
            self.assertEqual(instances[0].rule_id, rule.pk)
            self.assertEqual(instances[0].timed_schedule_id, schedule.schedule_id)
            self.assertEqual(instances[0].start_date, date(2017, 5, 1))
            self.assertEqual(instances[0].domain, self.domain)
            self.assertEqual(instances[0].recipient_type, 'CommCareUser')
            self.assertEqual(instances[0].recipient_id, self.user.get_id)
            self.assertEqual(instances[0].current_event_num, 0)
            self.assertEqual(instances[0].schedule_iteration_num, 1)
            self.assertEqual(instances[0].next_event_due, datetime(2017, 5, 1, 16, 0))
            self.assertTrue(instances[0].active)

            # Update the preferred time, and the schedule should recalculate
            update_case(self.domain, case.case_id, case_properties={'reminder_time': '09:00'})
            instances = get_case_timed_schedule_instances_for_schedule(case.case_id, schedule)
            self.assertEqual(instances.count(), 1)
            self.assertEqual(instances[0].case_id, case.case_id)
            self.assertEqual(instances[0].rule_id, rule.pk)
            self.assertEqual(instances[0].timed_schedule_id, schedule.schedule_id)
            self.assertEqual(instances[0].start_date, date(2017, 5, 1))
            self.assertEqual(instances[0].domain, self.domain)
            self.assertEqual(instances[0].recipient_type, 'CommCareUser')
            self.assertEqual(instances[0].recipient_id, self.user.get_id)
            self.assertEqual(instances[0].current_event_num, 0)
            self.assertEqual(instances[0].schedule_iteration_num, 1)
            self.assertEqual(instances[0].next_event_due, datetime(2017, 5, 1, 13, 0))
            self.assertTrue(instances[0].active)

            # Update the preferred time to a bad value and the default time is used again.
            update_case(self.domain, case.case_id, case_properties={'reminder_time': 'x'})
            instances = get_case_timed_schedule_instances_for_schedule(case.case_id, schedule)
            self.assertEqual(instances.count(), 1)
            self.assertEqual(instances[0].case_id, case.case_id)
            self.assertEqual(instances[0].rule_id, rule.pk)
            self.assertEqual(instances[0].timed_schedule_id, schedule.schedule_id)
            self.assertEqual(instances[0].start_date, date(2017, 5, 1))
            self.assertEqual(instances[0].domain, self.domain)
            self.assertEqual(instances[0].recipient_type, 'CommCareUser')
            self.assertEqual(instances[0].recipient_id, self.user.get_id)
            self.assertEqual(instances[0].current_event_num, 0)
            self.assertEqual(instances[0].schedule_iteration_num, 1)
            self.assertEqual(instances[0].next_event_due, datetime(2017, 5, 1, 16, 0))
            self.assertTrue(instances[0].active)
Ejemplo n.º 30
0
 def test_case_recipient(self):
     with create_case(self.domain, 'person') as case:
         instance = CaseTimedScheduleInstance(domain=self.domain, case_id=case.case_id, recipient_type='Self')
         self.assertTrue(is_commcarecase(instance.recipient))
         self.assertEqual(instance.recipient.case_id, case.case_id)
    def test_start_offset(self, utcnow_patch):
        schedule = TimedSchedule.create_simple_daily_schedule(
            self.domain,
            TimedEvent(time=time(9, 0)),
            SMSContent(message={'en': 'Hello'}),
            start_offset=2,
        )

        rule = create_empty_rule(self.domain, AutomaticUpdateRule.WORKFLOW_SCHEDULING)

        rule.add_action(
            CreateScheduleInstanceActionDefinition,
            timed_schedule_id=schedule.schedule_id,
            recipients=(('CommCareUser', self.user.get_id),),
        )

        AutomaticUpdateRule.clear_caches(self.domain, AutomaticUpdateRule.WORKFLOW_SCHEDULING)
        utcnow_patch.return_value = datetime(2017, 8, 1, 15, 0)

        with create_case(self.domain, 'person') as case:
            instances = get_case_timed_schedule_instances_for_schedule(case.case_id, schedule)
            self.assertEqual(instances.count(), 1)

            self.assertEqual(instances[0].case_id, case.case_id)
            self.assertEqual(instances[0].rule_id, rule.pk)
            self.assertEqual(instances[0].timed_schedule_id, schedule.schedule_id)
            self.assertEqual(instances[0].start_date, date(2017, 8, 1))
            self.assertEqual(instances[0].domain, self.domain)
            self.assertEqual(instances[0].recipient_type, 'CommCareUser')
            self.assertEqual(instances[0].recipient_id, self.user.get_id)
            self.assertEqual(instances[0].current_event_num, 0)
            self.assertEqual(instances[0].schedule_iteration_num, 1)
            self.assertEqual(instances[0].next_event_due, datetime(2017, 8, 3, 13, 0))
            self.assertEqual(instances[0].schedule_revision, schedule.get_schedule_revision())
            self.assertTrue(instances[0].active)

            # Change the schedule's start offset and force a case update to reprocess the schedule instance.
            # The start date should not change, but the schedule instance should respond to the new start offset
            # by calculating a new next_event_due timestamp.
            schedule.start_offset = 5
            schedule.save()
            schedule = TimedSchedule.objects.get(schedule_id=schedule.schedule_id)
            utcnow_patch.return_value = datetime(2017, 8, 4, 7, 0)
            update_case(self.domain, case.case_id, case_properties={'new_property': 'new value'})

            instances = get_case_timed_schedule_instances_for_schedule(case.case_id, schedule)
            self.assertEqual(instances.count(), 1)

            self.assertEqual(instances[0].case_id, case.case_id)
            self.assertEqual(instances[0].rule_id, rule.pk)
            self.assertEqual(instances[0].timed_schedule_id, schedule.schedule_id)
            self.assertEqual(instances[0].start_date, date(2017, 8, 1))
            self.assertEqual(instances[0].domain, self.domain)
            self.assertEqual(instances[0].recipient_type, 'CommCareUser')
            self.assertEqual(instances[0].recipient_id, self.user.get_id)
            self.assertEqual(instances[0].current_event_num, 0)
            self.assertEqual(instances[0].schedule_iteration_num, 1)
            self.assertEqual(instances[0].next_event_due, datetime(2017, 8, 6, 13, 0))
            self.assertEqual(instances[0].schedule_revision, schedule.get_schedule_revision())
            self.assertTrue(instances[0].active)

            # Making another arbitrary update doesn't cause any recalculating to happen
            with patch('corehq.messaging.scheduling.scheduling_partitioned.models.AbstractTimedScheduleInstance.recalculate_schedule') as recalculate_patch:
                update_case(self.domain, case.case_id, case_properties={'new_property': 'new value 2'})
                self.assertEqual(recalculate_patch.call_count, 0)

            instances = get_case_timed_schedule_instances_for_schedule(case.case_id, schedule)
            self.assertEqual(instances.count(), 1)

            self.assertEqual(instances[0].case_id, case.case_id)
            self.assertEqual(instances[0].rule_id, rule.pk)
            self.assertEqual(instances[0].timed_schedule_id, schedule.schedule_id)
            self.assertEqual(instances[0].start_date, date(2017, 8, 1))
            self.assertEqual(instances[0].domain, self.domain)
            self.assertEqual(instances[0].recipient_type, 'CommCareUser')
            self.assertEqual(instances[0].recipient_id, self.user.get_id)
            self.assertEqual(instances[0].current_event_num, 0)
            self.assertEqual(instances[0].schedule_iteration_num, 1)
            self.assertEqual(instances[0].next_event_due, datetime(2017, 8, 6, 13, 0))
            self.assertEqual(instances[0].schedule_revision, schedule.get_schedule_revision())
            self.assertTrue(instances[0].active)