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()
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
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()
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))
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
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()
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))
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()
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()
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
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))
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))
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)
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)
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']))
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)
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)
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)))
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()
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)
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)
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']))
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()
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)
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
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)))
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']))
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)
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()
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']))
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
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']))
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' })
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()
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', })
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())
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)
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])
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', }])