def test_ip_date_followup_blank_schedule1_new_patient(self):
     update_case(self.domain, self.episode_id,
                 {'patient_type_choice': 'new'})
     self.assert_update(
         datetime.date(2016, 1, 20),
         datetime.date(2016, 1, 20),
         'schedule1',
         self._generate_doses_taken(datetime.date(2016, 1, 20), 5),
         output={
             'adherence_total_doses_taken': 5,
             'adherence_ip_date_followup_test_expected': '',
             'adherence_ip_date_threshold_crossed': '',
         },
     )
    def test_ok(self):
        with self.create_case_1() as case1, self.create_case_2() as case2:

            # Initial condition
            CaseReminderHandler.now = datetime(year=2012,
                                               month=2,
                                               day=16,
                                               hour=11,
                                               minute=0)
            update_case(self.domain,
                        case1.case_id, {
                            'start_sending1': 'ok',
                            'start_sending2': 'ok'
                        },
                        user_id=self.user.get_id)

            update_case(self.domain,
                        case2.case_id, {
                            'start_sending1': 'ok',
                            'start_sending3': 'ok'
                        },
                        user_id=self.user.get_id)

            self.assertIsNotNone(self.handler1.get_reminder(case1))
            self.assertIsNone(self.handler1.get_reminder(case2))
            self.assertIsNotNone(self.handler2.get_reminder(case1))
            self.assertIsNone(self.handler2.get_reminder(case2))
            self.assertIsNone(self.handler3.get_reminder(case1))
            self.assertIsNone(self.handler3.get_reminder(case2))

            self.assertEqual(
                self.handler1.get_reminder(case1).next_fire,
                CaseReminderHandler.now +
                timedelta(days=self.handler1.start_offset))
            self.assertEqual(
                self.handler2.get_reminder(case1).next_fire,
                CaseReminderHandler.now +
                timedelta(days=self.handler2.start_offset))
Beispiel #3
0
 def test_run_on_save(self):
     with _with_case(self.domain, 'test-case-type-3', datetime(2016, 1, 1), case_name='signal') as case:
         with patch('corehq.apps.data_interfaces.models.AutomaticUpdateRule.apply_rule') as apply:
             # property is updated after save signal (case update used to force save)
             update_case(self.domain, case.case_id, {})
             apply.assert_called_once()
    def test_calculate_start_date_with_today_option(self):
        now = datetime.utcnow()

        with create_test_case(self.domain, 'contact', 'test-case') as case:

            reminder = CaseReminderHandler(
                domain=self.domain,
                use_today_if_start_date_is_blank=True
            )

            self.assertEqual(
                reminder.get_case_criteria_reminder_start_date_info(case, now),
                (now, True, True)
            )

            reminder.start_date = 'start_date_case_property'
            self.assertEqual(
                reminder.get_case_criteria_reminder_start_date_info(case, now),
                (now, True, True)
            )

            update_case(self.domain, case.case_id, {'start_date_case_property': ''})
            case = CaseAccessors(self.domain).get_case(case.case_id)
            self.assertEqual(
                reminder.get_case_criteria_reminder_start_date_info(case, now),
                (now, True, True)
            )

            update_case(self.domain, case.case_id, {'start_date_case_property': '   '})
            case = CaseAccessors(self.domain).get_case(case.case_id)
            self.assertEqual(
                reminder.get_case_criteria_reminder_start_date_info(case, now),
                (now, True, True)
            )

            update_case(self.domain, case.case_id, {'start_date_case_property': 'abcdefg'})
            case = CaseAccessors(self.domain).get_case(case.case_id)
            self.assertEqual(
                reminder.get_case_criteria_reminder_start_date_info(case, now),
                (now, True, True)
            )

            update_case(self.domain, case.case_id, {'start_date_case_property': '2016-01-32'})
            case = CaseAccessors(self.domain).get_case(case.case_id)
            self.assertEqual(
                reminder.get_case_criteria_reminder_start_date_info(case, now),
                (now, True, True)
            )

            update_case(self.domain, case.case_id, {'start_date_case_property': '2016-01-10'})
            case = CaseAccessors(self.domain).get_case(case.case_id)
            self.assertEqual(
                reminder.get_case_criteria_reminder_start_date_info(case, now),
                (datetime(2016, 1, 10), True, False)
            )

            update_case(self.domain, case.case_id, {'start_date_case_property': '2016-01-12T00:00:00Z'})
            case = CaseAccessors(self.domain).get_case(case.case_id)
            self.assertEqual(
                reminder.get_case_criteria_reminder_start_date_info(case, now),
                (datetime(2016, 1, 12), True, False)
            )
    def test_ok(self):
        with create_test_case(self.domain, 'case_type_a', 'test-case', drop_signals=False,
                user_id=self.user.get_id) as case:

            # Test changing a start condition which is a string
            # Spawn the reminder with an "ok" start condition value
            CaseReminderHandler.now = datetime(year=2012, month=2, day=17, hour=12, minute=0)
            self.assertIsNone(self.handler1.get_reminder(case))

            update_case(self.domain, case.case_id, {'start_sending1': 'ok'}, user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(
                reminder.next_fire,
                CaseReminderHandler.now + timedelta(days=self.handler1.start_offset)
            )

            # Test that saving the case without changing the start condition has no effect
            old_reminder_id = reminder.get_id
            update_case(self.domain, case.case_id, {'case_property1': 'abc'}, user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.get_id, old_reminder_id)

            # Test retiring the reminder
            old_reminder_id = reminder.get_id
            update_case(self.domain, case.case_id, {'start_sending1': ''}, user_id=self.user.get_id)

            self.assertIsNone(self.handler1.get_reminder(case))
            self.assertEqual(CaseReminder.get(old_reminder_id).doc_type, "CaseReminder-Deleted")

            # Test changing a start condition which is a date value
            # Spawn the reminder with date start condition value
            update_case(self.domain, case.case_id, {'start_sending1': '2012-02-20'}, user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNotNone(reminder)

            self.assertEqual(
                reminder.next_fire,
                datetime(2012, 2, 20) + timedelta(days=self.handler1.start_offset)
            )

            # Reset the date start condition
            old_reminder_id = reminder.get_id
            update_case(self.domain, case.case_id, {'start_sending1': '2012-02-22'}, user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(
                reminder.next_fire,
                datetime(2012, 2, 22) + timedelta(days=self.handler1.start_offset)
            )
            self.assertEqual(CaseReminder.get(old_reminder_id).doc_type, "CaseReminder-Deleted")

            # Test that saving the case without changing the start condition has no effect
            old_reminder_id = reminder.get_id
            update_case(self.domain, case.case_id, {'case_property1': 'abc'}, user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.get_id, old_reminder_id)

            # Retire the reminder
            old_reminder_id = reminder.get_id
            update_case(self.domain, case.case_id, {'start_sending1': ''}, user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNone(reminder)
            self.assertEqual(CaseReminder.get(old_reminder_id).doc_type, "CaseReminder-Deleted")

            # Test changing a start condition which is a string representation of a datetime value
            # Spawn the reminder with datetime start condition value
            update_case(self.domain, case.case_id, {'start_sending1': '2012-02-25 11:15'},
                user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNotNone(reminder)

            self.assertEqual(
                reminder.next_fire,
                datetime(2012, 2, 25, 11, 15) + timedelta(days=self.handler1.start_offset)
            )

            # Reset the datetime start condition
            old_reminder_id = reminder.get_id
            update_case(self.domain, case.case_id, {'start_sending1': '2012-02-26 11:20'},
                user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNotNone(reminder)

            self.assertEqual(
                reminder.next_fire,
                datetime(2012, 2, 26, 11, 20) + timedelta(days=self.handler1.start_offset)
            )
            self.assertEqual(CaseReminder.get(old_reminder_id).doc_type, "CaseReminder-Deleted")

            # Test that saving the case without changing the start condition has no effect
            old_reminder_id = reminder.get_id
            update_case(self.domain, case.case_id, {'case_property1': 'xyz'},
                user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.get_id, old_reminder_id)

            # Retire the reminder
            old_reminder_id = reminder.get_id
            update_case(self.domain, case.case_id, {'start_sending1': ''},
                user_id=self.user.get_id)

            reminder = self.handler1.get_reminder(case)
            self.assertIsNone(reminder)
            self.assertEqual(CaseReminder.get(old_reminder_id).doc_type, "CaseReminder-Deleted")
    def test_ok(self):
        with self.create_case_1() as case1, self.create_case_2() as case2:

            # Initial condition
            CaseReminderHandler.now = datetime(year=2012, month=2, day=16, hour=11, minute=0)
            update_case(self.domain, case1.case_id, {'start_sending1': 'ok', 'start_sending2': 'ok'},
                user_id=self.user.get_id)

            update_case(self.domain, case2.case_id, {'start_sending1': 'ok', 'start_sending3': 'ok'},
                user_id=self.user.get_id)

            self.assertIsNotNone(self.handler1.get_reminder(case1))
            self.assertIsNone(self.handler1.get_reminder(case2))
            self.assertIsNotNone(self.handler2.get_reminder(case1))
            self.assertIsNone(self.handler2.get_reminder(case2))
            self.assertIsNone(self.handler3.get_reminder(case1))
            self.assertIsNone(self.handler3.get_reminder(case2))

            self.assertEqual(
                self.handler1.get_reminder(case1).next_fire,
                CaseReminderHandler.now + timedelta(days=self.handler1.start_offset)
            )
            self.assertEqual(
                self.handler2.get_reminder(case1).next_fire,
                CaseReminderHandler.now + timedelta(days=self.handler2.start_offset)
            )

            # Test deactivation and spawn on change of CaseReminderHandler.case_type
            CaseReminderHandler.now = datetime(year=2012, month=2, day=16, hour=11, minute=15)

            self.handler1.case_type = 'case_type_b'
            self.handler1.save()
            self.handler2.case_type = 'case_type_b'
            self.handler2.save()
            self.handler3.case_type = 'case_type_b'
            self.handler3.save()

            self.assertIsNone(self.handler1.get_reminder(case1))
            self.assertIsNotNone(self.handler1.get_reminder(case2))
            self.assertIsNone(self.handler2.get_reminder(case1))
            self.assertIsNone(self.handler2.get_reminder(case2))
            self.assertIsNone(self.handler3.get_reminder(case1))
            self.assertIsNotNone(self.handler3.get_reminder(case2))

            self.assertEqual(
                self.handler1.get_reminder(case2).next_fire,
                CaseReminderHandler.now + timedelta(days=self.handler1.start_offset)
            )
            self.assertEqual(
                self.handler3.get_reminder(case2).next_fire,
                CaseReminderHandler.now + timedelta(days=self.handler3.start_offset)
            )

            # Test spawn on change of Case.type
            prev_now = CaseReminderHandler.now
            CaseReminderHandler.now = datetime(year=2012, month=2, day=16, hour=11, minute=30)

            self.update_case_type(case1, 'case_type_b')

            self.assertIsNotNone(self.handler1.get_reminder(case1))
            self.assertIsNotNone(self.handler1.get_reminder(case2))
            self.assertIsNotNone(self.handler2.get_reminder(case1))
            self.assertIsNone(self.handler2.get_reminder(case2))
            self.assertIsNone(self.handler3.get_reminder(case1))
            self.assertIsNotNone(self.handler3.get_reminder(case2))

            self.assertEqual(
                self.handler1.get_reminder(case1).next_fire,
                CaseReminderHandler.now + timedelta(days=self.handler1.start_offset)
            )
            self.assertEqual(
                self.handler2.get_reminder(case1).next_fire,
                CaseReminderHandler.now + timedelta(days=self.handler2.start_offset)
            )

            self.assertEqual(
                self.handler1.get_reminder(case2).next_fire,
                prev_now + timedelta(days=self.handler1.start_offset)
            )
            self.assertEqual(
                self.handler3.get_reminder(case2).next_fire,
                prev_now + timedelta(days=self.handler3.start_offset)
            )

            # Test deactivation on change of Case.type
            prev_now = CaseReminderHandler.now
            CaseReminderHandler.now = datetime(year=2012, month=2, day=16, hour=11, minute=45)

            self.update_case_type(case2, 'case_type_a')

            self.assertIsNotNone(self.handler1.get_reminder(case1))
            self.assertIsNone(self.handler1.get_reminder(case2))
            self.assertIsNotNone(self.handler2.get_reminder(case1))
            self.assertIsNone(self.handler2.get_reminder(case2))
            self.assertIsNone(self.handler3.get_reminder(case1))
            self.assertIsNone(self.handler3.get_reminder(case2))

            self.assertEqual(
                self.handler1.get_reminder(case1).next_fire,
                prev_now + timedelta(days=self.handler1.start_offset)
            )
            self.assertEqual(
                self.handler2.get_reminder(case1).next_fire,
                prev_now + timedelta(days=self.handler2.start_offset)
            )
    def test_ok(self):
        with create_test_case(self.domain, self.case_type, 'test-case', drop_signals=False,
                user_id=self.user.get_id) as case:

            self.assertIsNone(self.handler.get_reminder(case))

            # create reminder
            CaseReminderHandler.now = datetime(year=2011, month=7, day=7, hour=19, minute=8)
            update_case(self.domain, case.case_id, {'start_sending': 'ok'}, user_id=self.user.get_id)
            CaseReminderHandler.fire_reminders()
            reminder = self.handler.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(
                reminder.next_fire,
                CaseReminderHandler.now + timedelta(days=self.handler.start_offset)
            )
            self.assertIsNone(reminder.last_fired)

            # fire a day after created
            CaseReminderHandler.now = datetime(year=2011, month=7, day=8, hour=19, minute=8)
            update_case(self.domain, case.case_id, {'irrelevant_1': 'ok'}, user_id=self.user.get_id)
            CaseReminderHandler.fire_reminders()
            reminder = self.handler.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(
                reminder.next_fire,
                CaseReminderHandler.now + timedelta(days=self.handler.schedule_length)
            )
            self.assertEqual(reminder.last_fired, CaseReminderHandler.now)

            # Shouldn't fire until three days after created
            last_fired = CaseReminderHandler.now
            CaseReminderHandler.now = datetime(year=2011, month=7, day=9, hour=19, minute=8)
            CaseReminderHandler.fire_reminders()
            reminder = self.handler.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.last_fired, last_fired)
            self.assertEqual(
                reminder.next_fire,
                last_fired + timedelta(days=self.handler.schedule_length)
            )

            # fire three days after last fired
            CaseReminderHandler.now = datetime(year=2011, month=7, day=11, hour=19, minute=8)
            update_case(self.domain, case.case_id, {'irrelevant_2': 'ok'}, user_id=self.user.get_id)
            CaseReminderHandler.fire_reminders()
            reminder = self.handler.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(
                reminder.next_fire,
                CaseReminderHandler.now + timedelta(days=self.handler.schedule_length)
            )
            self.assertEqual(reminder.last_fired, CaseReminderHandler.now)

            # set stop_sending to 'ok' should make it stop sending and make the reminder inactive
            last_fired = CaseReminderHandler.now
            CaseReminderHandler.now = datetime(year=2011, month=7, day=14, hour=19, minute=8)
            update_case(self.domain, case.case_id, {'stop_sending': 'ok'}, user_id=self.user.get_id)
            CaseReminderHandler.fire_reminders()
            reminder = self.handler.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.last_fired, last_fired)
            self.assertEqual(reminder.active, False)
    def test_ok(self):
        with create_test_case(self.domain, self.case_type, 'test-case', drop_signals=False,
                user_id=self.user.get_id) as case:

            self.assertIsNone(self.handler.get_reminder(case))

            # Spawn CaseReminder
            CaseReminderHandler.now = datetime(year=2011, month=12, day=31, hour=23, minute=0)
            update_case(self.domain, case.case_id, {'start_sending': 'ok'}, user_id=self.user.get_id)
            reminder = self.handler.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=1, hour=7, minute=0))
            self.assertEqual(reminder.start_date, date(year=2012, month=1, day=1))
            self.assertEqual(reminder.schedule_iteration_num, 1)
            self.assertEqual(reminder.current_event_sequence_num, 0)
            self.assertEqual(reminder.last_fired, None)

            ######################
            # Day1, 10:00 reminder
            CaseReminderHandler.now = datetime(year=2012, month=1, day=1, hour=7, minute=0)
            CaseReminderHandler.fire_reminders()
            reminder = self.handler.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=1, hour=8, minute=0))
            self.assertEqual(reminder.schedule_iteration_num, 1)
            self.assertEqual(reminder.current_event_sequence_num, 1)
            self.assertEqual(reminder.last_fired, CaseReminderHandler.now)

            # Day1, 11:00 reminder
            CaseReminderHandler.now = datetime(year=2012, month=1, day=1, hour=8, minute=1)
            CaseReminderHandler.fire_reminders()
            reminder = self.handler.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=1, hour=8, minute=15))
            self.assertEqual(reminder.schedule_iteration_num, 1)
            self.assertEqual(reminder.current_event_sequence_num, 1)
            self.assertEqual(reminder.last_fired, CaseReminderHandler.now)

            event = self.get_expected_callback(
                datetime(2012, 1, 1, 8, 1),
                self.user.get_id
            )
            self.assertIsNotNone(event)
            self.assertEqual(event.status, CALLBACK_PENDING)

            # Create a callback
            Call.objects.create(
                couch_recipient_doc_type='CommCareUser',
                couch_recipient=self.user.get_id,
                phone_number='14445551234',
                direction='I',
                date=datetime(year=2012, month=1, day=1, hour=8, minute=5)
            )

            # Day1, 11:15 timeout (should move on to next event)
            CaseReminderHandler.now = datetime(year=2012, month=1, day=1, hour=8, minute=15)
            CaseReminderHandler.fire_reminders()
            reminder = self.handler.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=1, hour=8, minute=45))
            self.assertEqual(reminder.schedule_iteration_num, 1)
            self.assertEqual(reminder.current_event_sequence_num, 1)
            self.assertEqual(reminder.last_fired, CaseReminderHandler.now)

            # Day1, 11:45 timeout (should move on to next event)
            CaseReminderHandler.now = datetime(year=2012, month=1, day=1, hour=8, minute=45)
            CaseReminderHandler.fire_reminders()
            reminder = self.handler.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=2, hour=7, minute=0))
            self.assertEqual(reminder.schedule_iteration_num, 2)
            self.assertEqual(reminder.current_event_sequence_num, 0)
            self.assertEqual(reminder.last_fired, CaseReminderHandler.now)

            event = self.get_expected_callback(
                datetime(2012, 1, 1, 8, 1),
                self.user.get_id
            )
            self.assertIsNotNone(event)
            self.assertEqual(event.status, CALLBACK_RECEIVED)

            ######################
            # Day2, 10:00 reminder
            CaseReminderHandler.now = datetime(year=2012, month=1, day=2, hour=7, minute=0)
            CaseReminderHandler.fire_reminders()
            reminder = self.handler.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=2, hour=8, minute=0))
            self.assertEqual(reminder.schedule_iteration_num, 2)
            self.assertEqual(reminder.current_event_sequence_num, 1)
            self.assertEqual(reminder.last_fired, CaseReminderHandler.now)

            # Day2, 11:00 reminder
            CaseReminderHandler.now = datetime(year=2012, month=1, day=2, hour=8, minute=1)
            CaseReminderHandler.fire_reminders()
            reminder = self.handler.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=2, hour=8, minute=15))
            self.assertEqual(reminder.schedule_iteration_num, 2)
            self.assertEqual(reminder.current_event_sequence_num, 1)
            self.assertEqual(reminder.last_fired, CaseReminderHandler.now)

            event = self.get_expected_callback(
                datetime(2012, 1, 2, 8, 1),
                self.user.get_id
            )
            self.assertIsNotNone(event)
            self.assertEqual(event.status, CALLBACK_PENDING)

            # Day2, 11:15 timeout (should move on to next timeout)
            CaseReminderHandler.now = datetime(year=2012, month=1, day=2, hour=8, minute=15)
            CaseReminderHandler.fire_reminders()
            reminder = self.handler.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=2, hour=8, minute=45))
            self.assertEqual(reminder.schedule_iteration_num, 2)
            self.assertEqual(reminder.current_event_sequence_num, 1)
            self.assertEqual(reminder.last_fired, CaseReminderHandler.now)

            event = self.get_expected_callback(
                datetime(2012, 1, 2, 8, 1),
                self.user.get_id
            )
            self.assertIsNotNone(event)
            self.assertEqual(event.status, CALLBACK_PENDING)

            # Day2, 11:45 timeout (should move on to next day)
            CaseReminderHandler.now = datetime(year=2012, month=1, day=2, hour=8, minute=45)
            CaseReminderHandler.fire_reminders()
            reminder = self.handler.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=3, hour=7, minute=0))
            self.assertEqual(reminder.schedule_iteration_num, 3)
            self.assertEqual(reminder.current_event_sequence_num, 0)
            self.assertEqual(reminder.last_fired, CaseReminderHandler.now)

            event = self.get_expected_callback(
                datetime(2012, 1, 2, 8, 1),
                self.user.get_id
            )
            self.assertIsNotNone(event)
            self.assertEqual(event.status, CALLBACK_MISSED)

            ######################
            # Day3, 10:00 reminder
            CaseReminderHandler.now = datetime(year=2012, month=1, day=3, hour=7, minute=0)
            CaseReminderHandler.fire_reminders()
            reminder = self.handler.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=3, hour=8, minute=0))
            self.assertEqual(reminder.schedule_iteration_num, 3)
            self.assertEqual(reminder.current_event_sequence_num, 1)
            self.assertEqual(reminder.last_fired, CaseReminderHandler.now)

            # Day3, 11:00 reminder
            CaseReminderHandler.now = datetime(year=2012, month=1, day=3, hour=8, minute=1)
            CaseReminderHandler.fire_reminders()
            reminder = self.handler.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=3, hour=8, minute=15))
            self.assertEqual(reminder.schedule_iteration_num, 3)
            self.assertEqual(reminder.current_event_sequence_num, 1)
            self.assertEqual(reminder.last_fired, CaseReminderHandler.now)

            event = self.get_expected_callback(
                datetime(2012, 1, 3, 8, 1),
                self.user.get_id
            )
            self.assertIsNotNone(event)
            self.assertEqual(event.status, CALLBACK_PENDING)

            # Day3, 11:15 timeout (should move on to next timeout)
            CaseReminderHandler.now = datetime(year=2012, month=1, day=3, hour=8, minute=15)
            CaseReminderHandler.fire_reminders()
            reminder = self.handler.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=3, hour=8, minute=45))
            self.assertEqual(reminder.schedule_iteration_num, 3)
            self.assertEqual(reminder.current_event_sequence_num, 1)
            self.assertEqual(reminder.last_fired, CaseReminderHandler.now)

            event = self.get_expected_callback(
                datetime(2012, 1, 3, 8, 1),
                self.user.get_id
            )
            self.assertIsNotNone(event)
            self.assertEqual(event.status, CALLBACK_PENDING)

            # Create a callback (with phone_number missing country code)
            Call.objects.create(
                couch_recipient_doc_type='CommCareUser',
                couch_recipient=self.user.get_id,
                phone_number='4445551234',
                direction='I',
                date=datetime(year=2012, month=1, day=3, hour=8, minute=22)
            )

            # Day3, 11:45 timeout (should deactivate the reminder)
            CaseReminderHandler.now = datetime(year=2012, month=1, day=3, hour=8, minute=45)
            CaseReminderHandler.fire_reminders()
            reminder = self.handler.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.schedule_iteration_num, 4)
            self.assertEqual(reminder.current_event_sequence_num, 0)
            self.assertEqual(reminder.last_fired, CaseReminderHandler.now)
            self.assertEqual(reminder.active, False)

            event = self.get_expected_callback(
                datetime(2012, 1, 3, 8, 1),
                self.user.get_id
            )
            self.assertIsNotNone(event)
            self.assertEqual(event.status, CALLBACK_RECEIVED)
    def test_ok(self):

        with create_test_case(self.domain, self.case_type, 'test-case', drop_signals=False,
                user_id=self.user.get_id) as case:

            self.assertIsNone(self.handler.get_reminder(case))

            # Spawn CaseReminder
            CaseReminderHandler.now = datetime(year=2012, month=1, day=1, hour=4, minute=0)
            update_case(self.domain, case.case_id, {'start_sending': 'ok'}, user_id=self.user.get_id)
            reminder = self.handler.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=2, hour=10, minute=0))
            self.assertEqual(reminder.start_date, date(year=2012, month=1, day=1))
            self.assertEqual(reminder.schedule_iteration_num, 1)
            self.assertEqual(reminder.current_event_sequence_num, 0)
            self.assertEqual(reminder.last_fired, None)

            # Not yet the first fire time, nothing should happen
            CaseReminderHandler.now = datetime(year=2012, month=1, day=2, hour=9, minute=45)
            CaseReminderHandler.fire_reminders()
            reminder = self.handler.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=2, hour=10, minute=0))
            self.assertEqual(reminder.schedule_iteration_num, 1)
            self.assertEqual(reminder.current_event_sequence_num, 0)
            self.assertEqual(reminder.last_fired, None)

            # Week1, Day1, 10:00 reminder
            CaseReminderHandler.now = datetime(year=2012, month=1, day=2, hour=10, minute=7)
            CaseReminderHandler.fire_reminders()
            reminder = self.handler.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=5, hour=11, minute=0))
            self.assertEqual(reminder.schedule_iteration_num, 1)
            self.assertEqual(reminder.current_event_sequence_num, 1)
            self.assertEqual(reminder.last_fired, CaseReminderHandler.now)

            # Week1, Day4, 11:00 reminder
            CaseReminderHandler.now = datetime(year=2012, month=1, day=5, hour=11, minute=3)
            CaseReminderHandler.fire_reminders()
            reminder = self.handler.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=5, hour=11, minute=30))
            self.assertEqual(reminder.schedule_iteration_num, 1)
            self.assertEqual(reminder.current_event_sequence_num, 2)
            self.assertEqual(reminder.last_fired, CaseReminderHandler.now)

            # Week1, Day4, 11:30 reminder
            CaseReminderHandler.now = datetime(year=2012, month=1, day=5, hour=11, minute=30)
            CaseReminderHandler.fire_reminders()
            reminder = self.handler.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=9, hour=10, minute=0))
            self.assertEqual(reminder.schedule_iteration_num, 2)
            self.assertEqual(reminder.current_event_sequence_num, 0)
            self.assertEqual(reminder.last_fired, CaseReminderHandler.now)

            # Week2, Day1, 10:00 reminder
            CaseReminderHandler.now = datetime(year=2012, month=1, day=9, hour=10, minute=0)
            CaseReminderHandler.fire_reminders()
            reminder = self.handler.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=12, hour=11, minute=0))
            self.assertEqual(reminder.schedule_iteration_num, 2)
            self.assertEqual(reminder.current_event_sequence_num, 1)
            self.assertEqual(reminder.last_fired, CaseReminderHandler.now)

            # Week2, Day4, 11:00 reminder
            CaseReminderHandler.now = datetime(year=2012, month=1, day=12, hour=11, minute=0)
            CaseReminderHandler.fire_reminders()
            reminder = self.handler.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.next_fire, datetime(year=2012, month=1, day=12, hour=11, minute=30))
            self.assertEqual(reminder.schedule_iteration_num, 2)
            self.assertEqual(reminder.current_event_sequence_num, 2)
            self.assertEqual(reminder.last_fired, CaseReminderHandler.now)

            # Week2, Day4, 11:30 reminder
            CaseReminderHandler.now = datetime(year=2012, month=1, day=12, hour=11, minute=31)
            CaseReminderHandler.fire_reminders()
            reminder = self.handler.get_reminder(case)
            self.assertIsNotNone(reminder)
            self.assertEqual(reminder.schedule_iteration_num, 3)
            self.assertEqual(reminder.current_event_sequence_num, 0)
            self.assertEqual(reminder.last_fired, CaseReminderHandler.now)
            self.assertEqual(reminder.active, False)