예제 #1
0
class MigrationTaskTest(TestCase):

    def setUp(self):
        self.datapath = os.path.join(os.path.dirname(__file__), 'data')
        initial_bootstrap(TEST_DOMAIN)
        self.sms_backend = TestSMSBackend(name="MOBILE_BACKEND_TEST", is_global=True)
        self.sms_backend._id = self.sms_backend.name
        self.sms_backend.save()

        config = ILSGatewayConfig()
        config.domain = TEST_DOMAIN
        config.enabled = True
        config.password = '******'
        config.username = '******'
        config.url = 'http://test-api.com/'
        config.save()
        for product in Product.by_domain(TEST_DOMAIN):
            product.delete()

    def tearDown(self):
        self.sms_backend.delete()

    def test_migration(self):
        ils_bootstrap_domain_test_task(TEST_DOMAIN, MockEndpoint('http://test-api.com/', 'dummy', 'dummy'))
        self.assertEqual(6, len(list(Product.by_domain(TEST_DOMAIN))))
        self.assertEqual(5, len(list(Location.by_domain(TEST_DOMAIN))))
        self.assertEqual(6, len(list(CommCareUser.by_domain(TEST_DOMAIN))))
        self.assertEqual(5, len(list(WebUser.by_domain(TEST_DOMAIN))))

    @classmethod
    def tearDownClass(cls):
        for user in WebUser.by_domain(TEST_DOMAIN):
            user.delete()
예제 #2
0
class BaseReminderTestCase(BaseAccountingTest):
    def setUp(self):
        super(BaseReminderTestCase, self).setUp()
        self.domain_obj = Domain(name="test")
        self.domain_obj.save()
        # Prevent resource conflict
        self.domain_obj = Domain.get(self.domain_obj._id)

        self.account, _ = BillingAccount.get_or_create_account_by_domain(
            self.domain_obj.name,
            created_by="tests"
        )
        advanced_plan_version = DefaultProductPlan.get_default_plan_by_domain(
            self.domain_obj, edition=SoftwarePlanEdition.ADVANCED)
        self.subscription = Subscription.new_domain_subscription(
            self.account,
            self.domain_obj.name,
            advanced_plan_version
        )
        self.subscription.is_active = True
        self.subscription.save()

        self.sms_backend = TestSMSBackend(named="MOBILE_BACKEND_TEST", is_global=True)
        self.sms_backend.save()

        self.sms_backend_mapping = BackendMapping(is_global=True,prefix="*",backend_id=self.sms_backend._id)
        self.sms_backend_mapping.save()

    def tearDown(self):
        self.sms_backend_mapping.delete()
        self.sms_backend.delete()
        SubscriptionAdjustment.objects.all().delete()
        self.subscription.delete()
        self.account.delete()
        self.domain_obj.delete()
예제 #3
0
class OptTestCase(BaseAccountingTest):
    def setUp(self):
        super(OptTestCase, self).setUp()
        self.domain = "opt-test"

        self.domain_obj = Domain(name=self.domain)
        self.domain_obj.save()

        generator.instantiate_accounting_for_tests()
        self.account = BillingAccount.get_or_create_account_by_domain(
            self.domain_obj.name, created_by="automated-test"
        )[0]
        plan = DefaultProductPlan.get_default_plan_by_domain(self.domain_obj, edition=SoftwarePlanEdition.ADVANCED)
        self.subscription = Subscription.new_domain_subscription(self.account, self.domain_obj.name, plan)
        self.subscription.is_active = True
        self.subscription.save()

        self.backend = TestSMSBackend(is_global=True)
        self.backend.save()

        self.backend_mapping = BackendMapping(is_global=True, prefix="*", backend_id=self.backend._id)
        self.backend_mapping.save()

    def test_opt_out_and_opt_in(self):
        self.assertEqual(PhoneNumber.objects.count(), 0)

        incoming("99912345678", "stop", "GVI")
        self.assertEqual(PhoneNumber.objects.count(), 1)
        phone_number = PhoneNumber.objects.get(phone_number="99912345678")
        self.assertFalse(phone_number.send_sms)

        incoming("99912345678", "start", "GVI")
        self.assertEqual(PhoneNumber.objects.count(), 1)
        phone_number = PhoneNumber.objects.get(phone_number="99912345678")
        self.assertTrue(phone_number.send_sms)

    def test_sending_to_opted_out_number(self):
        self.assertEqual(PhoneNumber.objects.count(), 0)
        self.assertTrue(send_sms(self.domain, None, "999123456789", "hello"))

        incoming("999123456789", "stop", "GVI")
        self.assertEqual(PhoneNumber.objects.count(), 1)
        phone_number = PhoneNumber.objects.get(phone_number="999123456789")
        self.assertFalse(phone_number.send_sms)

        self.assertFalse(send_sms(self.domain, None, "999123456789", "hello"))

    def tearDown(self):
        self.backend_mapping.delete()
        self.backend.delete()
        self.domain_obj.delete()

        SubscriptionAdjustment.objects.all().delete()
        self.subscription.delete()
        self.account.delete()
예제 #4
0
파일: util.py 프로젝트: johan--/commcare-hq
class TouchformsTestCase(LiveServerTestCase):
    """
    For now, these test cases need to be run manually. Before running, the 
    following dependencies must be met:
        1. touchforms/backend/localsettings.py:
            URL_ROOT = "http://localhost:8081/a/{{DOMAIN}}"
        2. Django localsettings.py:
            TOUCHFORMS_API_USER = "******"
            TOUCHFORMS_API_PASSWORD = "******"
        3. Start touchforms
    """

    users = None
    apps = None
    keywords = None
    groups = None

    def create_domain(self, domain):
        domain_obj = Domain(name=domain)
        domain_obj.use_default_sms_response = True
        domain_obj.default_sms_response = "Default SMS Response"
        domain_obj.save()

        # I tried making this class inherit from BaseSMSTest, but somehow
        # the multiple inheritance was causing the postgres connection to
        # get in a weird state where it wasn't commiting any changes. So
        # for now, keeping this subscription setup code as is.
        generator.instantiate_accounting_for_tests()
        self.account = BillingAccount.get_or_create_account_by_domain(
            domain_obj.name,
            created_by="automated-test",
        )[0]
        plan = DefaultProductPlan.get_default_plan_by_domain(
            domain_obj, edition=SoftwarePlanEdition.ADVANCED
        )
        self.subscription = Subscription.new_domain_subscription(
            self.account,
            domain_obj.name,
            plan
        )
        self.subscription.is_active = True
        self.subscription.save()
        return domain_obj

    def create_mobile_worker(self, username, password, phone_number, save_vn=True):
        user = CommCareUser.create(self.domain, username, password,
            phone_number=phone_number)
        if save_vn:
            user.save_verified_number(self.domain, phone_number, True, None)
        self.users.append(user)
        return user

    def update_case_owner(self, case, owner):
        case_block = CaseBlock(
            create=False,
            case_id=case._id,
            case_type='participant',
            owner_id=owner._id,
            user_id=owner._id,
        ).as_xml()
        FormProcessorInterface.post_case_blocks([case_block], {'domain': self.domain})

    def add_parent_access(self, user, case):
        case_block = CaseBlock(
            create=True,
            case_id=uuid.uuid4().hex,
            case_type='magic_map',
            owner_id=user._id,
            index={'parent': ('participant', case._id)}
        ).as_xml()
        FormProcessorInterface.post_case_blocks([case_block], {'domain': self.domain})

    def create_web_user(self, username, password):
        user = WebUser.create(self.domain, username, password)
        self.users.append(user)
        return user

    def create_group(self, name, users):
        group = Group(
            domain=self.domain,
            name=name,
            users=[user._id for user in users],
            case_sharing=True,
        )
        group.save()
        self.groups.append(group)
        return group

    def load_app(self, filename, dirname=None):
        dirname = dirname or os.path.dirname(os.path.abspath(__file__))
        full_filename = "%s/%s" % (dirname, filename)
        with open(full_filename, "r") as f:
            app_source = f.read()
            app_source = json.loads(app_source)
        app = import_app(app_source, self.domain)
        self.apps.append(app)
        return app

    def create_sms_keyword(self, keyword, reply_sms,
        override_open_sessions=True, initiator_filter=None,
        recipient=RECIPIENT_SENDER, recipient_id=None):
        sk = SurveyKeyword(
            domain=self.domain,
            keyword=keyword,
            description=keyword,
            actions=[SurveyKeywordAction(
                recipient=recipient,
                recipient_id=recipient_id,
                action=METHOD_SMS,
                message_content=reply_sms,
                form_unique_id=None,
                use_named_args=False,
                named_args={},
                named_args_separator=None,
            )],
            delimiter=None,
            override_open_sessions=override_open_sessions,
            initiator_doc_type_filter=initiator_filter or [],
        )
        sk.save()
        self.keywords.append(sk)
        return sk

    def create_survey_keyword(self, keyword, form_unique_id, delimiter=None,
        override_open_sessions=True, initiator_filter=None):
        sk = SurveyKeyword(
            domain=self.domain,
            keyword=keyword,
            description=keyword,
            actions=[SurveyKeywordAction(
                recipient=RECIPIENT_SENDER,
                recipient_id=None,
                action=METHOD_SMS_SURVEY,
                message_content=None,
                form_unique_id=form_unique_id,
                use_named_args=False,
                named_args={},
                named_args_separator=None,
            )],
            delimiter=delimiter,
            override_open_sessions=override_open_sessions,
            initiator_doc_type_filter=initiator_filter or [],
        )
        sk.save()
        self.keywords.append(sk)
        return sk

    def create_structured_sms_keyword(self, keyword, form_unique_id, reply_sms,
        delimiter=None, named_args=None, named_args_separator=None,
        override_open_sessions=True, initiator_filter=None):
        sk = SurveyKeyword(
            domain=self.domain,
            keyword=keyword,
            description=keyword,
            actions=[
                SurveyKeywordAction(
                    recipient=RECIPIENT_SENDER,
                    recipient_id=None,
                    action=METHOD_SMS,
                    message_content=reply_sms,
                    form_unique_id=None,
                    use_named_args=False,
                    named_args={},
                    named_args_separator=None,
                ),
                SurveyKeywordAction(
                    recipient=RECIPIENT_SENDER,
                    recipient_id=None,
                    action=METHOD_STRUCTURED_SMS,
                    message_content=None,
                    form_unique_id=form_unique_id,
                    use_named_args=(named_args is not None),
                    named_args=(named_args or {}),
                    named_args_separator=named_args_separator,
                )
            ],
            delimiter=delimiter,
            override_open_sessions=override_open_sessions,
            initiator_doc_type_filter=initiator_filter or [],
        )
        sk.save()
        self.keywords.append(sk)
        return sk

    def create_site(self):
        site = Site(id=settings.SITE_ID, domain=self.live_server_url,
            name=self.live_server_url)
        site.save()
        return site

    def get_case(self, external_id):
        return get_one_case_in_domain_by_external_id(self.domain, external_id)

    def assertCasePropertyEquals(self, case, prop, value):
        self.assertEquals(case.get_case_property(prop), value)

    def get_last_form_submission(self):
        result = get_forms_by_type(self.domain, 'XFormInstance',
                                   recent_first=True, limit=1)
        return result[0] if len(result) > 0 else None

    def assertNoNewSubmission(self, last_submission):
        new_submission = self.get_last_form_submission()
        self.assertEquals(last_submission._id, new_submission._id)

    def assertFormQuestionEquals(self, form, question, value, cast=None):
        self.assertIn(question, form.form)
        form_value = form.form[question]
        if cast:
            form_value = cast(form_value)
        self.assertEquals(form_value, value)

    def get_last_outbound_sms(self, contact):
        # Not clear why this should be necessary, but without it the latest
        # sms may not be returned
        sleep(0.25)
        sms = SMSLog.view("sms/by_recipient",
            startkey=[contact.doc_type, contact._id, "SMSLog", "O", {}],
            endkey=[contact.doc_type, contact._id, "SMSLog", "O"],
            descending=True,
            include_docs=True,
            reduce=False,
        ).first()
        return sms

    def get_last_outbound_call(self, contact):
        # Not clear why this should be necessary, but without it the latest
        # call may not be returned
        sleep(0.25)
        call = CallLog.view("sms/by_recipient",
            startkey=[contact.doc_type, contact._id, "CallLog", "O", {}],
            endkey=[contact.doc_type, contact._id, "CallLog", "O"],
            descending=True,
            include_docs=True,
            reduce=False,
        ).first()
        return call

    def get_open_session(self, contact):
        return SQLXFormsSession.get_open_sms_session(self.domain, contact._id)

    def assertLastOutboundSMSEquals(self, contact, message):
        sms = self.get_last_outbound_sms(contact)
        self.assertIsNotNone(sms)
        self.assertEqual(sms.text, message)
        return sms

    def assertMetadataEqual(self, sms, xforms_session_couch_id=None, workflow=None):
        if xforms_session_couch_id:
            self.assertEqual(sms.xforms_session_couch_id, xforms_session_couch_id)
        if workflow:
            self.assertEqual(sms.workflow, workflow)

    def setUp(self):
        self.users = []
        self.apps = []
        self.keywords = []
        self.groups = []
        self.site = self.create_site()
        self.domain = "test-domain"
        self.domain_obj = self.create_domain(self.domain)
        self.create_web_user("touchforms_user", "123")

        self.backend = TestSMSBackend(name="TEST", is_global=True)
        self.backend.save()
        self.backend_mapping = BackendMapping(is_global=True, prefix="*",
            backend_id=self.backend._id)
        self.backend_mapping.save()

        settings.DEBUG = True

    def tearDown(self):
        for user in self.users:
            user.delete_verified_number()
            user.delete()
        for app in self.apps:
            app.delete()
        for keyword in self.keywords:
            keyword.delete()
        for group in self.groups:
            group.delete()
        self.domain_obj.delete()
        self.site.delete()
        self.backend.delete()
        self.backend_mapping.delete()
        SubscriptionAdjustment.objects.all().delete()
        self.subscription.delete()
        self.account.delete()
예제 #5
0
class AllBackendTest(BaseSMSTest):
    def setUp(self):
        super(AllBackendTest, self).setUp()
        backend_api.TEST = True

        self.domain_obj = Domain(name='all-backend-test')
        self.domain_obj.save()
        self.create_account_and_subscription(self.domain_obj.name)
        self.domain_obj = Domain.get(self.domain_obj._id)

        self.test_phone_number = '99912345'
        self.contact1 = CommCareCase(domain=self.domain_obj.name)
        self.contact1.set_case_property('contact_phone_number', self.test_phone_number)
        self.contact1.set_case_property('contact_phone_number_is_verified', '1')
        self.contact1.save()
        self.contact1 = CommConnectCase.wrap(self.contact1.to_json())

        # For use with megamobile only
        self.contact2 = CommCareCase(domain=self.domain_obj.name)
        self.contact2.set_case_property('contact_phone_number', '63%s' % self.test_phone_number)
        self.contact2.set_case_property('contact_phone_number_is_verified', '1')
        self.contact2.save()
        self.contact2 = CommConnectCase.wrap(self.contact2.to_json())

        self.unicel_backend = UnicelBackend(name='UNICEL', is_global=True)
        self.unicel_backend.save()

        self.mach_backend = MachBackend(name='MACH', is_global=True)
        self.mach_backend.save()

        self.tropo_backend = TropoBackend(name='TROPO', is_global=True)
        self.tropo_backend.save()

        self.http_backend = HttpBackend(name='HTTP', is_global=True)
        self.http_backend.save()

        self.telerivet_backend = TelerivetBackend(name='TELERIVET', is_global=True,
            webhook_secret='telerivet-webhook-secret')
        self.telerivet_backend.save()

        self.test_backend = TestSMSBackend(name='TEST', is_global=True)
        self.test_backend.save()

        self.grapevine_backend = GrapevineBackend(name='GRAPEVINE', is_global=True)
        self.grapevine_backend.save()

        self.twilio_backend = TwilioBackend(name='TWILIO', is_global=True)
        self.twilio_backend.save()

        self.megamobile_backend = MegamobileBackend(name='MEGAMOBILE', is_global=True)
        self.megamobile_backend.save()

        self.smsgh_backend = SMSGHBackend(name='SMSGH', is_global=True)
        self.smsgh_backend.save()

        self.apposit_backend = AppositBackend(name='APPOSIT', is_global=True)
        self.apposit_backend.save()

    def _test_outbound_backend(self, backend, msg_text, mock_send):
        self.domain_obj.default_sms_backend_id = backend._id
        self.domain_obj.save()

        send_sms(self.domain_obj.name, None, self.test_phone_number, msg_text)
        sms = SMS.objects.get(
            domain=self.domain_obj.name,
            direction='O',
            text=msg_text
        )

        self.assertTrue(mock_send.called)
        msg_arg = mock_send.call_args[0][0]
        self.assertEqual(msg_arg.date, sms.date)

    def _verify_inbound_request(self, backend_api_id, msg_text):
        sms = SMS.objects.get(
            domain=self.domain_obj.name,
            direction='I',
            text=msg_text
        )
        self.assertEqual(sms.backend_api, backend_api_id)

    def _simulate_inbound_request_with_payload(self, url,
            content_type, payload):
        response = Client().post(url, payload, content_type=content_type)
        self.assertEqual(response.status_code, 200)

    def _simulate_inbound_request(self, url, phone_param,
            msg_param, msg_text, post=False, additional_params=None):
        fcn = Client().post if post else Client().get

        payload = {
            phone_param: self.test_phone_number,
            msg_param: msg_text,
        }

        if additional_params:
            payload.update(additional_params)

        response = fcn(url, payload)
        self.assertEqual(response.status_code, 200)

    @patch('corehq.messaging.smsbackends.unicel.api.UnicelBackend.send')
    @patch('corehq.messaging.smsbackends.mach.api.MachBackend.send')
    @patch('corehq.messaging.smsbackends.tropo.api.TropoBackend.send')
    @patch('corehq.messaging.smsbackends.http.api.HttpBackend.send')
    @patch('corehq.messaging.smsbackends.telerivet.models.TelerivetBackend.send')
    @patch('corehq.messaging.smsbackends.test.api.TestSMSBackend.send')
    @patch('corehq.messaging.smsbackends.grapevine.api.GrapevineBackend.send')
    @patch('corehq.messaging.smsbackends.twilio.models.TwilioBackend.send')
    @patch('corehq.messaging.smsbackends.megamobile.api.MegamobileBackend.send')
    @patch('corehq.messaging.smsbackends.smsgh.models.SMSGHBackend.send')
    @patch('corehq.messaging.smsbackends.apposit.models.AppositBackend.send')
    def test_outbound_sms(
            self,
            apposit_send,
            smsgh_send,
            megamobile_send,
            twilio_send,
            grapevine_send,
            test_send,
            telerivet_send,
            http_send,
            tropo_send,
            mach_send,
            unicel_send):
        self._test_outbound_backend(self.unicel_backend, 'unicel test', unicel_send)
        self._test_outbound_backend(self.mach_backend, 'mach test', mach_send)
        self._test_outbound_backend(self.tropo_backend, 'tropo test', tropo_send)
        self._test_outbound_backend(self.http_backend, 'http test', http_send)
        self._test_outbound_backend(self.telerivet_backend, 'telerivet test', telerivet_send)
        self._test_outbound_backend(self.test_backend, 'test test', test_send)
        self._test_outbound_backend(self.grapevine_backend, 'grapevine test', grapevine_send)
        self._test_outbound_backend(self.twilio_backend, 'twilio test', twilio_send)
        self._test_outbound_backend(self.megamobile_backend, 'megamobile test', megamobile_send)
        self._test_outbound_backend(self.smsgh_backend, 'smsgh test', smsgh_send)
        self._test_outbound_backend(self.apposit_backend, 'apposit test', apposit_send)

    def test_unicel_inbound_sms(self):
        self._simulate_inbound_request('/unicel/in/', phone_param=InboundParams.SENDER,
            msg_param=InboundParams.MESSAGE, msg_text='unicel test')

        self._verify_inbound_request(self.unicel_backend.get_api_id(), 'unicel test')

    def test_tropo_inbound_sms(self):
        tropo_data = {'session': {'from': {'id': self.test_phone_number}, 'initialText': 'tropo test'}}
        self._simulate_inbound_request_with_payload('/tropo/sms/',
            content_type='text/json', payload=json.dumps(tropo_data))

        self._verify_inbound_request(self.tropo_backend.get_api_id(), 'tropo test')

    def test_telerivet_inbound_sms(self):
        additional_params = {
            'event': 'incoming_message',
            'message_type': 'sms',
            'secret': self.telerivet_backend.webhook_secret
        }
        self._simulate_inbound_request('/telerivet/in/', phone_param='from_number_e164',
            msg_param='content', msg_text='telerivet test', post=True,
            additional_params=additional_params)

        self._verify_inbound_request(self.telerivet_backend.get_api_id(), 'telerivet test')

    @override_settings(SIMPLE_API_KEYS={'grapevine-test': 'grapevine-api-key'})
    def test_grapevine_inbound_sms(self):
        xml = """
        <gviSms>
            <smsDateTime>2015-10-12T12:00:00</smsDateTime>
            <cellNumber>99912345</cellNumber>
            <content>grapevine test</content>
        </gviSms>
        """
        payload = urlencode({'XML': xml})
        self._simulate_inbound_request_with_payload(
            '/gvi/api/sms/?apiuser=grapevine-test&apikey=grapevine-api-key',
            content_type='application/x-www-form-urlencoded', payload=payload)

        self._verify_inbound_request(self.grapevine_backend.get_api_id(), 'grapevine test')

    def test_twilio_inbound_sms(self):
        self._simulate_inbound_request('/twilio/sms/', phone_param='From',
            msg_param='Body', msg_text='twilio test', post=True)

        self._verify_inbound_request(self.twilio_backend.get_api_id(), 'twilio test')

    def test_megamobile_inbound_sms(self):
        self._simulate_inbound_request('/megamobile/sms/', phone_param='cel',
            msg_param='msg', msg_text='megamobile test')

        self._verify_inbound_request(self.megamobile_backend.get_api_id(), 'megamobile test')

    def test_sislog_inbound_sms(self):
        self._simulate_inbound_request('/sislog/in/', phone_param='sender',
            msg_param='msgdata', msg_text='sislog test')

        self._verify_inbound_request('SISLOG', 'sislog test')

    def test_yo_inbound_sms(self):
        self._simulate_inbound_request('/yo/sms/', phone_param='sender',
            msg_param='message', msg_text='yo test')

        self._verify_inbound_request('YO', 'yo test')

    def test_smsgh_inbound_sms(self):
        user = ApiUser.create('smsgh-api-key', 'smsgh-api-key', permissions=[PERMISSION_POST_SMS])
        user.save()

        self._simulate_inbound_request('/smsgh/sms/smsgh-api-key/', phone_param='snr',
            msg_param='msg', msg_text='smsgh test')

        self._verify_inbound_request('SMSGH', 'smsgh test')

        user.delete()

    def test_apposit_inbound_sms(self):
        user = ApiUser.create('apposit-api-key', 'apposit-api-key', permissions=[PERMISSION_POST_SMS])
        user.save()

        self._simulate_inbound_request(
            '/apposit/in/apposit-api-key/',
            phone_param='fromAddress',
            msg_param='content',
            msg_text='apposit test',
            post=True,
            additional_params={'channel': 'SMS'}
        )
        self._verify_inbound_request('APPOSIT', 'apposit test')

        user.delete()

    def tearDown(self):
        backend_api.TEST = False
        self.contact1.get_verified_number().delete()
        self.contact1.delete()
        self.contact2.get_verified_number().delete()
        self.contact2.delete()
        self.domain_obj.delete()
        self.unicel_backend.delete()
        self.mach_backend.delete()
        self.tropo_backend.delete()
        self.http_backend.delete()
        self.telerivet_backend.delete()
        self.test_backend.delete()
        self.grapevine_backend.delete()
        self.twilio_backend.delete()
        self.megamobile_backend.delete()
        self.smsgh_backend.delete()
        self.apposit_backend.delete()
        super(AllBackendTest, self).tearDown()