Example #1
0
    def testOutbound(self):
        # Send an outbound call using self.reminder1 to self.case
        # and answer it
        CaseReminderHandler.now = datetime(2014, 6, 23, 10, 0)
        self.case = CommCareCase.get(
            register_sms_contact(
                self.domain,
                'participant',
                'case1',
                self.user1._id,
                '91000',
                owner_id=self.groups[0]._id,
            ))
        CaseReminderHandler.now = datetime(2014, 6, 23, 12, 0)
        CaseReminderHandler.fire_reminders()
        reminder = self.reminder1.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 23, 12, 30))

        call = self.get_last_outbound_call(self.case)
        self.assertTrue(call.use_precached_first_response)

        kookoo_session_id = call.gateway_session_id[7:]
        resp = self.kookoo_in({
            "cid": "0000",
            "sid": kookoo_session_id,
            "event": "NewCall",
        })
        self.assertEqual(
            resp, '<response sid="%s"><collectdtmf l="1" o="3000">'
            '<playtext>How do you feel today? Press 1 for good, 2 for bad.'
            '</playtext></collectdtmf></response>' % kookoo_session_id)

        resp = self.kookoo_in({
            "cid": "0000",
            "sid": kookoo_session_id,
            "event": "GotDTMF",
            "data": "1",
        })
        self.assertEqual(
            resp, '<response sid="%s"><collectdtmf l="1" o="3000">'
            '<playtext>Did you remember to take your meds today? Press 1 for yes, 2 for no.'
            '</playtext></collectdtmf></response>' % kookoo_session_id)

        resp = self.kookoo_in({
            "cid": "0000",
            "sid": kookoo_session_id,
            "event": "GotDTMF",
            "data": "2",
        })
        self.assertEqual(
            resp,
            '<response sid="%s"><hangup/></response>' % kookoo_session_id)

        self.kookoo_finished({
            "sid": kookoo_session_id,
            "status": "answered",
            "duration": "20",
        })

        call = CallLog.get(call._id)
        self.assertTrue(call.answered)
        self.assertEqual(call.duration, 20)

        form = self.get_last_form_submission()
        self.assertFormQuestionEquals(form, "how_feel", "1")
        self.assertFormQuestionEquals(form, "take_meds", "2")
        case = CommCareCase.get(self.case._id)
        self.assertCasePropertyEquals(case, "how_feel", "1")
        self.assertCasePropertyEquals(case, "take_meds", "2")

        CaseReminderHandler.now = datetime(2014, 6, 23, 12, 30)
        CaseReminderHandler.fire_reminders()

        reminder = self.reminder1.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 23, 13, 0))

        last_call = self.get_last_outbound_call(self.case)
        self.assertEqual(call._id, last_call._id)

        # Move on to the second event which now uses an all-label form and
        # should not precache the first ivr response
        CaseReminderHandler.now = datetime(2014, 6, 23, 13, 0)
        CaseReminderHandler.fire_reminders()

        reminder = self.reminder1.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 23, 13, 30))

        call = self.get_last_outbound_call(self.case)
        self.assertFalse(call.use_precached_first_response)

        kookoo_session_id = call.gateway_session_id[7:]
        resp = self.kookoo_in({
            "cid": "0000",
            "sid": kookoo_session_id,
            "event": "NewCall",
        })
        self.assertEqual(
            resp, '<response sid="%s">'
            '<playtext>This is just a reminder to take your meds.'
            '</playtext><hangup/></response>' % kookoo_session_id)

        self.kookoo_finished({
            "sid": kookoo_session_id,
            "status": "answered",
            "duration": "5",
        })

        call = CallLog.get(call._id)
        self.assertTrue(call.answered)
        self.assertEqual(call.duration, 5)

        form = self.get_last_form_submission()
        self.assertFormQuestionEquals(form, "label", "ok")

        CaseReminderHandler.now = datetime(2014, 6, 23, 13, 30)
        CaseReminderHandler.fire_reminders()

        reminder = self.reminder1.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 24, 12, 0))

        last_call = self.get_last_outbound_call(self.case)
        self.assertEqual(call._id, last_call._id)

        # Now test sending outbound calls to a group of users (the owners
        # of the case)

        # Allow sending to unverified numbers
        self.domain_obj = Domain.get(self.domain_obj._id)
        self.domain_obj.send_to_duplicated_case_numbers = True
        self.domain_obj.save()

        CaseReminderHandler.now = datetime(2014, 6, 24, 10, 0)
        self.case = CommCareCase.get(
            register_sms_contact(
                self.domain,
                'participant',
                'case2',
                self.user1._id,
                '91003',
                owner_id=self.groups[0]._id,
            ))
        reminder = self.reminder2.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 24, 12, 0))

        CaseReminderHandler.now = datetime(2014, 6, 24, 12, 0)
        CaseReminderHandler.fire_reminders()
        reminder = self.reminder2.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 24, 12, 30))

        call1 = self.get_last_outbound_call(self.user1)
        self.assertTrue(call1.use_precached_first_response)
        self.assertFalse(call1.answered)

        call2 = self.get_last_outbound_call(self.user2)
        self.assertTrue(call2.use_precached_first_response)
        self.assertFalse(call2.answered)

        old_call1 = call1
        old_call2 = call2

        CaseReminderHandler.now = datetime(2014, 6, 24, 12, 30)
        CaseReminderHandler.fire_reminders()
        reminder = self.reminder2.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 24, 13, 0))

        call1 = self.get_last_outbound_call(self.user1)
        self.assertTrue(call1.use_precached_first_response)
        self.assertNotEqual(call1._id, old_call1._id)

        call2 = self.get_last_outbound_call(self.user2)
        self.assertTrue(call2.use_precached_first_response)
        self.assertFalse(call2.answered)
        self.assertNotEqual(call2._id, old_call2._id)

        kookoo_session_id = call1.gateway_session_id[7:]
        resp = self.kookoo_in({
            "cid": "0001",
            "sid": kookoo_session_id,
            "event": "NewCall",
        })
        self.assertEqual(
            resp, '<response sid="%s"><collectdtmf l="1" o="3000">'
            '<playtext>How do you feel today? Press 1 for good, 2 for bad.'
            '</playtext></collectdtmf></response>' % kookoo_session_id)

        resp = self.kookoo_in({
            "cid": "0001",
            "sid": kookoo_session_id,
            "event": "GotDTMF",
            "data": "2",
        })
        self.assertEqual(
            resp, '<response sid="%s"><collectdtmf l="1" o="3000">'
            '<playtext>Did you remember to take your meds today? Press 1 for yes, 2 for no.'
            '</playtext></collectdtmf></response>' % kookoo_session_id)

        resp = self.kookoo_in({
            "cid": "0001",
            "sid": kookoo_session_id,
            "event": "GotDTMF",
            "data": "1",
        })
        self.assertEqual(
            resp,
            '<response sid="%s"><hangup/></response>' % kookoo_session_id)

        self.kookoo_finished({
            "sid": kookoo_session_id,
            "status": "answered",
            "duration": "20",
        })
        call1 = CallLog.get(call1._id)
        self.assertTrue(call1.answered)
        self.assertEqual(call1.duration, 20)

        form = self.get_last_form_submission()
        self.assertFormQuestionEquals(form, "how_feel", "2")
        self.assertFormQuestionEquals(form, "take_meds", "1")
        self.assertEqual(form.form["meta"]["userID"], self.user1._id)
        case = CommCareCase.get(self.case._id)
        self.assertCasePropertyEquals(case, "how_feel", "2")
        self.assertCasePropertyEquals(case, "take_meds", "1")
        self.assertEqual(case.user_id, self.user1._id)

        old_call1 = call1
        old_call2 = call2

        CaseReminderHandler.now = datetime(2014, 6, 24, 13, 0)
        CaseReminderHandler.fire_reminders()
        reminder = self.reminder2.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 25, 12, 0))

        call1 = self.get_last_outbound_call(self.user1)
        # No new call for user1 since it was already answered
        self.assertEqual(call1._id, old_call1._id)

        call2 = self.get_last_outbound_call(self.user2)
        self.assertTrue(call2.use_precached_first_response)
        self.assertNotEqual(call2._id, old_call2._id)

        kookoo_session_id = call2.gateway_session_id[7:]
        resp = self.kookoo_in({
            "cid": "0002",
            "sid": kookoo_session_id,
            "event": "NewCall",
        })
        self.assertEqual(
            resp, '<response sid="%s"><collectdtmf l="1" o="3000">'
            '<playtext>How do you feel today? Press 1 for good, 2 for bad.'
            '</playtext></collectdtmf></response>' % kookoo_session_id)

        resp = self.kookoo_in({
            "cid": "0002",
            "sid": kookoo_session_id,
            "event": "GotDTMF",
            "data": "1",
        })
        self.assertEqual(
            resp, '<response sid="%s"><collectdtmf l="1" o="3000">'
            '<playtext>Did you remember to take your meds today? Press 1 for yes, 2 for no.'
            '</playtext></collectdtmf></response>' % kookoo_session_id)

        resp = self.kookoo_in({
            "cid": "0002",
            "sid": kookoo_session_id,
            "event": "GotDTMF",
            "data": "2",
        })
        self.assertEqual(
            resp,
            '<response sid="%s"><hangup/></response>' % kookoo_session_id)

        self.kookoo_finished({
            "sid": kookoo_session_id,
            "status": "answered",
            "duration": "20",
        })
        call2 = CallLog.get(call2._id)
        self.assertTrue(call2.answered)
        self.assertEqual(call2.duration, 20)

        form = self.get_last_form_submission()
        self.assertFormQuestionEquals(form, "how_feel", "1")
        self.assertFormQuestionEquals(form, "take_meds", "2")
        self.assertEqual(form.form["meta"]["userID"], self.user2._id)
        case = CommCareCase.get(self.case._id)
        self.assertCasePropertyEquals(case, "how_feel", "1")
        self.assertCasePropertyEquals(case, "take_meds", "2")
        self.assertEqual(case.user_id, self.user2._id)
Example #2
0
 def fire_reminders():
     CaseReminderHandler.fire_reminders()
Example #3
0
    def testOutbound(self):
        # Send an outbound call using self.reminder1 to self.case
        # and answer it
        CaseReminderHandler.now = datetime(2014, 6, 23, 10, 0)
        self.case = CommCareCase.get(register_sms_contact(
            self.domain,
            'participant',
            'case1',
            self.user1._id,
            '91000',
            owner_id=self.groups[0]._id,
            contact_ivr_backend_id='MOBILE_BACKEND_KOOKOO'
        ))
        CaseReminderHandler.now = datetime(2014, 6, 23, 12, 0)
        CaseReminderHandler.fire_reminders()
        reminder = self.reminder1.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 23, 12, 30))

        call = self.get_last_outbound_call(self.case)
        self.assertTrue(call.use_precached_first_response)

        kookoo_session_id = call.gateway_session_id[7:]
        resp = self.kookoo_in({
            "cid": "0000",
            "sid": kookoo_session_id,
            "event": "NewCall",
        })
        self.assertEqual(resp, '<response sid="%s"><collectdtmf l="1" o="3000">'
            '<playtext>How do you feel today? Press 1 for good, 2 for bad.'
            '</playtext></collectdtmf></response>' % kookoo_session_id)

        resp = self.kookoo_in({
            "cid": "0000",
            "sid": kookoo_session_id,
            "event": "GotDTMF",
            "data": "1",
        })
        self.assertEqual(resp, '<response sid="%s"><collectdtmf l="1" o="3000">'
            '<playtext>Did you remember to take your meds today? Press 1 for yes, 2 for no.'
            '</playtext></collectdtmf></response>' % kookoo_session_id)

        resp = self.kookoo_in({
            "cid": "0000",
            "sid": kookoo_session_id,
            "event": "GotDTMF",
            "data": "2",
        })
        self.assertEqual(resp, '<response sid="%s"><hangup/></response>' % kookoo_session_id)

        self.kookoo_finished({
            "sid": kookoo_session_id,
            "status": "answered",
            "duration": "20",
        })

        call = CallLog.get(call._id)
        self.assertTrue(call.answered)
        self.assertEqual(call.duration, 20)

        form = self.get_last_form_submission()
        self.assertFormQuestionEquals(form, "how_feel", "1")
        self.assertFormQuestionEquals(form, "take_meds", "2")
        case = CommCareCase.get(self.case._id)
        self.assertCasePropertyEquals(case, "how_feel", "1")
        self.assertCasePropertyEquals(case, "take_meds", "2")

        CaseReminderHandler.now = datetime(2014, 6, 23, 12, 30)
        CaseReminderHandler.fire_reminders()

        reminder = self.reminder1.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 23, 13, 0))

        last_call = self.get_last_outbound_call(self.case)
        self.assertEqual(call._id, last_call._id)

        # Move on to the second event which now uses an all-label form and
        # should not precache the first ivr response
        CaseReminderHandler.now = datetime(2014, 6, 23, 13, 0)
        CaseReminderHandler.fire_reminders()

        reminder = self.reminder1.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 23, 13, 30))

        call = self.get_last_outbound_call(self.case)
        self.assertFalse(call.use_precached_first_response)

        kookoo_session_id = call.gateway_session_id[7:]
        resp = self.kookoo_in({
            "cid": "0000",
            "sid": kookoo_session_id,
            "event": "NewCall",
        })
        self.assertEqual(resp, '<response sid="%s">'
            '<playtext>This is just a reminder to take your meds.'
            '</playtext><hangup/></response>' % kookoo_session_id)

        self.kookoo_finished({
            "sid": kookoo_session_id,
            "status": "answered",
            "duration": "5",
        })

        call = CallLog.get(call._id)
        self.assertTrue(call.answered)
        self.assertEqual(call.duration, 5)

        form = self.get_last_form_submission()
        self.assertFormQuestionEquals(form, "label", "ok")

        CaseReminderHandler.now = datetime(2014, 6, 23, 13, 30)
        CaseReminderHandler.fire_reminders()

        reminder = self.reminder1.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 24, 12, 0))

        last_call = self.get_last_outbound_call(self.case)
        self.assertEqual(call._id, last_call._id)

        # Now test sending outbound calls to a group of users (the owners
        # of the case)

        # Allow sending to unverified numbers
        self.domain_obj = Domain.get(self.domain_obj._id)
        self.domain_obj.send_to_duplicated_case_numbers = True
        self.domain_obj.save()

        CaseReminderHandler.now = datetime(2014, 6, 24, 10, 0)
        self.case = CommCareCase.get(register_sms_contact(
            self.domain,
            'participant',
            'case2',
            self.user1._id,
            '91003',
            owner_id=self.groups[0]._id,
        ))
        reminder = self.reminder2.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 24, 12, 0))

        CaseReminderHandler.now = datetime(2014, 6, 24, 12, 0)
        CaseReminderHandler.fire_reminders()
        reminder = self.reminder2.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 24, 12, 30))

        call1 = self.get_last_outbound_call(self.user1)
        self.assertTrue(call1.use_precached_first_response)
        self.assertFalse(call1.answered)

        call2 = self.get_last_outbound_call(self.user2)
        self.assertTrue(call2.use_precached_first_response)
        self.assertFalse(call2.answered)

        old_call1 = call1
        old_call2 = call2

        CaseReminderHandler.now = datetime(2014, 6, 24, 12, 30)
        CaseReminderHandler.fire_reminders()
        reminder = self.reminder2.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 24, 13, 0))

        call1 = self.get_last_outbound_call(self.user1)
        self.assertTrue(call1.use_precached_first_response)
        self.assertNotEqual(call1._id, old_call1._id)

        call2 = self.get_last_outbound_call(self.user2)
        self.assertTrue(call2.use_precached_first_response)
        self.assertFalse(call2.answered)
        self.assertNotEqual(call2._id, old_call2._id)

        kookoo_session_id = call1.gateway_session_id[7:]
        resp = self.kookoo_in({
            "cid": "0001",
            "sid": kookoo_session_id,
            "event": "NewCall",
        })
        self.assertEqual(resp, '<response sid="%s"><collectdtmf l="1" o="3000">'
            '<playtext>How do you feel today? Press 1 for good, 2 for bad.'
            '</playtext></collectdtmf></response>' % kookoo_session_id)

        resp = self.kookoo_in({
            "cid": "0001",
            "sid": kookoo_session_id,
            "event": "GotDTMF",
            "data": "2",
        })
        self.assertEqual(resp, '<response sid="%s"><collectdtmf l="1" o="3000">'
            '<playtext>Did you remember to take your meds today? Press 1 for yes, 2 for no.'
            '</playtext></collectdtmf></response>' % kookoo_session_id)

        resp = self.kookoo_in({
            "cid": "0001",
            "sid": kookoo_session_id,
            "event": "GotDTMF",
            "data": "1",
        })
        self.assertEqual(resp, '<response sid="%s"><hangup/></response>' % kookoo_session_id)

        self.kookoo_finished({
            "sid": kookoo_session_id,
            "status": "answered",
            "duration": "20",
        })
        call1 = CallLog.get(call1._id)
        self.assertTrue(call1.answered)
        self.assertEqual(call1.duration, 20)

        form = self.get_last_form_submission()
        self.assertFormQuestionEquals(form, "how_feel", "2")
        self.assertFormQuestionEquals(form, "take_meds", "1")
        self.assertEqual(form.form["meta"]["userID"], self.user1._id)
        case = CommCareCase.get(self.case._id)
        self.assertCasePropertyEquals(case, "how_feel", "2")
        self.assertCasePropertyEquals(case, "take_meds", "1")
        self.assertEqual(case.user_id, self.user1._id)

        old_call1 = call1
        old_call2 = call2

        CaseReminderHandler.now = datetime(2014, 6, 24, 13, 0)
        CaseReminderHandler.fire_reminders()
        reminder = self.reminder2.get_reminder(self.case)
        self.assertEquals(reminder.next_fire, datetime(2014, 6, 25, 12, 0))

        call1 = self.get_last_outbound_call(self.user1)
        # No new call for user1 since it was already answered
        self.assertEqual(call1._id, old_call1._id)

        call2 = self.get_last_outbound_call(self.user2)
        self.assertTrue(call2.use_precached_first_response)
        self.assertNotEqual(call2._id, old_call2._id)

        kookoo_session_id = call2.gateway_session_id[7:]
        resp = self.kookoo_in({
            "cid": "0002",
            "sid": kookoo_session_id,
            "event": "NewCall",
        })
        self.assertEqual(resp, '<response sid="%s"><collectdtmf l="1" o="3000">'
            '<playtext>How do you feel today? Press 1 for good, 2 for bad.'
            '</playtext></collectdtmf></response>' % kookoo_session_id)

        resp = self.kookoo_in({
            "cid": "0002",
            "sid": kookoo_session_id,
            "event": "GotDTMF",
            "data": "1",
        })
        self.assertEqual(resp, '<response sid="%s"><collectdtmf l="1" o="3000">'
            '<playtext>Did you remember to take your meds today? Press 1 for yes, 2 for no.'
            '</playtext></collectdtmf></response>' % kookoo_session_id)

        resp = self.kookoo_in({
            "cid": "0002",
            "sid": kookoo_session_id,
            "event": "GotDTMF",
            "data": "2",
        })
        self.assertEqual(resp, '<response sid="%s"><hangup/></response>' % kookoo_session_id)

        self.kookoo_finished({
            "sid": kookoo_session_id,
            "status": "answered",
            "duration": "20",
        })
        call2 = CallLog.get(call2._id)
        self.assertTrue(call2.answered)
        self.assertEqual(call2.duration, 20)

        form = self.get_last_form_submission()
        self.assertFormQuestionEquals(form, "how_feel", "1")
        self.assertFormQuestionEquals(form, "take_meds", "2")
        self.assertEqual(form.form["meta"]["userID"], self.user2._id)
        case = CommCareCase.get(self.case._id)
        self.assertCasePropertyEquals(case, "how_feel", "1")
        self.assertCasePropertyEquals(case, "take_meds", "2")
        self.assertEqual(case.user_id, self.user2._id)
Example #4
0
 def fire_reminders():
     CaseReminderHandler.fire_reminders()
    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=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)
    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)