def test_date_case_properties_for_equality(self):
        """
        Date case properties are automatically converted from string to date
        when fetching from the db, so here we want to make sure this doesn't
        interfere with our ability to compare dates for equality.
        """
        case = CommCareCase(
            domain=self.domain,
            type='test-case-type-2',
        )

        self.rule2.automaticupdaterulecriteria_set = [
            AutomaticUpdateRuleCriteria(
                property_name='property1',
                property_value='2016-02-24',
                match_type=AutomaticUpdateRuleCriteria.MATCH_EQUAL,
            ),
        ]

        case.set_case_property('property1', '2016-02-24')
        case.save()
        case = CommCareCase.get(case.get_id)
        case.server_modified_on = datetime(2015, 1, 1)
        self.assertTrue(self.rule2.rule_matches_case(case, datetime(2016, 1, 1)))

        case.set_case_property('property1', '2016-02-25')
        case.save()
        case = CommCareCase.get(case.get_id)
        case.server_modified_on = datetime(2015, 1, 1)
        self.assertFalse(self.rule2.rule_matches_case(case, datetime(2016, 1, 1)))

        case.delete()
Example #2
0
class UtilTestCase(TestCase):
    
    def setUp(self):
        self.case = CommCareCase(domain='test-domain', name='test-case')
        self.case.save()
        self.user = CommCareUser.create('test-domain', 'test-user', '123')

    def tearDown(self):
        self.case.delete()
        self.user.delete()

    def testCleanPhoneNumber(self):
        phone_number = "  324 23-23421241"
        cleaned = clean_phone_number(phone_number)
        self.assertEquals(cleaned, "+3242323421241")

    def test_get_contact(self):
        contact = get_contact(self.case.get_id)
        self.assertEqual(contact.get_id, self.case.get_id)
        self.assertTrue(isinstance(contact, CommConnectCase))

        contact = get_contact(self.user.get_id)
        self.assertEqual(contact.get_id, self.user.get_id)
        self.assertTrue(isinstance(contact, CommCareUser))

        with self.assertRaises(ContactNotFoundException):
            get_contact('this-id-should-not-be-found')

    def test_apply_leniency(self):
        self.assertEqual('16175551234', apply_leniency(' 1 (617) 555-1234 '))
        self.assertEqual('16175551234', apply_leniency(' 1.617.555.1234 '))
        self.assertEqual('16175551234', apply_leniency(' +1 617 555 1234 '))
    def setUp(self):
        self.now = datetime(2015, 10, 22, 0, 0)
        self.domain = 'auto-update-test'
        self.rule = AutomaticUpdateRule(
            domain=self.domain,
            name='test-rule',
            case_type='test-case-type',
            active=True,
            server_modified_boundary=30,
        )
        self.rule.save()
        self.rule.automaticupdaterulecriteria_set = [
            AutomaticUpdateRuleCriteria(
                property_name='last_visit_date',
                property_value='30',
                match_type=AutomaticUpdateRuleCriteria.MATCH_DAYS_SINCE,
            ),
        ]
        self.rule.automaticupdateaction_set = [
            AutomaticUpdateAction(
                action=AutomaticUpdateAction.ACTION_UPDATE,
                property_name='update_flag',
                property_value='Y',
            ),
            AutomaticUpdateAction(
                action=AutomaticUpdateAction.ACTION_CLOSE,
            ),
        ]

        self.rule2 = AutomaticUpdateRule(
            domain=self.domain,
            name='test-rule-2',
            case_type='test-case-type-2',
            active=True,
            server_modified_boundary=30,
        )
        self.rule2.save()
        self.rule2.automaticupdateaction_set = [
            AutomaticUpdateAction(
                action=AutomaticUpdateAction.ACTION_CLOSE,
            ),
        ]

        self.rule3 = AutomaticUpdateRule(
            domain=self.domain,
            name='test-rule-3',
            case_type='test-case-type-2',
            active=True,
            server_modified_boundary=50,
        )
        self.rule3.save()
        self.rule3.automaticupdateaction_set = [
            AutomaticUpdateAction(
                action=AutomaticUpdateAction.ACTION_CLOSE,
            ),
        ]

        case = CommCareCase(domain=self.domain, type='test-case-type')
        case.save()
        self.case_id = case.get_id
Example #4
0
    def test_get_list(self):
        """
        Any case in the appropriate domain should be in the list from the API.
        """

        # The actual infrastructure involves saving to CouchDB, having PillowTop
        # read the changes and write it to ElasticSearch.

        #the pillow is set to offline mode - elasticsearch not needed to validate
        pillow = CasePillow(online=False)
        fake_case_es = FakeXFormES()
        v0_4.MOCK_CASE_ES = fake_case_es

        modify_date = datetime.utcnow()

        backend_case = CommCareCase(server_modified_on=modify_date, domain=self.domain.name)
        backend_case.type = CC_BIHAR_PREGNANCY
        backend_case.save()

        translated_doc = pillow.change_transform(backend_case.to_json())

        fake_case_es.add_doc(translated_doc['_id'], translated_doc)

        self.client.login(username=self.username, password=self.password)

        response = self.client.get(self.list_endpoint)
        self.assertEqual(response.status_code, 200)

        api_cases = simplejson.loads(response.content)['objects']
        self.assertEqual(len(api_cases), 2)

        api_case = api_cases['mother_lists'][0]
        self.assertEqual(dateutil.parser.parse(api_case['server_date_modified']), backend_case.server_modified_on)

        backend_case.delete()
Example #5
0
    def test_get_list(self):
        """
        Any case in the appropriate domain should be in the list from the API.
        """

        # The actual infrastructure involves saving to CouchDB, having PillowTop
        # read the changes and write it to ElasticSearch.

        # the pillow is set to offline mode - elasticsearch not needed to validate
        fake_case_es = FakeXFormES()
        v0_4.MOCK_CASE_ES = fake_case_es

        modify_date = datetime.utcnow()

        backend_case = CommCareCase(server_modified_on=modify_date, domain=self.domain.name)
        backend_case.save()
        self.addCleanup(backend_case.delete)

        translated_doc = transform_case_for_elasticsearch(backend_case.to_json())

        fake_case_es.add_doc(translated_doc['_id'], translated_doc)

        response = self._assert_auth_get_resource(self.list_endpoint)
        self.assertEqual(response.status_code, 200)

        api_cases = json.loads(response.content)['objects']
        self.assertEqual(len(api_cases), 1)

        api_case = api_cases[0]
        self.assertEqual(api_case['server_date_modified'], json_format_datetime(backend_case.server_modified_on))
Example #6
0
    def hard_rebuild_case(domain, case_id, detail):
        try:
            case = CommCareCase.get(case_id)
            assert case.domain == domain
            found = True
        except CaseNotFound:
            case = CommCareCase()
            case.case_id = case_id
            case.domain = domain
            found = False

        forms = FormProcessorCouch.get_case_forms(case_id)
        filtered_forms = [f for f in forms if f.is_normal]
        sorted_forms = sorted(filtered_forms, key=lambda f: f.received_on)

        actions = _get_actions_from_forms(domain, sorted_forms, case_id)

        if not found and case.domain is None:
            case.domain = domain

        rebuild_case_from_actions(case, actions)
        # todo: should this move to case.rebuild?
        if not case.xform_ids:
            if not found:
                return None
            # there were no more forms. 'delete' the case
            case.doc_type = 'CommCareCase-Deleted'

        # add a "rebuild" action
        case.actions.append(_rebuild_action())
        case.save()
        return case
Example #7
0
class TestUtilFunctions(TestCase):
    def setUp(self):
        self.case = CommCareCase(domain='test-domain', name='test-case')
        self.case.save()

        self.user = CommCareUser.create('test-domain', 'test-user', '123')

    def test_get_contact(self):
        contact = get_contact(self.case.get_id)
        self.assertEqual(contact.get_id, self.case.get_id)
        self.assertTrue(isinstance(contact, CommConnectCase))

        contact = get_contact(self.user.get_id)
        self.assertEqual(contact.get_id, self.user.get_id)
        self.assertTrue(isinstance(contact, CommCareUser))

        try:
            get_contact('this-id-should-not-be-found')
        except Exception:
            pass
        else:
            self.assertTrue(False)

    def test_apply_leniency(self):
        self.assertEqual('16175551234', apply_leniency(' 1 (617) 555-1234 '))
        self.assertEqual('16175551234', apply_leniency(' 1.617.555.1234 '))
        self.assertEqual('16175551234', apply_leniency(' +1 617 555 1234 '))

    def tearDown(self):
        self.case.delete()
        self.user.delete()
Example #8
0
    def test_get_list(self):
        """
        Any case in the appropriate domain should be in the list from the API.
        """

        # The actual infrastructure involves saving to CouchDB, having PillowTop
        # read the changes and write it to ElasticSearch.

        # the pillow is set to offline mode - elasticsearch not needed to validate
        fake_case_es = FakeXFormES()
        v0_3.MOCK_CASE_ES = fake_case_es

        modify_date = datetime.utcnow()

        backend_case = CommCareCase(server_modified_on=modify_date,
                                    domain=self.domain.name)
        backend_case.save()
        self.addCleanup(backend_case.delete)

        translated_doc = transform_case_for_elasticsearch(
            backend_case.to_json())

        fake_case_es.add_doc(translated_doc['_id'], translated_doc)

        response = self._assert_auth_get_resource(self.list_endpoint)
        self.assertEqual(response.status_code, 200)

        api_cases = json.loads(response.content)['objects']
        self.assertEqual(len(api_cases), 1)

        api_case = api_cases[0]
        self.assertEqual(api_case['server_date_modified'],
                         json_format_datetime(backend_case.server_modified_on))
Example #9
0
    def testParentCase(self):
        headers = ['parent_id', 'name', 'case_id']
        config = self._config(headers,
                              create_new_cases=True,
                              search_column='case_id')
        rows = 3
        parent_case = CommCareCase(domain=self.domain,
                                   type=self.default_case_type)
        parent_case.save()

        file = MockExcelFile(header_columns=headers,
                             num_rows=rows,
                             row_generator=id_match_generator(
                                 parent_case['_id']))
        file_missing = MockExcelFile(header_columns=headers, num_rows=rows)

        # Should successfully match on `rows` cases
        res = do_import(file, config, self.domain)
        self.assertEqual(rows, res['created_count'])

        # Should be unable to find parent case on `rows` cases
        res = do_import(file_missing, config, self.domain)
        self.assertEqual(
            rows, len(res['errors'][ImportErrors.InvalidParentId]['rows']),
            "All cases should have missing parent")
    def test_date_case_properties_for_inequality(self):
        case = CommCareCase(
            domain=self.domain,
            type='test-case-type-2',
        )

        self.rule2.automaticupdaterulecriteria_set = [
            AutomaticUpdateRuleCriteria(
                property_name='property1',
                property_value='2016-02-24',
                match_type=AutomaticUpdateRuleCriteria.MATCH_NOT_EQUAL,
            ),
        ]

        case.set_case_property('property1', '2016-02-24')
        case.save()
        case = CommCareCase.get(case.get_id)
        case.server_modified_on = datetime(2015, 1, 1)
        self.assertFalse(self.rule2.rule_matches_case(case, datetime(2016, 1, 1)))

        case.set_case_property('property1', '2016-02-25')
        case.save()
        case = CommCareCase.get(case.get_id)
        case.server_modified_on = datetime(2015, 1, 1)
        self.assertTrue(self.rule2.rule_matches_case(case, datetime(2016, 1, 1)))

        case.delete()
Example #11
0
    def test_get_list(self):
        """
        Any case in the appropriate domain should be in the list from the API.
        """

        # The actual infrastructure involves saving to CouchDB, having PillowTop
        # read the changes and write it to ElasticSearch.

        #the pillow is set to offline mode - elasticsearch not needed to validate
        pillow = CasePillow(online=False)
        fake_case_es = FakeXFormES()
        v0_4.MOCK_CASE_ES = fake_case_es

        modify_date = datetime.utcnow()

        backend_case = CommCareCase(server_modified_on=modify_date, domain=self.domain.name)
        backend_case.save()

        translated_doc = pillow.change_transform(backend_case.to_json())

        fake_case_es.add_doc(translated_doc['_id'], translated_doc)

        self.client.login(username=self.username, password=self.password)

        response = self.client.get(self.list_endpoint)
        self.assertEqual(response.status_code, 200)

        api_cases = simplejson.loads(response.content)['objects']
        self.assertEqual(len(api_cases), 1)

        api_case = api_cases[0]
        self.assertEqual(dateutil.parser.parse(api_case['server_date_modified']), backend_case.server_modified_on)

        backend_case.delete()
Example #12
0
def rebuild_case(case_id):
    """
    Given a case ID, rebuild the entire case state based on all existing forms
    referencing it. Useful when things go wrong or when you need to manually
    rebuild a case after archiving / deleting it
    """

    try:
        case = CommCareCase.get(case_id)
        found = True
    except ResourceNotFound:
        case = CommCareCase()
        case._id = case_id
        found = False

    # clear actions, xform_ids, close state, and all dynamic properties
    dynamic_properties = set([k for action in case.actions for k in action.updated_unknown_properties.keys()])
    for k in dynamic_properties:
        try:
            delattr(case, k)
        except KeyError:
            pass

    # already deleted means it was explicitly set to "deleted",
    # as opposed to getting set to that because it has no actions
    already_deleted = case.doc_type == 'CommCareCase-Deleted' and primary_actions(case)
    if not already_deleted:
        case.doc_type = 'CommCareCase'
    case.xform_ids = []
    case.actions = []
    case.closed = False
    case.closed_on = None
    case.closed_by = ''

    form_ids = get_case_xform_ids(case_id)
    forms = [fetch_and_wrap_form(id) for id in form_ids]
    filtered_forms = [f for f in forms if f.doc_type == "XFormInstance"]
    sorted_forms = sorted(filtered_forms, key=lambda f: f.received_on)
    for form in sorted_forms:
        if not found and case.domain is None:
            case.domain = form.domain
        assert form.domain == case.domain

        case_updates = get_case_updates(form)
        filtered_updates = [u for u in case_updates if u.id == case_id]
        for u in filtered_updates:
            case.update_from_case_update(u, form)

    case.xform_ids = [f._id for f in sorted_forms]
    if not case.xform_ids:
        if not found:
            return None
        # there were no more forms. 'delete' the case
        case.doc_type = 'CommCareCase-Deleted'

    # add a "rebuild" action
    case.actions.append(_rebuild_action())
    case.save()
    return case
Example #13
0
class TestReverseIndexedCases(TestCase):
    def setUp(self):
        super(TestReverseIndexedCases, self).setUp()
        self.domain = 'domain'
        self.factory = CaseFactory(self.domain)
        self.indexed_case_id = uuid.uuid4().hex
        self.index = CommCareCaseIndex(identifier="host",
                                       referenced_type="host",
                                       relationship=CASE_INDEX_EXTENSION,
                                       referenced_id=self.indexed_case_id)
        self.case = CommCareCase(domain=self.domain, indices=[self.index])
        self.case.save()

    def tearDown(self):
        FormProcessorTestUtils.delete_all_cases()
        FormProcessorTestUtils.delete_all_xforms()
        super(TestReverseIndexedCases, self).tearDown()

    def _delete_relationship(self):
        del self.case.indices[0].relationship
        self.case.save()

    def test_legacy_reverse_index(self):
        """Test that cases with indices without a relationship are still returned"""
        self.assertEqual([self.case._id], [
            c._id for c in get_reverse_indexed_cases(
                self.domain, [self.indexed_case_id],
                relationship=CASE_INDEX_EXTENSION)
        ])
        # remove the relationship and make sure the case is still returned when asking for child indexes
        self._delete_relationship()
        self.assertEqual([self.case._id], [
            c._id for c in get_reverse_indexed_cases(self.domain,
                                                     [self.indexed_case_id])
        ])
        # make sure it doesn't show up if we are asking for extension indexes
        self.assertEqual([], [
            c._id for c in get_reverse_indexed_cases(
                self.domain, [self.indexed_case_id], CASE_INDEX_EXTENSION)
        ])

    def test_legacy_reverse_index_json(self):
        expected_returned_json = [{
            'doc_type': 'CommCareCaseIndex',
            'identifier': self.index.identifier,
            'relationship': self.index.relationship,
            'referenced_type': self.index.referenced_type,
            'referenced_id': self.case._id
        }]
        self.assertEqual(
            expected_returned_json,
            get_reverse_indices_json(self.domain, self.indexed_case_id))

        self._delete_relationship()
        # it should now be a child relationship
        expected_returned_json[0]['relationship'] = CASE_INDEX_CHILD
        self.assertEqual(
            expected_returned_json,
            get_reverse_indices_json(self.domain, self.indexed_case_id))
Example #14
0
class TestReverseIndexedCases(TestCase):

    def setUp(self):
        super(TestReverseIndexedCases, self).setUp()
        self.domain = 'domain'
        self.factory = CaseFactory(self.domain)
        self.indexed_case_id = uuid.uuid4().hex
        self.index = CommCareCaseIndex(
            identifier="host",
            referenced_type="host",
            relationship=CASE_INDEX_EXTENSION,
            referenced_id=self.indexed_case_id
        )
        self.case = CommCareCase(domain=self.domain, indices=[self.index])
        self.case.save()

    def tearDown(self):
        FormProcessorTestUtils.delete_all_cases()
        FormProcessorTestUtils.delete_all_xforms()
        super(TestReverseIndexedCases, self).tearDown()

    def _delete_relationship(self):
        del self.case.indices[0].relationship
        self.case.save()

    def test_legacy_reverse_index(self):
        """Test that cases with indices without a relationship are still returned"""
        self.assertEqual(
            [self.case._id],
            [c._id for c in
             get_reverse_indexed_cases(self.domain, [self.indexed_case_id], relationship=CASE_INDEX_EXTENSION)])
        # remove the relationship and make sure the case is still returned when asking for child indexes
        self._delete_relationship()
        self.assertEqual(
            [self.case._id],
            [c._id for c in get_reverse_indexed_cases(self.domain, [self.indexed_case_id])])
        # make sure it doesn't show up if we are asking for extension indexes
        self.assertEqual(
            [],
            [c._id for c in
             get_reverse_indexed_cases(self.domain, [self.indexed_case_id], CASE_INDEX_EXTENSION)])

    def test_legacy_reverse_index_json(self):
        expected_returned_json = [{
            'doc_type': 'CommCareCaseIndex',
            'identifier': self.index.identifier,
            'relationship': self.index.relationship,
            'referenced_type': self.index.referenced_type,
            'referenced_id': self.case._id
        }]
        self.assertEqual(
            expected_returned_json,
            get_reverse_indices_json(self.domain, self.indexed_case_id))

        self._delete_relationship()
        # it should now be a child relationship
        expected_returned_json[0]['relationship'] = CASE_INDEX_CHILD
        self.assertEqual(expected_returned_json, get_reverse_indices_json(self.domain, self.indexed_case_id))
Example #15
0
def saving(request):
    xform = XFormInstance(_attachments={'form.xml': {'data': '-'}})
    xform.save()
    case = CommCareCase()
    case.save()
    xform.initial_processing_complete = True
    xform.save()
    case.delete()
    xform.delete()
    return HttpResponse('Thanks for submitting', status=201)
Example #16
0
class RebuildStockStateTest(TestCase):
    def setUp(self):
        self.domain = 'asldkjf-domain'
        self.case = CommCareCase(domain=self.domain)
        self.case.save()
        self.product = make_product(self.domain, 'Product Name', 'prodcode')
        self._stock_state_key = dict(
            section_id='stock',
            case_id=self.case.get_id,
            product_id=self.product.get_id
        )

    def _get_stats(self):
        stock_state = StockState.objects.get(**self._stock_state_key)
        latest_txn = StockTransaction.latest(**self._stock_state_key)
        all_txns = StockTransaction.get_ordered_transactions_for_stock(
            **self._stock_state_key)
        return stock_state, latest_txn, all_txns

    def _submit_ledgers(self, ledger_blocks):
        submit_case_blocks(ledger_blocks.format(**self._stock_state_key),
                           self.domain)

    def test_simple(self):
        self._submit_ledgers(LEDGER_BLOCKS_SIMPLE)
        stock_state, latest_txn, all_txns = self._get_stats()
        self.assertEqual(stock_state.stock_on_hand, 100)
        self.assertEqual(latest_txn.stock_on_hand, 100)
        self.assertEqual(all_txns.count(), 2)

        rebuild_stock_state(**self._stock_state_key)

        stock_state, latest_txn, all_txns = self._get_stats()
        self.assertEqual(stock_state.stock_on_hand, 200)
        self.assertEqual(latest_txn.stock_on_hand, 200)
        self.assertEqual(all_txns.count(), 2)

    def test_inferred(self):
        self._submit_ledgers(LEDGER_BLOCKS_INFERRED)
        stock_state, latest_txn, all_txns = self._get_stats()
        # this is weird behavior:
        # it just doesn't process the second one
        # even though knowing yesterday's certainly changes the meaning
        # of today's transfer
        self.assertEqual(stock_state.stock_on_hand, 50)
        self.assertEqual(latest_txn.stock_on_hand, 50)
        self.assertEqual(all_txns.count(), 3)

        rebuild_stock_state(**self._stock_state_key)

        stock_state, latest_txn, all_txns = self._get_stats()

        self.assertEqual(stock_state.stock_on_hand, 150)
        self.assertEqual(latest_txn.stock_on_hand, 150)
        self.assertEqual(all_txns.count(), 2)
Example #17
0
 def test_recursive_indexes(self):
     c = CommCareCase(
         _id='infinite-recursion',
         name='infinite_recursion',
         type='bug',
         indices=[CommCareCaseIndex(identifier='self', referenced_type='bug', referenced_id='infinite-recursion')],
     )
     c.save()
     # this call used to fail with infinite recursion
     hierarchy = get_case_hierarchy(c, {})
     self.assertEqual(1, len(hierarchy['case_list']))
Example #18
0
    def test_get_doc_count_in_domain_by_class(self):
        case = CommCareCase(domain=self.domain, opened_on=datetime.datetime(2000, 1, 1))
        case.save()
        self.addCleanup(case.delete)
        case2 = CommCareCase(domain=self.domain, opened_on=datetime.datetime(2001, 1, 1))
        case2.save()
        self.addCleanup(case2.delete)

        get = functools.partial(
            get_doc_count_in_domain_by_class, self.domain, CommCareCase)

        self.assertEqual(get(), 2)
Example #19
0
class RebuildStockStateTest(TestCase):
    def setUp(self):
        self.domain = 'asldkjf-domain'
        self.case = CommCareCase(domain=self.domain)
        self.case.save()
        self.product = make_product(self.domain, 'Product Name', 'prodcode')
        self._stock_state_key = dict(section_id='stock',
                                     case_id=self.case.get_id,
                                     product_id=self.product.get_id)

    def _get_stats(self):
        stock_state = StockState.objects.get(**self._stock_state_key)
        latest_txn = StockTransaction.latest(**self._stock_state_key)
        all_txns = StockTransaction.get_ordered_transactions_for_stock(
            **self._stock_state_key)
        return stock_state, latest_txn, all_txns

    def _submit_ledgers(self, ledger_blocks):
        submit_case_blocks(ledger_blocks.format(**self._stock_state_key),
                           self.domain)

    def test_simple(self):
        self._submit_ledgers(LEDGER_BLOCKS_SIMPLE)
        stock_state, latest_txn, all_txns = self._get_stats()
        self.assertEqual(stock_state.stock_on_hand, 100)
        self.assertEqual(latest_txn.stock_on_hand, 100)
        self.assertEqual(all_txns.count(), 2)

        rebuild_stock_state(**self._stock_state_key)

        stock_state, latest_txn, all_txns = self._get_stats()
        self.assertEqual(stock_state.stock_on_hand, 200)
        self.assertEqual(latest_txn.stock_on_hand, 200)
        self.assertEqual(all_txns.count(), 2)

    def test_inferred(self):
        self._submit_ledgers(LEDGER_BLOCKS_INFERRED)
        stock_state, latest_txn, all_txns = self._get_stats()
        # this is weird behavior:
        # it just doesn't process the second one
        # even though knowing yesterday's certainly changes the meaning
        # of today's transfer
        self.assertEqual(stock_state.stock_on_hand, 50)
        self.assertEqual(latest_txn.stock_on_hand, 50)
        self.assertEqual(all_txns.count(), 3)

        rebuild_stock_state(**self._stock_state_key)

        stock_state, latest_txn, all_txns = self._get_stats()

        self.assertEqual(stock_state.stock_on_hand, 150)
        self.assertEqual(latest_txn.stock_on_hand, 150)
        self.assertEqual(all_txns.count(), 2)
Example #20
0
 def testCaseLookupTypeCheck(self):
     case = CommCareCase(domain=self.domain, type='nonmatch-type')
     case.save()
     self.assertEqual(1, len(get_case_ids_in_domain(self.domain)))
     config = self._config(self.default_headers)
     file = MockExcelFile(header_columns=self.default_headers, num_rows=3,
                          row_generator=id_match_generator(case._id))
     res = do_import(file, config, self.domain)
     # because the type is wrong these shouldn't match
     self.assertEqual(3, res['created_count'])
     self.assertEqual(0, res['match_count'])
     self.assertEqual(4, len(get_case_ids_in_domain(self.domain)))
Example #21
0
    def _create_change(self):
        case = CommCareCase(domain=self.domain)
        case.save()

        change = Change(
            case._id,
            'seq',
            document_store=CouchDocumentStore(
                CommCareCase.get_db(),
                self.domain,
            )
        )
        return change, case
    def test_invalid_phone_format(self):
        case = CommCareCase(
            domain='case-phone-number-test',
            name='TEST1'
        )
        case.set_case_property('contact_phone_number', '99987658765')
        case.set_case_property('contact_phone_number_is_verified', '1')
        case.save()
        self.assertIsNotNone(self.get_case_verified_number(case))

        case.set_case_property('contact_phone_number', 'xyz')
        case.save()
        self.assertIsNone(self.get_case_verified_number(case))
        case.delete()
Example #23
0
def rebuild_case(case_id):
    """
    Given a case ID, rebuild the entire case state based on all existing forms
    referencing it. Useful when things go wrong or when you need to manually
    rebuild a case after archiving / deleting it
    """

    try:
        case = CommCareCase.get(case_id)
        found = True
    except ResourceNotFound:
        case = CommCareCase()
        case._id = case_id
        found = False

    reset_state(case)
    # in addition to resetting the state, also manually clear xform_ids and actions
    # since we're going to rebuild these from the forms
    case.xform_ids = []
    case.actions = []

    forms = get_case_forms(case_id)
    filtered_forms = [f for f in forms if f.doc_type == "XFormInstance"]
    sorted_forms = sorted(filtered_forms, key=lambda f: f.received_on)
    for form in sorted_forms:
        if not found and case.domain is None:
            case.domain = form.domain
        assert form.domain == case.domain

        case_updates = get_case_updates(form)
        filtered_updates = [u for u in case_updates if u.id == case_id]
        for u in filtered_updates:
            case.actions.extend(u.get_case_actions(form))

    # call "rebuild" on the case, which should populate xform_ids
    # and re-sort actions if necessary
    case.rebuild(strict=False, xforms={f._id: f for f in sorted_forms})
    case.xform_ids = case.xform_ids + [f._id for f in sorted_forms if f._id not in case.xform_ids]

    # todo: should this move to case.rebuild?
    if not case.xform_ids:
        if not found:
            return None
        # there were no more forms. 'delete' the case
        case.doc_type = 'CommCareCase-Deleted'

    # add a "rebuild" action
    case.actions.append(_rebuild_action())
    case.save()
    return case
    def test_case_zero_phone_number(self):
        case = CommCareCase(
            domain='case-phone-number-test',
            name='TEST1'
        )
        set_case_property_directly(case, 'contact_phone_number', '99987658765')
        set_case_property_directly(case, 'contact_phone_number_is_verified', '1')
        case.save()
        self.assertIsNotNone(self.get_case_verified_number(case))

        set_case_property_directly(case, 'contact_phone_number', '0')
        case.save()
        self.assertIsNone(self.get_case_verified_number(case))
        case.delete()
    def test_case_soft_delete(self):
        case = CommCareCase(
            domain='case-phone-number-test',
            name='TEST1'
        )
        case.set_case_property('contact_phone_number', '99987658765')
        case.set_case_property('contact_phone_number_is_verified', '1')
        case.save()
        self.assertIsNotNone(self.get_case_verified_number(case))

        case.doc_type += '-Deleted'
        case.save()
        self.assertIsNone(self.get_case_verified_number(case))
        case.delete()
 def testForceSave(self):
     original = CommCareCase()
     original.save()
     conflict = CommCareCase.get(original._id)
     original.foo = 'bar'
     conflict.foo = 'not bar'
     original.save()
     try:
         conflict.save()
         self.fail('conflicting save should fail hard!')
     except ResourceConflict:
         pass
     conflict.force_save()
     self.assertEqual('not bar', CommCareCase.get(original._id).foo) 
Example #27
0
    def testCaseAPIResultJSON(self):
        case = CommCareCase()
        # because of how setattr is overridden you have to set it to None in this wacky way
        case._doc['type'] = None
        case.save()
        self.addCleanup(case.delete)
        self.assertEqual(None, CommCareCase.get(case.case_id).type)
        res_sanitized = CaseAPIResult(domain=TEST_DOMAIN, id=case.case_id, couch_doc=case, sanitize=True)
        res_unsanitized = CaseAPIResult(domain=TEST_DOMAIN, id=case.case_id, couch_doc=case, sanitize=False)

        json = res_sanitized.case_json
        self.assertEqual(json['properties']['case_type'], '')

        json = res_unsanitized.case_json
        self.assertEqual(json['properties']['case_type'], None)
Example #28
0
 def test_recursive_indexes(self):
     c = CommCareCase(
         _id='infinite-recursion',
         name='infinite_recursion',
         type='bug',
         indices=[
             CommCareCaseIndex(identifier='self',
                               referenced_type='bug',
                               referenced_id='infinite-recursion')
         ],
     )
     c.save()
     # this call used to fail with infinite recursion
     hierarchy = get_case_hierarchy(c, {})
     self.assertEqual(1, len(hierarchy['case_list']))
Example #29
0
    def test_derived_properties(self):
        """
        Smoke test that the HOPE properties do not crash on a pretty empty CommCareCase
        """

        modify_date = datetime.utcnow()

        backend_case = CommCareCase(server_modified_on=modify_date, domain=self.domain.name)
        backend_case.save()

        # Rather than a re-fetch, this simulates the common case where it is pulled from ES
        hope_case = HOPECase.wrap(backend_case.to_json())

        self.hit_every_HOPE_property(hope_case)

        backend_case.delete()
Example #30
0
class MessageTestCase(BaseReminderTestCase):

    def setUp(self):
        self.domain = "test"

        self.parent_case = CommCareCase(
            domain=self.domain,
            type="parent",
            name="P001",
        )
        self.parent_case.set_case_property("parent_prop1", "abc")
        self.parent_case.save()

        self.child_case = CommCareCase(
            domain=self.domain,
            type="child",
            name="P002",
            indices=[CommCareCaseIndex(
                identifier="parent",
                referenced_type="parent",
                referenced_id=self.parent_case._id,
            )],
        )
        self.child_case.set_case_property("child_prop1", "def")
        self.child_case.save()

    def tearDown(self):
        self.child_case.delete()
        self.parent_case.delete()

    def test_message(self):
        message = 'The EDD for client with ID {case.external_id} is approaching in {case.edd.days_until} days.'
        case = {'external_id': 123, 'edd': datetime.utcnow() + timedelta(days=30)}
        outcome = 'The EDD for client with ID 123 is approaching in 30 days.'
        self.assertEqual(Message.render(message, case=case), outcome)

    def test_template_params(self):
        child_result = {"case": self.child_case.case_properties()}
        child_result["case"]["parent"] = self.parent_case.case_properties()
        self.assertEqual(
            get_message_template_params(self.child_case), child_result)

        parent_result = {"case": self.parent_case.case_properties()}
        parent_result["case"]["parent"] = {}
        self.assertEqual(
            get_message_template_params(self.parent_case), parent_result)
Example #31
0
    def testCaseAPIResultJSON(self):
        try:
            case = CommCareCase()
            # because of how setattr is overridden you have to set it to None in this wacky way
            case._doc["type"] = None
            case.save()
            self.assertEqual(None, CommCareCase.get(case._id).type)
            res_sanitized = CaseAPIResult(id=case._id, couch_doc=case, sanitize=True)
            res_unsanitized = CaseAPIResult(id=case._id, couch_doc=case, sanitize=False)

            json = res_sanitized.case_json
            self.assertEqual(json["properties"]["case_type"], "")

            json = res_unsanitized.case_json
            self.assertEqual(json["properties"]["case_type"], None)
        finally:
            case.delete()
    def _setup_fake_es(self):
        # The actual infrastructure involves saving to CouchDB, having PillowTop
        # read the changes and write it to ElasticSearch.

        # the pillow is set to offline mode - elasticsearch not needed to validate
        fake_case_es = FakeXFormES()
        v0_3.MOCK_CASE_ES = fake_case_es

        modify_date = datetime.utcnow()

        backend_case = CommCareCase(server_modified_on=modify_date, domain=self.domain.name)
        backend_case.save()
        self.addCleanup(backend_case.delete)

        translated_doc = transform_case_for_elasticsearch(backend_case.to_json())

        fake_case_es.add_doc(translated_doc['_id'], translated_doc)
        return backend_case
    def setUp(self):
        self.now = datetime(2015, 10, 22, 0, 0)
        self.domain = "auto-update-test"
        self.rule = AutomaticUpdateRule(
            domain=self.domain, name="test-rule", case_type="test-case-type", active=True, server_modified_boundary=30
        )
        self.rule.save()
        self.rule.automaticupdaterulecriteria_set = [
            AutomaticUpdateRuleCriteria(
                property_name="last_visit_date",
                property_value="30",
                match_type=AutomaticUpdateRuleCriteria.MATCH_DAYS_SINCE,
            )
        ]
        self.rule.automaticupdateaction_set = [
            AutomaticUpdateAction(
                action=AutomaticUpdateAction.ACTION_UPDATE, property_name="update_flag", property_value="Y"
            ),
            AutomaticUpdateAction(action=AutomaticUpdateAction.ACTION_CLOSE),
        ]

        self.rule2 = AutomaticUpdateRule(
            domain=self.domain,
            name="test-rule-2",
            case_type="test-case-type-2",
            active=True,
            server_modified_boundary=30,
        )
        self.rule2.save()
        self.rule2.automaticupdateaction_set = [AutomaticUpdateAction(action=AutomaticUpdateAction.ACTION_CLOSE)]

        self.rule3 = AutomaticUpdateRule(
            domain=self.domain,
            name="test-rule-3",
            case_type="test-case-type-2",
            active=True,
            server_modified_boundary=50,
        )
        self.rule3.save()
        self.rule3.automaticupdateaction_set = [AutomaticUpdateAction(action=AutomaticUpdateAction.ACTION_CLOSE)]

        case = CommCareCase(domain=self.domain, type="test-case-type")
        case.save()
        self.case_id = case.get_id
Example #34
0
    def testExternalIdMatching(self):
        # bootstrap a stub case
        case = CommCareCase(domain=self.domain, type=self.default_case_type)
        external_id = 'importer-test-external-id'
        case.external_id = external_id
        case.save()
        self.assertEqual(1, len(get_case_ids_in_domain(self.domain)))

        headers = ['external_id', 'age', 'sex', 'location']
        config = self._config(headers, search_field='external_id')
        file = MockExcelFile(header_columns=headers, num_rows=3,
                             row_generator=id_match_generator(external_id))
        res = do_import(file, config, self.domain)
        self.assertEqual(0, res['created_count'])
        self.assertEqual(3, res['match_count'])
        self.assertFalse(res['errors'])

        # shouldn't create any more cases, just the one
        self.assertEqual(1, len(get_case_ids_in_domain(self.domain)))
Example #35
0
    def test_normal_index(self):
        cp = CommCareCase(
            _id='parent',
            name='parent',
            type='parent',
        )
        cp.save()

        cc = CommCareCase(
            _id='child',
            name='child',
            type='child',
            indices=[CommCareCaseIndex(identifier='parent', referenced_type='parent', referenced_id='parent')],
        )
        cc.save()

        hierarchy = get_case_hierarchy(cp, {})
        self.assertEqual(2, len(hierarchy['case_list']))
        self.assertEqual(1, len(hierarchy['child_cases']))
Example #36
0
    def hard_rebuild_case(domain, case_id, detail, save=True, lock=True):
        if lock:
            # only record metric if locking since otherwise it has been
            # (most likley) recorded elsewhere
            case_load_counter("rebuild_case", domain)()
        case, lock_obj = FormProcessorCouch.get_case_with_lock(case_id, lock=lock, wrap=True)
        found = bool(case)
        if not found:
            case = CommCareCase()
            case.case_id = case_id
            case.domain = domain
            if lock:
                lock_obj = CommCareCase.get_obj_lock_by_id(case_id)
                acquire_lock(lock_obj, degrade_gracefully=False)

        try:
            assert case.domain == domain, (case.domain, domain)
            forms = FormProcessorCouch.get_case_forms(case_id)
            form_load_counter("rebuild_case", domain)(len(forms))
            filtered_forms = [f for f in forms if f.is_normal]
            sorted_forms = sorted(filtered_forms, key=lambda f: f.received_on)

            actions = _get_actions_from_forms(domain, sorted_forms, case_id)

            if not found and case.domain is None:
                case.domain = domain

            rebuild_case_from_actions(case, actions)
            # todo: should this move to case.rebuild?
            if not case.xform_ids:
                if not found:
                    return None
                # there were no more forms. 'delete' the case
                case.doc_type = 'CommCareCase-Deleted'

            # add a "rebuild" action
            case.actions.append(_rebuild_action())
            if save:
                case.save()
            return case
        finally:
            release_lock(lock_obj, degrade_gracefully=True)
Example #37
0
    def setUp(self):
        for doc in get_all_forms_in_all_domains():
            # purge all xforms prior to start
            if doc.xmlns in [XMLNS_DOTS_FORM, XMLNS_PATIENT_UPDATE_DOT]:
                doc.delete()

        two_weeks = timedelta(days=14)
        self.domain = Domain()
        self.domain.name = PACT_DOMAIN
        self.domain.is_active = True
        self.domain.date_created = datetime.utcnow() - two_weeks
        self.domain.save()

        self.submit_url = '/a/%s/receiver' % self.domain.name

        self.user = CommCareUser.create(self.domain.name, 'ctsims', 'mockmock', uuid=CTSIMS_ID)

        nonart_case_regimens = regimen_dict_from_choice(DOT_NONART, "morning,evening,bedtime")
        art_case_regimens = regimen_dict_from_choice(DOT_ART, "morning,noon")
        props= {'_id': CASE_ID, 'dot_status': 'DOT1', 'domain': self.domain.name}
        props.update(nonart_case_regimens)
        props.update(art_case_regimens)

        case = CommCareCase(**props)
        case.save()

        #generate CaseDoc

        self.pillbox_form = ""
        with open(os.path.join(os.path.abspath(os.path.dirname(__file__)), 'dots_data',
                               '01_pillbox.xml')) as fin:
            self.pillbox_form = fin.read()

        self.no_pillbox_form = ""
        with open(os.path.join(os.path.abspath(os.path.dirname(__file__)), 'dots_data',
                               '02_no_pillbox.xml')) as fin:
            self.no_pillbox_form = fin.read()
        self.no_pillbox_form2 = ""
        with open(os.path.join(os.path.abspath(os.path.dirname(__file__)), 'dots_data',
                               '03_no_pillbox.xml')) as fin:
            self.no_pillbox_form2 = fin.read()
Example #38
0
    def test_normal_index(self):
        cp = CommCareCase(
            _id='parent',
            name='parent',
            type='parent',
        )
        cp.save()

        cc = CommCareCase(
            _id='child',
            name='child',
            type='child',
            indices=[
                CommCareCaseIndex(identifier='parent',
                                  referenced_type='parent',
                                  referenced_id='parent')
            ],
        )
        cc.save()

        hierarchy = get_case_hierarchy(cp, {})
        self.assertEqual(2, len(hierarchy['case_list']))
        self.assertEqual(1, len(hierarchy['child_cases']))
Example #39
0
    def _setup_case(self, cases=None):

        modify_date = datetime.utcnow()

        cases = cases or [(None, None)]
        for owner_id, case_id in cases:
            kwargs = {}
            if owner_id:
                kwargs['owner_id'] = owner_id
            if case_id:
                kwargs['_id'] = case_id
            backend_case = CommCareCase(server_modified_on=modify_date,
                                        domain=self.domain.name,
                                        **kwargs)
            backend_case.save()
            self.addCleanup(backend_case.delete)

            translated_doc = transform_case_for_elasticsearch(
                backend_case.to_json())

            send_to_elasticsearch('cases', translated_doc)
        self.es.indices.refresh(CASE_INDEX_INFO.index)
        return backend_case
Example #40
0
    def test_complex_index(self):
        cp = CommCareCase(
            _id='parent',
            name='parent',
            type='parent',
        )
        cp.save()

        # cases processed according to ID order so ensure that this case is
        # processed after the task case by making its ID sort after task ID
        cc = CommCareCase(
            _id='z_goal',
            name='goal',
            type='goal',
            indices=[
                CommCareCaseIndex(identifier='parent',
                                  referenced_type='parent',
                                  referenced_id='parent')
            ],
        )
        cc.save()

        cc = CommCareCase(
            _id='task1',
            name='task1',
            type='task',
            indices=[
                CommCareCaseIndex(identifier='goal',
                                  referenced_type='goal',
                                  referenced_id='z_goal'),
                CommCareCaseIndex(identifier='parent',
                                  referenced_type='parent',
                                  referenced_id='parent')
            ],
        )
        cc.save()

        # with 'ignore_relationship_types' if a case got processed along the ignored relationship first
        # then it got marked as 'seen' and would be not be processed again when it came to the correct relationship
        type_info = {
            'task': {
                'ignore_relationship_types': ['parent']
            },
        }

        hierarchy = get_case_hierarchy(cp, type_info)
        self.assertEqual(3, len(hierarchy['case_list']))
        self.assertEqual(1, len(hierarchy['child_cases']))
        self.assertEqual(2, len(hierarchy['child_cases'][0]['case_list']))
        self.assertEqual(1, len(hierarchy['child_cases'][0]['child_cases']))
Example #41
0
class TestGetInfoResourcesListOneCase(TestCase, DomainSubscriptionMixin):
    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.domain_obj = create_domain(DOMAIN)
        cls.setup_subscription(DOMAIN, SoftwarePlanEdition.PRO)

        cls.case_type = CaseType.objects.create(domain=DOMAIN, name='person')
        name = CaseProperty.objects.create(case_type=cls.case_type,
                                           name='name')

        resource_type = FHIRResourceType.objects.create(
            domain=DOMAIN, case_type=cls.case_type, name='Patient')
        FHIRResourceProperty.objects.create(
            resource_type=resource_type,
            case_property=name,
            jsonpath='$.name[0].text',
        )

    @classmethod
    def tearDownClass(cls):
        cls.case_type.delete()
        cls.teardown_subscriptions()
        cls.domain_obj.delete()
        clear_plan_version_cache()
        super().tearDownClass()

    def setUp(self):
        now = datetime.utcnow()
        self.case_id = str(uuid4())
        self.case = CommCareCase(
            _id=self.case_id,
            domain=DOMAIN,
            type='person',
            name='Ted',
            owner_id=str(uuid4()),
            modified_on=now,
            server_modified_on=now,
        )
        self.case.save()

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

    def test_get_info_resource_list(self):
        resource_type = get_resource_type_or_none(self.case,
                                                  FHIR_VERSION_4_0_1)
        case_trigger_infos = [get_case_trigger_info(self.case, resource_type)]
        resource_types_by_case_type = {'person': resource_type}
        [(info, resource)] = get_info_resource_list(
            case_trigger_infos,
            resource_types_by_case_type,
        )
        self.assertEqual(
            resource, {
                'id': self.case_id,
                'name': [{
                    'text': 'Ted'
                }],
                'resourceType': 'Patient'
            })
Example #42
0
class KooKooTestCase(TouchformsTestCase):
    """
    Must be run manually (see corehq.apps.sms.tests.util.TouchformsTestCase)
    """
    def setUp(self):
        super(KooKooTestCase, self).setUp()
        self.ivr_backend = MobileBackend(
            _id="MOBILE_BACKEND_KOOKOO",
            outbound_module="corehq.apps.kookoo.api",
            outbound_params={
                "is_test": True,
                "api_key": "xyz"
            },
        )
        self.ivr_backend.save()

        self.user1 = self.create_mobile_worker("user1",
                                               "123",
                                               "91001",
                                               save_vn=False)
        self.user2 = self.create_mobile_worker("user2",
                                               "123",
                                               "91002",
                                               save_vn=False)
        self.create_group("group1", [self.user1, self.user2])

        self.case = CommCareCase(
            domain=self.domain,
            type="participant",
            owner_id=self.groups[0]._id,
        )
        self.case.set_case_property("contact_phone_number", "91000")
        self.case.set_case_property("contact_phone_number_is_verified", "1")
        self.case.set_case_property("contact_ivr_backend_id",
                                    "MOBILE_BACKEND_KOOKOO")
        self.case.save()

        dirname = os.path.dirname(os.path.abspath(__file__))
        self.load_app("app1.json", dirname)
        self.load_app("app2.json", dirname)

        self.reminder1 = CaseReminderHandler(
            domain=self.domain,
            active=True,
            case_type="participant",
            method=METHOD_IVR_SURVEY,
            recipient=RECIPIENT_CASE,
            sample_id=None,
            user_group_id=None,
            user_id=None,
            case_id=None,
            reminder_type=REMINDER_TYPE_DEFAULT,
            submit_partial_forms=True,
            include_case_side_effects=False,
            max_question_retries=5,
            start_condition_type=CASE_CRITERIA,
            start_property="name",
            start_value="case1",
            start_date=None,
            start_offset=0,
            start_match_type=MATCH_EXACT,
            events=[
                CaseReminderEvent(
                    day_num=0,
                    fire_time=time(12, 0),
                    fire_time_type=FIRE_TIME_DEFAULT,
                    callback_timeout_intervals=[30],
                    form_unique_id=self.apps[0].modules[0].forms[0].unique_id,
                ),
                CaseReminderEvent(
                    day_num=0,
                    fire_time=time(13, 0),
                    fire_time_type=FIRE_TIME_DEFAULT,
                    callback_timeout_intervals=[30],
                    form_unique_id=self.apps[0].modules[0].forms[1].unique_id,
                ),
            ],
            schedule_length=1,
            event_interpretation=EVENT_AS_SCHEDULE,
            max_iteration_count=7,
            until=None,
            force_surveys_to_use_triggered_case=False,
        )
        self.reminder1.save()

        self.reminder2 = CaseReminderHandler(
            domain=self.domain,
            active=True,
            case_type="participant",
            method=METHOD_IVR_SURVEY,
            recipient=RECIPIENT_OWNER,
            sample_id=None,
            user_group_id=None,
            user_id=None,
            case_id=None,
            reminder_type=REMINDER_TYPE_DEFAULT,
            submit_partial_forms=True,
            include_case_side_effects=True,
            max_question_retries=5,
            start_condition_type=CASE_CRITERIA,
            start_property="name",
            start_value="case2",
            start_date=None,
            start_offset=0,
            start_match_type=MATCH_EXACT,
            events=[
                CaseReminderEvent(
                    day_num=0,
                    fire_time=time(12, 0),
                    fire_time_type=FIRE_TIME_DEFAULT,
                    callback_timeout_intervals=[30, 30],
                    form_unique_id=self.apps[1].modules[0].forms[0].unique_id,
                ),
            ],
            schedule_length=1,
            event_interpretation=EVENT_AS_SCHEDULE,
            max_iteration_count=7,
            until=None,
            force_surveys_to_use_triggered_case=False,
        )
        self.reminder2.save()

    def kookoo_in(self, params):
        """
        params should be a dictionary containing:
        event, cid, sid, and (optionally) data
        """
        params = urllib.urlencode(params)
        url = "%s/kookoo/ivr/" % self.live_server_url
        return urllib2.urlopen("%s?%s" % (url, params)).read()

    def kookoo_finished(self, params):
        """
        params should be a dictionary containing:
        sid, status, and duration
        """
        params = urllib.urlencode(params)
        url = "%s/kookoo/ivr_finished/" % self.live_server_url
        return urllib2.urlopen(url, params).read()

    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.name = "case1"
        self.case.save()
        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(self.case._id)
        self.case.name = "case2"
        self.case.save()
        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)

    def tearDown(self):
        self.ivr_backend.delete()
        super(KooKooTestCase, self).tearDown()
Example #43
0
class TestGetInfoResourcesListSubCases(TestCase, DomainSubscriptionMixin):
    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.domain_obj = create_domain(DOMAIN)
        cls.setup_subscription(DOMAIN, SoftwarePlanEdition.PRO)

        cls.person_case_type = CaseType.objects.create(domain=DOMAIN,
                                                       name='person')
        name = CaseProperty.objects.create(case_type=cls.person_case_type,
                                           name='name')

        resource_type_for_person = FHIRResourceType.objects.create(
            domain=DOMAIN, case_type=cls.person_case_type, name='Patient')
        FHIRResourceProperty.objects.create(
            resource_type=resource_type_for_person,
            case_property=name,
            jsonpath='$.name[0].text',
        )
        FHIRResourceProperty.objects.create(
            resource_type=resource_type_for_person,
            value_source_config={
                'subcase_value_source': {
                    'case_property': 'given_names',
                    # Use counter1 to skip the name set by the parent case
                    'jsonpath': '$.name[{counter1}].given',
                    'commcare_data_type': COMMCARE_DATA_TYPE_TEXT,
                    'external_data_type': FHIR_DATA_TYPE_LIST_OF_STRING,
                },
                'case_types': ['person_name'],
            })
        FHIRResourceProperty.objects.create(
            resource_type=resource_type_for_person,
            value_source_config={
                'subcase_value_source': {
                    'case_property': 'family_name',
                    'jsonpath': '$.name[{counter1}].family',
                },
                'case_types': ['person_name'],
            })

    @classmethod
    def tearDownClass(cls):
        cls.person_case_type.delete()
        cls.teardown_subscriptions()
        cls.domain_obj.delete()
        clear_plan_version_cache()
        super().tearDownClass()

    def setUp(self):
        now = datetime.utcnow()
        self.parent_case_id = str(uuid4())
        self.parent_case = CommCareCase(
            _id=self.parent_case_id,
            domain=DOMAIN,
            type='person',
            name='Ted',
            owner_id=str(uuid4()),
            modified_on=now,
            server_modified_on=now,
        )
        self.parent_case.save()

        self.child_case_1 = CommCareCase(
            case_id='111111111',
            domain=DOMAIN,
            type='person_name',
            name='Theodore',
            given_names='Theodore John',
            family_name='Kaczynski',
            indices=[
                CommCareCaseIndex(
                    identifier='parent',
                    referenced_type='person',
                    referenced_id=self.parent_case_id,
                )
            ],
            owner_id=str(uuid4()),
            modified_on=now,
            server_modified_on=now,
        )
        self.child_case_1.save()
        self.child_case_2 = CommCareCase(
            case_id='222222222',
            domain=DOMAIN,
            type='person_name',
            name='Unabomber',
            given_names='Unabomber',
            indices=[
                CommCareCaseIndex(
                    identifier='parent',
                    referenced_type='person',
                    referenced_id=self.parent_case_id,
                )
            ],
            owner_id=str(uuid4()),
            modified_on=now,
            server_modified_on=now,
        )
        self.child_case_2.save()

    def tearDown(self):
        self.child_case_1.delete()
        self.child_case_2.delete()
        self.parent_case.delete()

    def test_get_info_resource_list(self):
        rt = get_resource_type_or_none(self.parent_case, FHIR_VERSION_4_0_1)
        case_trigger_infos = [get_case_trigger_info(self.parent_case, rt)]
        resource_types_by_case_type = {'person': rt}
        [(info, resource)] = get_info_resource_list(
            case_trigger_infos,
            resource_types_by_case_type,
        )
        self.assertEqual(
            resource, {
                'id':
                self.parent_case_id,
                'name': [
                    {
                        'text': 'Ted'
                    },
                    {
                        'given': ['Theodore', 'John'],
                        'family': 'Kaczynski'
                    },
                    {
                        'given': ['Unabomber']
                    },
                ],
                'resourceType':
                'Patient',
            })
Example #44
0
class BackendTestCase(TestCase):
    def setUp(self):
        self.domain = "test-domain"
        self.domain2 = "test-domain2"

        self.domain_obj = Domain(name=self.domain)
        self.domain_obj.save()
        self.domain_obj = Domain.get(
            self.domain_obj._id)  # Prevent resource conflict

        self.backend1 = TestCaseBackend(name="BACKEND1", is_global=True)
        self.backend1.save()

        self.backend2 = TestCaseBackend(name="BACKEND2", is_global=True)
        self.backend2.save()

        self.backend3 = TestCaseBackend(name="BACKEND3", is_global=True)
        self.backend3.save()

        self.backend4 = TestCaseBackend(name="BACKEND4", is_global=True)
        self.backend4.save()

        self.backend5 = TestCaseBackend(name="BACKEND5",
                                        domain=self.domain,
                                        is_global=False,
                                        authorized_domains=[])
        self.backend5.save()

        self.backend6 = TestCaseBackend(name="BACKEND6",
                                        domain=self.domain2,
                                        is_global=False,
                                        authorized_domains=[self.domain])
        self.backend6.save()

        self.backend7 = TestCaseBackend(name="BACKEND7",
                                        domain=self.domain2,
                                        is_global=False,
                                        authorized_domains=[])
        self.backend7.save()

        self.backend8 = TestCaseBackend(name="BACKEND",
                                        domain=self.domain,
                                        is_global=False,
                                        authorized_domains=[])
        self.backend8.save()

        self.backend9 = TestCaseBackend(name="BACKEND",
                                        domain=self.domain2,
                                        is_global=False,
                                        authorized_domains=[self.domain])
        self.backend9.save()

        self.backend10 = TestCaseBackend(name="BACKEND", is_global=True)
        self.backend10.save()

        self.backend_mapping1 = BackendMapping(is_global=True,
                                               prefix="*",
                                               backend_id=self.backend1._id)
        self.backend_mapping1.save()

        self.backend_mapping2 = BackendMapping(is_global=True,
                                               prefix="1",
                                               backend_id=self.backend2._id)
        self.backend_mapping2.save()

        self.backend_mapping3 = BackendMapping(is_global=True,
                                               prefix="91",
                                               backend_id=self.backend3._id)
        self.backend_mapping3.save()

        self.backend_mapping4 = BackendMapping(is_global=True,
                                               prefix="265",
                                               backend_id=self.backend4._id)
        self.backend_mapping4.save()

        self.case = CommCareCase(domain=self.domain)
        self.case.set_case_property("contact_phone_number", "15551234567")
        self.case.set_case_property("contact_phone_number_is_verified", "1")
        self.case.save()

        self.contact = CommConnectCase.wrap(self.case.to_json())

        settings.SMS_LOADED_BACKENDS.append(
            "corehq.apps.sms.tests.TestCaseBackend")

    def tearDown(self):
        self.backend1.delete_invoke_doc()
        self.backend1.delete()
        self.backend_mapping1.delete()

        self.backend2.delete_invoke_doc()
        self.backend2.delete()
        self.backend_mapping2.delete()

        self.backend3.delete_invoke_doc()
        self.backend3.delete()
        self.backend_mapping3.delete()

        self.backend4.delete_invoke_doc()
        self.backend4.delete()
        self.backend_mapping4.delete()

        self.backend5.delete_invoke_doc()
        self.backend5.delete()

        self.backend6.delete_invoke_doc()
        self.backend6.delete()

        self.backend7.delete_invoke_doc()
        self.backend7.delete()

        self.contact.delete_verified_number()
        self.case.delete()

        self.domain_obj.delete()

        settings.SMS_LOADED_BACKENDS.pop()

    def test_backend(self):
        # Test the backend map

        self.assertTrue(
            send_sms(self.domain, None, "15551234567", "Test for BACKEND2"))
        self.assertFalse(self.backend1.invoke_doc_exists())
        self.assertTrue(self.backend2.invoke_doc_exists())
        self.assertFalse(self.backend3.invoke_doc_exists())
        self.assertFalse(self.backend4.invoke_doc_exists())
        self.assertFalse(self.backend5.invoke_doc_exists())
        self.assertFalse(self.backend6.invoke_doc_exists())
        self.assertFalse(self.backend7.invoke_doc_exists())
        self.assertFalse(self.backend8.invoke_doc_exists())
        self.assertFalse(self.backend9.invoke_doc_exists())
        self.assertFalse(self.backend10.invoke_doc_exists())
        self.backend2.delete_invoke_doc()
        self.assertFalse(self.backend2.invoke_doc_exists())

        self.assertTrue(
            send_sms(self.domain, None, "9100000000", "Test for BACKEND3"))
        self.assertFalse(self.backend1.invoke_doc_exists())
        self.assertFalse(self.backend2.invoke_doc_exists())
        self.assertTrue(self.backend3.invoke_doc_exists())
        self.assertFalse(self.backend4.invoke_doc_exists())
        self.assertFalse(self.backend5.invoke_doc_exists())
        self.assertFalse(self.backend6.invoke_doc_exists())
        self.assertFalse(self.backend7.invoke_doc_exists())
        self.assertFalse(self.backend8.invoke_doc_exists())
        self.assertFalse(self.backend9.invoke_doc_exists())
        self.assertFalse(self.backend10.invoke_doc_exists())
        self.backend3.delete_invoke_doc()
        self.assertFalse(self.backend3.invoke_doc_exists())

        self.assertTrue(
            send_sms(self.domain, None, "26500000000", "Test for BACKEND4"))
        self.assertFalse(self.backend1.invoke_doc_exists())
        self.assertFalse(self.backend2.invoke_doc_exists())
        self.assertFalse(self.backend3.invoke_doc_exists())
        self.assertTrue(self.backend4.invoke_doc_exists())
        self.assertFalse(self.backend5.invoke_doc_exists())
        self.assertFalse(self.backend6.invoke_doc_exists())
        self.assertFalse(self.backend7.invoke_doc_exists())
        self.assertFalse(self.backend8.invoke_doc_exists())
        self.assertFalse(self.backend9.invoke_doc_exists())
        self.assertFalse(self.backend10.invoke_doc_exists())
        self.backend4.delete_invoke_doc()
        self.assertFalse(self.backend4.invoke_doc_exists())

        self.assertTrue(
            send_sms(self.domain, None, "25800000000", "Test for BACKEND1"))
        self.assertTrue(self.backend1.invoke_doc_exists())
        self.assertFalse(self.backend2.invoke_doc_exists())
        self.assertFalse(self.backend3.invoke_doc_exists())
        self.assertFalse(self.backend4.invoke_doc_exists())
        self.assertFalse(self.backend5.invoke_doc_exists())
        self.assertFalse(self.backend6.invoke_doc_exists())
        self.assertFalse(self.backend7.invoke_doc_exists())
        self.assertFalse(self.backend8.invoke_doc_exists())
        self.assertFalse(self.backend9.invoke_doc_exists())
        self.assertFalse(self.backend10.invoke_doc_exists())
        self.backend1.delete_invoke_doc()
        self.assertFalse(self.backend1.invoke_doc_exists())

        # Test overriding with a domain-level backend

        self.domain_obj.default_sms_backend_id = self.backend5._id
        self.domain_obj.save()

        self.assertTrue(
            send_sms(self.domain, None, "15551234567", "Test for BACKEND5"))
        self.assertFalse(self.backend1.invoke_doc_exists())
        self.assertFalse(self.backend2.invoke_doc_exists())
        self.assertFalse(self.backend3.invoke_doc_exists())
        self.assertFalse(self.backend4.invoke_doc_exists())
        self.assertTrue(self.backend5.invoke_doc_exists())
        self.assertFalse(self.backend6.invoke_doc_exists())
        self.assertFalse(self.backend7.invoke_doc_exists())
        self.assertFalse(self.backend8.invoke_doc_exists())
        self.assertFalse(self.backend9.invoke_doc_exists())
        self.assertFalse(self.backend10.invoke_doc_exists())
        self.backend5.delete_invoke_doc()
        self.assertFalse(self.backend5.invoke_doc_exists())

        # Test use of backend that another domain owns but has granted access

        self.domain_obj.default_sms_backend_id = self.backend6._id
        self.domain_obj.save()

        self.assertTrue(
            send_sms(self.domain, None, "25800000000", "Test for BACKEND6"))
        self.assertFalse(self.backend1.invoke_doc_exists())
        self.assertFalse(self.backend2.invoke_doc_exists())
        self.assertFalse(self.backend3.invoke_doc_exists())
        self.assertFalse(self.backend4.invoke_doc_exists())
        self.assertFalse(self.backend5.invoke_doc_exists())
        self.assertTrue(self.backend6.invoke_doc_exists())
        self.assertFalse(self.backend7.invoke_doc_exists())
        self.assertFalse(self.backend8.invoke_doc_exists())
        self.assertFalse(self.backend9.invoke_doc_exists())
        self.assertFalse(self.backend10.invoke_doc_exists())
        self.backend6.delete_invoke_doc()
        self.assertFalse(self.backend6.invoke_doc_exists())

        # Test backend access control

        self.domain_obj.default_sms_backend_id = self.backend7._id
        self.domain_obj.save()

        self.assertFalse(
            send_sms(self.domain, None, "25800000000", "Test for BACKEND7"))
        self.assertFalse(self.backend1.invoke_doc_exists())
        self.assertFalse(self.backend2.invoke_doc_exists())
        self.assertFalse(self.backend3.invoke_doc_exists())
        self.assertFalse(self.backend4.invoke_doc_exists())
        self.assertFalse(self.backend5.invoke_doc_exists())
        self.assertFalse(self.backend6.invoke_doc_exists())
        self.assertFalse(self.backend7.invoke_doc_exists())
        self.assertFalse(self.backend8.invoke_doc_exists())
        self.assertFalse(self.backend9.invoke_doc_exists())
        self.assertFalse(self.backend10.invoke_doc_exists())

        # Test sending to verified number with backend map

        self.domain_obj.default_sms_backend_id = None
        self.domain_obj.save()

        verified_number = self.contact.get_verified_number()
        self.assertTrue(verified_number is not None)
        self.assertTrue(verified_number.backend_id is None)
        self.assertEqual(verified_number.phone_number, "15551234567")

        self.assertTrue(
            send_sms_to_verified_number(verified_number, "Test for BACKEND2"))
        self.assertFalse(self.backend1.invoke_doc_exists())
        self.assertTrue(self.backend2.invoke_doc_exists())
        self.assertFalse(self.backend3.invoke_doc_exists())
        self.assertFalse(self.backend4.invoke_doc_exists())
        self.assertFalse(self.backend5.invoke_doc_exists())
        self.assertFalse(self.backend6.invoke_doc_exists())
        self.assertFalse(self.backend7.invoke_doc_exists())
        self.assertFalse(self.backend8.invoke_doc_exists())
        self.assertFalse(self.backend9.invoke_doc_exists())
        self.assertFalse(self.backend10.invoke_doc_exists())
        self.backend2.delete_invoke_doc()
        self.assertFalse(self.backend2.invoke_doc_exists())

        # Test sending to verified number with default domain backend

        self.domain_obj.default_sms_backend_id = self.backend5._id
        self.domain_obj.save()

        self.assertTrue(
            send_sms_to_verified_number(verified_number, "Test for BACKEND5"))
        self.assertFalse(self.backend1.invoke_doc_exists())
        self.assertFalse(self.backend2.invoke_doc_exists())
        self.assertFalse(self.backend3.invoke_doc_exists())
        self.assertFalse(self.backend4.invoke_doc_exists())
        self.assertTrue(self.backend5.invoke_doc_exists())
        self.assertFalse(self.backend6.invoke_doc_exists())
        self.assertFalse(self.backend7.invoke_doc_exists())
        self.assertFalse(self.backend8.invoke_doc_exists())
        self.assertFalse(self.backend9.invoke_doc_exists())
        self.assertFalse(self.backend10.invoke_doc_exists())
        self.backend5.delete_invoke_doc()
        self.assertFalse(self.backend5.invoke_doc_exists())

        # Test sending to verified number with a contact-level backend owned by the domain

        self.case.set_case_property("contact_backend_id", "BACKEND")
        self.case.save()
        self.contact = CommConnectCase.wrap(self.case.to_json())
        verified_number = self.contact.get_verified_number()
        self.assertTrue(verified_number is not None)
        self.assertEqual(verified_number.backend_id, "BACKEND")
        self.assertEqual(verified_number.phone_number, "15551234567")

        self.assertTrue(
            send_sms_to_verified_number(verified_number, "Test for BACKEND"))
        self.assertFalse(self.backend1.invoke_doc_exists())
        self.assertFalse(self.backend2.invoke_doc_exists())
        self.assertFalse(self.backend3.invoke_doc_exists())
        self.assertFalse(self.backend4.invoke_doc_exists())
        self.assertFalse(self.backend5.invoke_doc_exists())
        self.assertFalse(self.backend6.invoke_doc_exists())
        self.assertFalse(self.backend7.invoke_doc_exists())
        self.assertTrue(self.backend8.invoke_doc_exists())
        self.assertFalse(self.backend9.invoke_doc_exists())
        self.assertFalse(self.backend10.invoke_doc_exists())
        self.backend8.delete_invoke_doc()
        self.assertFalse(self.backend8.invoke_doc_exists())

        # Test sending to verified number with a contact-level backend granted to the domain by another domain

        self.backend8.delete()

        self.assertTrue(
            send_sms_to_verified_number(verified_number, "Test for BACKEND"))
        self.assertFalse(self.backend1.invoke_doc_exists())
        self.assertFalse(self.backend2.invoke_doc_exists())
        self.assertFalse(self.backend3.invoke_doc_exists())
        self.assertFalse(self.backend4.invoke_doc_exists())
        self.assertFalse(self.backend5.invoke_doc_exists())
        self.assertFalse(self.backend6.invoke_doc_exists())
        self.assertFalse(self.backend7.invoke_doc_exists())
        self.assertTrue(self.backend9.invoke_doc_exists())
        self.assertFalse(self.backend10.invoke_doc_exists())
        self.backend9.delete_invoke_doc()
        self.assertFalse(self.backend9.invoke_doc_exists())

        # Test sending to verified number with a contact-level global backend

        self.backend9.delete()

        self.assertTrue(
            send_sms_to_verified_number(verified_number, "Test for BACKEND"))
        self.assertFalse(self.backend1.invoke_doc_exists())
        self.assertFalse(self.backend2.invoke_doc_exists())
        self.assertFalse(self.backend3.invoke_doc_exists())
        self.assertFalse(self.backend4.invoke_doc_exists())
        self.assertFalse(self.backend5.invoke_doc_exists())
        self.assertFalse(self.backend6.invoke_doc_exists())
        self.assertFalse(self.backend7.invoke_doc_exists())
        self.assertTrue(self.backend10.invoke_doc_exists())
        self.backend10.delete_invoke_doc()
        self.assertFalse(self.backend10.invoke_doc_exists())

        # Test raising exception if contact-level backend is not found

        self.backend10.delete()

        try:
            self.assertTrue(
                send_sms_to_verified_number(verified_number,
                                            "Test for BACKEND"))
        except BadSMSConfigException:
            pass
        else:
            self.assertTrue(False)

        # Test send_sms_with_backend

        self.assertTrue(
            send_sms_with_backend(self.domain, "+15551234567",
                                  "Test for BACKEND3", self.backend3._id))
        self.assertFalse(self.backend1.invoke_doc_exists())
        self.assertFalse(self.backend2.invoke_doc_exists())
        self.assertTrue(self.backend3.invoke_doc_exists())
        self.assertFalse(self.backend4.invoke_doc_exists())
        self.assertFalse(self.backend5.invoke_doc_exists())
        self.assertFalse(self.backend6.invoke_doc_exists())
        self.assertFalse(self.backend7.invoke_doc_exists())
        self.backend3.delete_invoke_doc()
        self.assertFalse(self.backend3.invoke_doc_exists())

        # Test send_sms_with_backend_name

        self.assertTrue(
            send_sms_with_backend_name(self.domain, "+15551234567",
                                       "Test for BACKEND3", "BACKEND3"))
        self.assertFalse(self.backend1.invoke_doc_exists())
        self.assertFalse(self.backend2.invoke_doc_exists())
        self.assertTrue(self.backend3.invoke_doc_exists())
        self.assertFalse(self.backend4.invoke_doc_exists())
        self.assertFalse(self.backend5.invoke_doc_exists())
        self.assertFalse(self.backend6.invoke_doc_exists())
        self.assertFalse(self.backend7.invoke_doc_exists())
        self.backend3.delete_invoke_doc()
        self.assertFalse(self.backend3.invoke_doc_exists())
Example #45
0
class BackendTestCase(BaseAccountingTest):
    def get_or_create_site(self):
        site, created = Site.objects.get_or_create(id=settings.SITE_ID)
        if created:
            site.domain = 'localhost'
            site.name = 'localhost'
            site.save()
        return (site, created)

    def setUp(self):
        super(BackendTestCase, self).setUp()

        self.domain = "test-domain"
        self.domain2 = "test-domain2"

        self.site, self.site_created = self.get_or_create_site()

        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.domain_obj = Domain.get(
            self.domain_obj._id)  # Prevent resource conflict

        self.backend1 = TestCaseBackend(name="BACKEND1", is_global=True)
        self.backend1.save()

        self.backend2 = TestCaseBackend(name="BACKEND2", is_global=True)
        self.backend2.save()

        self.backend3 = TestCaseBackend(name="BACKEND3", is_global=True)
        self.backend3.save()

        self.backend4 = TestCaseBackend(name="BACKEND4", is_global=True)
        self.backend4.save()

        self.backend5 = TestCaseBackend(name="BACKEND5",
                                        domain=self.domain,
                                        is_global=False,
                                        authorized_domains=[])
        self.backend5.save()

        self.backend6 = TestCaseBackend(name="BACKEND6",
                                        domain=self.domain2,
                                        is_global=False,
                                        authorized_domains=[self.domain])
        self.backend6.save()

        self.backend7 = TestCaseBackend(name="BACKEND7",
                                        domain=self.domain2,
                                        is_global=False,
                                        authorized_domains=[])
        self.backend7.save()

        self.backend8 = TestCaseBackend(name="BACKEND",
                                        domain=self.domain,
                                        is_global=False,
                                        authorized_domains=[])
        self.backend8.save()

        self.backend9 = TestCaseBackend(name="BACKEND",
                                        domain=self.domain2,
                                        is_global=False,
                                        authorized_domains=[self.domain])
        self.backend9.save()

        self.backend10 = TestCaseBackend(name="BACKEND", is_global=True)
        self.backend10.save()

        self.backend_mapping1 = BackendMapping(is_global=True,
                                               prefix="*",
                                               backend_id=self.backend1._id)
        self.backend_mapping1.save()

        self.backend_mapping2 = BackendMapping(is_global=True,
                                               prefix="1",
                                               backend_id=self.backend2._id)
        self.backend_mapping2.save()

        self.backend_mapping3 = BackendMapping(is_global=True,
                                               prefix="91",
                                               backend_id=self.backend3._id)
        self.backend_mapping3.save()

        self.backend_mapping4 = BackendMapping(is_global=True,
                                               prefix="265",
                                               backend_id=self.backend4._id)
        self.backend_mapping4.save()

        self.backend_mapping5 = BackendMapping(is_global=True,
                                               prefix="256",
                                               backend_id=self.backend5._id)
        self.backend_mapping5.save()

        self.backend_mapping6 = BackendMapping(is_global=True,
                                               prefix="25670",
                                               backend_id=self.backend6._id)
        self.backend_mapping6.save()

        self.backend_mapping7 = BackendMapping(is_global=True,
                                               prefix="25675",
                                               backend_id=self.backend7._id)
        self.backend_mapping7.save()

        self.case = CommCareCase(domain=self.domain)
        self.case.set_case_property("contact_phone_number", "15551234567")
        self.case.set_case_property("contact_phone_number_is_verified", "1")
        self.case.save()

        self.contact = CommConnectCase.wrap(self.case.to_json())

        settings.SMS_LOADED_BACKENDS.append(
            "corehq.apps.sms.tests.TestCaseBackend")

    def tearDown(self):
        self.backend1.delete_invoke_doc()
        self.backend1.delete()
        self.backend_mapping1.delete()

        self.backend2.delete_invoke_doc()
        self.backend2.delete()
        self.backend_mapping2.delete()

        self.backend3.delete_invoke_doc()
        self.backend3.delete()
        self.backend_mapping3.delete()

        self.backend4.delete_invoke_doc()
        self.backend4.delete()
        self.backend_mapping4.delete()

        self.backend5.delete_invoke_doc()
        self.backend5.delete()
        self.backend_mapping5.delete()

        self.backend6.delete_invoke_doc()
        self.backend6.delete()
        self.backend_mapping6.delete()

        self.backend7.delete_invoke_doc()
        self.backend7.delete()
        self.backend_mapping7.delete()

        self.contact.delete_verified_number()
        self.case.delete()

        SubscriptionAdjustment.objects.all().delete()
        self.subscription.delete()
        self.account.delete()

        self.domain_obj.delete()

        if self.site_created:
            self.site.delete()

        settings.SMS_LOADED_BACKENDS.pop()

    def test_multiple_country_prefixes(self):
        self.assertEqual(
            MobileBackend.auto_load('256800000000')._id, self.backend5._id)
        self.assertEqual(
            MobileBackend.auto_load('256700000000')._id, self.backend6._id)
        self.assertEqual(
            MobileBackend.auto_load('256750000000')._id, self.backend7._id)

    def test_backend(self):
        # Test the backend map

        self.assertTrue(
            send_sms(self.domain, None, "15551234567", "Test for BACKEND2"))
        self.assertFalse(self.backend1.invoke_doc_exists())
        self.assertTrue(self.backend2.invoke_doc_exists())
        self.assertFalse(self.backend3.invoke_doc_exists())
        self.assertFalse(self.backend4.invoke_doc_exists())
        self.assertFalse(self.backend5.invoke_doc_exists())
        self.assertFalse(self.backend6.invoke_doc_exists())
        self.assertFalse(self.backend7.invoke_doc_exists())
        self.assertFalse(self.backend8.invoke_doc_exists())
        self.assertFalse(self.backend9.invoke_doc_exists())
        self.assertFalse(self.backend10.invoke_doc_exists())
        self.backend2.delete_invoke_doc()
        self.assertFalse(self.backend2.invoke_doc_exists())

        self.assertTrue(
            send_sms(self.domain, None, "9100000000", "Test for BACKEND3"))
        self.assertFalse(self.backend1.invoke_doc_exists())
        self.assertFalse(self.backend2.invoke_doc_exists())
        self.assertTrue(self.backend3.invoke_doc_exists())
        self.assertFalse(self.backend4.invoke_doc_exists())
        self.assertFalse(self.backend5.invoke_doc_exists())
        self.assertFalse(self.backend6.invoke_doc_exists())
        self.assertFalse(self.backend7.invoke_doc_exists())
        self.assertFalse(self.backend8.invoke_doc_exists())
        self.assertFalse(self.backend9.invoke_doc_exists())
        self.assertFalse(self.backend10.invoke_doc_exists())
        self.backend3.delete_invoke_doc()
        self.assertFalse(self.backend3.invoke_doc_exists())

        self.assertTrue(
            send_sms(self.domain, None, "26500000000", "Test for BACKEND4"))
        self.assertFalse(self.backend1.invoke_doc_exists())
        self.assertFalse(self.backend2.invoke_doc_exists())
        self.assertFalse(self.backend3.invoke_doc_exists())
        self.assertTrue(self.backend4.invoke_doc_exists())
        self.assertFalse(self.backend5.invoke_doc_exists())
        self.assertFalse(self.backend6.invoke_doc_exists())
        self.assertFalse(self.backend7.invoke_doc_exists())
        self.assertFalse(self.backend8.invoke_doc_exists())
        self.assertFalse(self.backend9.invoke_doc_exists())
        self.assertFalse(self.backend10.invoke_doc_exists())
        self.backend4.delete_invoke_doc()
        self.assertFalse(self.backend4.invoke_doc_exists())

        self.assertTrue(
            send_sms(self.domain, None, "25800000000", "Test for BACKEND1"))
        self.assertTrue(self.backend1.invoke_doc_exists())
        self.assertFalse(self.backend2.invoke_doc_exists())
        self.assertFalse(self.backend3.invoke_doc_exists())
        self.assertFalse(self.backend4.invoke_doc_exists())
        self.assertFalse(self.backend5.invoke_doc_exists())
        self.assertFalse(self.backend6.invoke_doc_exists())
        self.assertFalse(self.backend7.invoke_doc_exists())
        self.assertFalse(self.backend8.invoke_doc_exists())
        self.assertFalse(self.backend9.invoke_doc_exists())
        self.assertFalse(self.backend10.invoke_doc_exists())
        self.backend1.delete_invoke_doc()
        self.assertFalse(self.backend1.invoke_doc_exists())

        # Test overriding with a domain-level backend

        self.domain_obj = Domain.get(
            self.domain_obj._id)  # Prevent resource conflict
        self.domain_obj.default_sms_backend_id = self.backend5._id
        self.domain_obj.save()

        self.assertTrue(
            send_sms(self.domain, None, "15551234567", "Test for BACKEND5"))
        self.assertFalse(self.backend1.invoke_doc_exists())
        self.assertFalse(self.backend2.invoke_doc_exists())
        self.assertFalse(self.backend3.invoke_doc_exists())
        self.assertFalse(self.backend4.invoke_doc_exists())
        self.assertTrue(self.backend5.invoke_doc_exists())
        self.assertFalse(self.backend6.invoke_doc_exists())
        self.assertFalse(self.backend7.invoke_doc_exists())
        self.assertFalse(self.backend8.invoke_doc_exists())
        self.assertFalse(self.backend9.invoke_doc_exists())
        self.assertFalse(self.backend10.invoke_doc_exists())
        self.backend5.delete_invoke_doc()
        self.assertFalse(self.backend5.invoke_doc_exists())

        # Test use of backend that another domain owns but has granted access

        self.domain_obj.default_sms_backend_id = self.backend6._id
        self.domain_obj.save()

        self.assertTrue(
            send_sms(self.domain, None, "25800000000", "Test for BACKEND6"))
        self.assertFalse(self.backend1.invoke_doc_exists())
        self.assertFalse(self.backend2.invoke_doc_exists())
        self.assertFalse(self.backend3.invoke_doc_exists())
        self.assertFalse(self.backend4.invoke_doc_exists())
        self.assertFalse(self.backend5.invoke_doc_exists())
        self.assertTrue(self.backend6.invoke_doc_exists())
        self.assertFalse(self.backend7.invoke_doc_exists())
        self.assertFalse(self.backend8.invoke_doc_exists())
        self.assertFalse(self.backend9.invoke_doc_exists())
        self.assertFalse(self.backend10.invoke_doc_exists())
        self.backend6.delete_invoke_doc()
        self.assertFalse(self.backend6.invoke_doc_exists())

        # Test backend access control

        self.domain_obj.default_sms_backend_id = self.backend7._id
        self.domain_obj.save()

        self.assertFalse(
            send_sms(self.domain, None, "25800000000", "Test for BACKEND7"))
        self.assertFalse(self.backend1.invoke_doc_exists())
        self.assertFalse(self.backend2.invoke_doc_exists())
        self.assertFalse(self.backend3.invoke_doc_exists())
        self.assertFalse(self.backend4.invoke_doc_exists())
        self.assertFalse(self.backend5.invoke_doc_exists())
        self.assertFalse(self.backend6.invoke_doc_exists())
        self.assertFalse(self.backend7.invoke_doc_exists())
        self.assertFalse(self.backend8.invoke_doc_exists())
        self.assertFalse(self.backend9.invoke_doc_exists())
        self.assertFalse(self.backend10.invoke_doc_exists())

        # Test sending to verified number with backend map

        self.domain_obj.default_sms_backend_id = None
        self.domain_obj.save()

        verified_number = self.contact.get_verified_number()
        self.assertTrue(verified_number is not None)
        self.assertTrue(verified_number.backend_id is None)
        self.assertEqual(verified_number.phone_number, "15551234567")

        self.assertTrue(
            send_sms_to_verified_number(verified_number, "Test for BACKEND2"))
        self.assertFalse(self.backend1.invoke_doc_exists())
        self.assertTrue(self.backend2.invoke_doc_exists())
        self.assertFalse(self.backend3.invoke_doc_exists())
        self.assertFalse(self.backend4.invoke_doc_exists())
        self.assertFalse(self.backend5.invoke_doc_exists())
        self.assertFalse(self.backend6.invoke_doc_exists())
        self.assertFalse(self.backend7.invoke_doc_exists())
        self.assertFalse(self.backend8.invoke_doc_exists())
        self.assertFalse(self.backend9.invoke_doc_exists())
        self.assertFalse(self.backend10.invoke_doc_exists())
        self.backend2.delete_invoke_doc()
        self.assertFalse(self.backend2.invoke_doc_exists())

        # Test sending to verified number with default domain backend

        self.domain_obj.default_sms_backend_id = self.backend5._id
        self.domain_obj.save()

        self.assertTrue(
            send_sms_to_verified_number(verified_number, "Test for BACKEND5"))
        self.assertFalse(self.backend1.invoke_doc_exists())
        self.assertFalse(self.backend2.invoke_doc_exists())
        self.assertFalse(self.backend3.invoke_doc_exists())
        self.assertFalse(self.backend4.invoke_doc_exists())
        self.assertTrue(self.backend5.invoke_doc_exists())
        self.assertFalse(self.backend6.invoke_doc_exists())
        self.assertFalse(self.backend7.invoke_doc_exists())
        self.assertFalse(self.backend8.invoke_doc_exists())
        self.assertFalse(self.backend9.invoke_doc_exists())
        self.assertFalse(self.backend10.invoke_doc_exists())
        self.backend5.delete_invoke_doc()
        self.assertFalse(self.backend5.invoke_doc_exists())

        # Test sending to verified number with a contact-level backend owned by the domain

        self.case.set_case_property("contact_backend_id", "BACKEND")
        self.case.save()
        self.contact = CommConnectCase.wrap(self.case.to_json())
        verified_number = self.contact.get_verified_number()
        self.assertTrue(verified_number is not None)
        self.assertEqual(verified_number.backend_id, "BACKEND")
        self.assertEqual(verified_number.phone_number, "15551234567")

        self.assertTrue(
            send_sms_to_verified_number(verified_number, "Test for BACKEND"))
        self.assertFalse(self.backend1.invoke_doc_exists())
        self.assertFalse(self.backend2.invoke_doc_exists())
        self.assertFalse(self.backend3.invoke_doc_exists())
        self.assertFalse(self.backend4.invoke_doc_exists())
        self.assertFalse(self.backend5.invoke_doc_exists())
        self.assertFalse(self.backend6.invoke_doc_exists())
        self.assertFalse(self.backend7.invoke_doc_exists())
        self.assertTrue(self.backend8.invoke_doc_exists())
        self.assertFalse(self.backend9.invoke_doc_exists())
        self.assertFalse(self.backend10.invoke_doc_exists())
        self.backend8.delete_invoke_doc()
        self.assertFalse(self.backend8.invoke_doc_exists())

        # Test sending to verified number with a contact-level backend granted to the domain by another domain

        self.backend8.delete()

        self.assertTrue(
            send_sms_to_verified_number(verified_number, "Test for BACKEND"))
        self.assertFalse(self.backend1.invoke_doc_exists())
        self.assertFalse(self.backend2.invoke_doc_exists())
        self.assertFalse(self.backend3.invoke_doc_exists())
        self.assertFalse(self.backend4.invoke_doc_exists())
        self.assertFalse(self.backend5.invoke_doc_exists())
        self.assertFalse(self.backend6.invoke_doc_exists())
        self.assertFalse(self.backend7.invoke_doc_exists())
        self.assertTrue(self.backend9.invoke_doc_exists())
        self.assertFalse(self.backend10.invoke_doc_exists())
        self.backend9.delete_invoke_doc()
        self.assertFalse(self.backend9.invoke_doc_exists())

        # Test sending to verified number with a contact-level global backend

        self.backend9.delete()

        self.assertTrue(
            send_sms_to_verified_number(verified_number, "Test for BACKEND"))
        self.assertFalse(self.backend1.invoke_doc_exists())
        self.assertFalse(self.backend2.invoke_doc_exists())
        self.assertFalse(self.backend3.invoke_doc_exists())
        self.assertFalse(self.backend4.invoke_doc_exists())
        self.assertFalse(self.backend5.invoke_doc_exists())
        self.assertFalse(self.backend6.invoke_doc_exists())
        self.assertFalse(self.backend7.invoke_doc_exists())
        self.assertTrue(self.backend10.invoke_doc_exists())
        self.backend10.delete_invoke_doc()
        self.assertFalse(self.backend10.invoke_doc_exists())

        # Test raising exception if contact-level backend is not found

        self.backend10.delete()

        try:
            self.assertTrue(
                send_sms_to_verified_number(verified_number,
                                            "Test for BACKEND"))
        except BadSMSConfigException:
            pass
        else:
            self.assertTrue(False)

        # Test send_sms_with_backend

        self.assertTrue(
            send_sms_with_backend(self.domain, "+15551234567",
                                  "Test for BACKEND3", self.backend3._id))
        self.assertFalse(self.backend1.invoke_doc_exists())
        self.assertFalse(self.backend2.invoke_doc_exists())
        self.assertTrue(self.backend3.invoke_doc_exists())
        self.assertFalse(self.backend4.invoke_doc_exists())
        self.assertFalse(self.backend5.invoke_doc_exists())
        self.assertFalse(self.backend6.invoke_doc_exists())
        self.assertFalse(self.backend7.invoke_doc_exists())
        self.backend3.delete_invoke_doc()
        self.assertFalse(self.backend3.invoke_doc_exists())

        # Test send_sms_with_backend_name

        self.assertTrue(
            send_sms_with_backend_name(self.domain, "+15551234567",
                                       "Test for BACKEND3", "BACKEND3"))
        self.assertFalse(self.backend1.invoke_doc_exists())
        self.assertFalse(self.backend2.invoke_doc_exists())
        self.assertTrue(self.backend3.invoke_doc_exists())
        self.assertFalse(self.backend4.invoke_doc_exists())
        self.assertFalse(self.backend5.invoke_doc_exists())
        self.assertFalse(self.backend6.invoke_doc_exists())
        self.assertFalse(self.backend7.invoke_doc_exists())
        self.backend3.delete_invoke_doc()
        self.assertFalse(self.backend3.invoke_doc_exists())

    def test_sms_registration(self):
        formatted_username = format_username("tester", self.domain)

        incoming("+9991234567", "JOIN {} WORKER tester".format(self.domain),
                 "TEST_CASE_BACKEND")
        # Test without mobile worker registration enabled
        self.assertIsNone(CommCareUser.get_by_username(formatted_username))

        # Enable mobile worker registration
        setattr(self.domain_obj, "sms_mobile_worker_registration_enabled",
                True)
        self.domain_obj.save()

        incoming("+9991234567", "JOIN {} WORKER tester".format(self.domain),
                 "TEST_CASE_BACKEND")
        self.assertIsNotNone(CommCareUser.get_by_username(formatted_username))

        # Test a duplicate registration
        prev_num_users = num_mobile_users(self.domain)
        incoming("+9991234568", "JOIN {} WORKER tester".format(self.domain),
                 "TEST_CASE_BACKEND")
        current_num_users = num_mobile_users(self.domain)
        self.assertEqual(prev_num_users, current_num_users)
Example #46
0
class dotsOrderingTests(TestCase):
    @override_settings(TIME_ZONE='UTC')
    def setUp(self):

        for doc in get_all_forms_in_all_domains():
            # purge all xforms prior to start
            if doc.xmlns in [XMLNS_DOTS_FORM, XMLNS_PATIENT_UPDATE_DOT]:
                doc.delete()

        two_weeks = timedelta(days=14)
        self.domain = create_domain(PACT_DOMAIN)
        self.domain.date_created = datetime.utcnow() - two_weeks
        self.domain.save()

        self.submit_url = '/a/%s/receiver' % self.domain.name

        self.user = CommCareUser.create(self.domain.name,
                                        'ctsims',
                                        'mockmock',
                                        uuid=CTSIMS_ID)

        nonart_case_regimens = regimen_dict_from_choice(
            DOT_NONART, "morning,bedtime")
        art_case_regimens = regimen_dict_from_choice(DOT_ART,
                                                     "morning,bedtime")
        props = {
            '_id': CASE_ID,
            'dot_status': 'DOT1',
            'domain': self.domain.name
        }
        props.update(nonart_case_regimens)
        props.update(art_case_regimens)

        self.case = CommCareCase(**props)
        self.case.save()

        self.form_a = ""
        with open(
                os.path.join(os.path.abspath(os.path.dirname(__file__)),
                             'dots_data', '05_uncheck_a.xml')) as fin:
            self.form_a = fin.read() % {
                'encounter_date': ANCHOR_DATE_A.strftime('%Y-%m-%d'),
                'anchor_date': ANCHOR_DATE_A.strftime("%d %b %Y")
            }

        self.form_b = ""
        with open(
                os.path.join(os.path.abspath(os.path.dirname(__file__)),
                             'dots_data', '06_uncheck_b.xml')) as fin:
            self.form_b = fin.read() % {
                'encounter_date': ANCHOR_DATE_B.strftime('%Y-%m-%d'),
                'anchor_date': ANCHOR_DATE_B.strftime("%d %b %Y")
            }

    def tearDown(self):
        CommCareCase.get_db().delete_doc(CASE_ID)
        CommCareUser.get_db().delete_doc(CTSIMS_ID)
        self.user = None

    @skip(
        'This test fails at odd hours and the code is not being edited anyways.'
    )
    def testFormA(self):
        """
        Test the dot map function that the no-pillbox checker is faithfully returning DOT data in the calendar thanks to the view
        """
        bundle = {
            "xml": self.form_a,
            "start_date": START_DATE,
            "end_date": ANCHOR_DATE_A,
            "xform_id": FORM_A,
            "anchor_date": ANCHOR_DATE_A,
            'nonart': [["full", "pillbox", "", 0],
                       ["unchecked", "pillbox", "", 3]],
            'art': [["full", "self", "", 0], ["unchecked", "pillbox", "", 3]],
            'submit_idx': -1,
            'check_idx': -2,
        }
        self._submitAndVerifyBundle(bundle)

    @skip(
        'This test fails at odd hours and the code is not being edited anyways.'
    )
    def testFormB(self, verify=True):
        bundle = {
            "xml":
            self.form_b,
            "start_date":
            START_DATE,
            "end_date":
            ANCHOR_DATE_B,
            "xform_id":
            FORM_B,
            "anchor_date":
            ANCHOR_DATE_B,
            'nonart': [["unchecked", "pillbox", "", 0],
                       ["empty", "pillbox", "", 3]],
            'art': [["unchecked", "pillbox", "", 0],
                    ["empty", "pillbox", "", 3]],
            'submit_idx':
            -2,
            'check_idx':
            -2
        }
        self._submitAndVerifyBundle(bundle, verify=verify)

    @skip(
        'This test fails at odd hours and the code is not being edited anyways.'
    )
    def testForA_B(self):

        self.testFormA()
        self.testFormB(verify=False)

        updated_case = PactPatientCase.get(CASE_ID)
        case_dots = updated_case.dots
        days = json.loads(case_dots)['days']

        nonart = [["full", "pillbox", "", 0], ["empty", "pillbox", "", 3]]
        art = [["full", "self", "", 0], ["empty", "pillbox", "", 3]]

        examine_day = days[-2]

        self._verify_dot_cells(nonart, art, examine_day)

    def _submitAndVerifyBundle(self, bundle, verify=True):
        start_nums = len(self.case.xform_ids)
        submit_xform(self.submit_url, self.domain.name, bundle['xml'])
        time.sleep(1)
        submitted = XFormInstance.get(bundle['xform_id'])
        self.assertTrue(hasattr(submitted, PACT_DOTS_DATA_PROPERTY))

        submitted_dots = getattr(submitted, PACT_DOTS_DATA_PROPERTY)
        updated_case = PactPatientCase.get(CASE_ID)
        case_dots = get_dots_case_json(updated_case)
        days = case_dots['days']

        if verify:
            nonart_submissions = bundle['nonart']
            art_submissions = bundle['art']
            examine_day = days[bundle['check_idx']]

            self._verify_dot_cells(nonart_submissions, art_submissions,
                                   examine_day)

    def _verify_dot_cells(self, nonart_submissions, art_submissions,
                          examine_day):
        for day_dose_idx, time_string in enumerate(['morning', 'evening']):
            self.assertEqual(examine_day[DOT_NONART_IDX][day_dose_idx][0:2],
                             nonart_submissions[day_dose_idx][0:2])
            self.assertEqual(examine_day[DOT_ART_IDX][day_dose_idx][0:2],
                             art_submissions[day_dose_idx][0:2])
Example #47
0
class TestGetInfoResourcesListResources(TestCase, DomainSubscriptionMixin):
    """
    Demonstrates building multiple resources using subcases.
    """
    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.domain_obj = create_domain(DOMAIN)
        cls.setup_subscription(DOMAIN, SoftwarePlanEdition.PRO)

        cls.person_case_type = CaseType.objects.create(domain=DOMAIN,
                                                       name='person')
        name = CaseProperty.objects.create(case_type=cls.person_case_type,
                                           name='name')

        resource_type_for_person = FHIRResourceType.objects.create(
            domain=DOMAIN, case_type=cls.person_case_type, name='Patient')
        FHIRResourceProperty.objects.create(
            resource_type=resource_type_for_person,
            case_property=name,
            jsonpath='$.name[0].text',
        )

        cls.vitals_case_type = CaseType.objects.create(domain=DOMAIN,
                                                       name='vitals')
        CaseProperty.objects.create(case_type=cls.vitals_case_type,
                                    name='temperature')

        resource_type_for_vitals = FHIRResourceType.objects.create(
            domain=DOMAIN,
            case_type=cls.vitals_case_type,
            name='Observation',
            template={
                'code': {
                    'coding': [{
                        'system': 'http://loinc.org',
                        'code': '8310-5',
                        'display': 'Body temperature',
                    }],
                    'text':
                    'Temperature',
                },
                'valueQuantity': {
                    'unit': 'degrees Celsius',
                },
            })
        FHIRResourceProperty.objects.create(
            resource_type=resource_type_for_vitals,
            value_source_config={
                'case_property': 'temperature',
                'jsonpath': '$.valueQuantity.value',
                'external_data_type': COMMCARE_DATA_TYPE_DECIMAL,
            })
        FHIRResourceProperty.objects.create(
            resource_type=resource_type_for_vitals,
            value_source_config={
                'supercase_value_source': {
                    'case_property': 'name',
                    'jsonpath': '$.subject.display',
                }
            })
        FHIRResourceProperty.objects.create(
            resource_type=resource_type_for_vitals,
            value_source_config={
                'supercase_value_source': {
                    'case_property': 'case_id',
                    'jsonpath': '$.subject.reference',
                }
            })

    @classmethod
    def tearDownClass(cls):
        cls.person_case_type.delete()
        cls.vitals_case_type.delete()
        cls.teardown_subscriptions()
        cls.domain_obj.delete()
        clear_plan_version_cache()
        super().tearDownClass()

    def setUp(self):
        now = datetime.utcnow()
        owner_id = str(uuid4())
        self.parent_case_id = str(uuid4())
        self.parent_case = CommCareCase(
            _id=self.parent_case_id,
            domain=DOMAIN,
            type='person',
            name='Beth',
            owner_id=owner_id,
            modified_on=now,
            server_modified_on=now,
        )
        self.parent_case.save()

        self.child_case_id = str(uuid4())
        self.child_case = CommCareCase(
            _id=self.child_case_id,
            domain=DOMAIN,
            type='vitals',
            temperature=36.1,
            indices=[
                CommCareCaseIndex(
                    identifier='parent',
                    referenced_type='person',
                    referenced_id=self.parent_case_id,
                )
            ],
            owner_id=owner_id,
            modified_on=now,
            server_modified_on=now,
        )
        self.child_case.save()

    def tearDown(self):
        self.child_case.delete()
        self.parent_case.delete()

    def test_get_info_resource_list(self):
        resource_type_for_person = get_resource_type_or_none(
            self.parent_case,
            FHIR_VERSION_4_0_1,
        )
        resource_type_for_vitals = get_resource_type_or_none(
            self.child_case,
            FHIR_VERSION_4_0_1,
        )
        case_trigger_infos = [
            get_case_trigger_info(self.parent_case, resource_type_for_person),
            get_case_trigger_info(self.child_case, resource_type_for_vitals),
        ]
        resource_types_by_case_type = {
            'person': resource_type_for_person,
            'vitals': resource_type_for_vitals,
        }
        info_resource_list = get_info_resource_list(
            case_trigger_infos,
            resource_types_by_case_type,
        )
        resources = [resource for info, resource in info_resource_list]
        self.assertEqual(resources, [{
            'id': self.parent_case_id,
            'name': [{
                'text': 'Beth'
            }],
            'resourceType': 'Patient',
        }, {
            'id': self.child_case_id,
            'code': {
                'coding': [{
                    'system': 'http://loinc.org',
                    'code': '8310-5',
                    'display': 'Body temperature',
                }],
                'text':
                'Temperature',
            },
            'valueQuantity': {
                'value': 36.1,
                'unit': 'degrees Celsius',
            },
            'subject': {
                'reference': self.parent_case_id,
                'display': 'Beth',
            },
            'resourceType': 'Observation',
        }])