def test_create_from_structure(self): owner_id = uuid.uuid4().hex factory = CaseFactory(case_defaults={ 'owner_id': owner_id, 'create': True, 'update': {'custom_prop': 'custom_value'} }) case_id = uuid.uuid4().hex child_case_id = uuid.uuid4().hex parent_case_id = uuid.uuid4().hex structures = [ CaseStructure(case_id=case_id), CaseStructure( case_id=child_case_id, relationships=[ CaseRelationship(CaseStructure(case_id=parent_case_id)) ] ) ] cases = factory.create_or_update_cases(structures) for case in cases: self.assertEqual(owner_id, case.owner_id) self.assertEqual('custom_value', case.custom_prop) [regular, child, parent] = cases self.assertEqual(1, len(child.indices)) self.assertEqual(parent_case_id, child.indices[0].referenced_id) self.assertEqual(2, len(regular.actions)) # create + update self.assertEqual(2, len(parent.actions)) # create + update self.assertEqual(3, len(child.actions)) # create + update + index
def test_create_from_structure(self): owner_id = uuid.uuid4().hex factory = CaseFactory(case_defaults={ 'owner_id': owner_id, 'create': True, 'update': {'custom_prop': 'custom_value'} }) case_id = uuid.uuid4().hex child_case_id = uuid.uuid4().hex parent_case_id = uuid.uuid4().hex structures = [ CaseStructure(case_id=case_id, attrs={'create': True}), CaseStructure( case_id=child_case_id, indices=[ CaseIndex(CaseStructure(case_id=parent_case_id, attrs={'create': True})) ] ) ] cases = factory.create_or_update_cases(structures) for case in cases: self.assertEqual(owner_id, case.owner_id) self.assertEqual('custom_value', case.dynamic_case_properties()['custom_prop']) [regular, child, parent] = cases self.assertEqual(1, len(child.indices)) self.assertEqual(parent_case_id, child.indices[0].referenced_id) if not getattr(settings, 'TESTS_SHOULD_USE_SQL_BACKEND', False): self.assertEqual(2, len(regular.actions)) # create + update self.assertEqual(2, len(parent.actions)) # create + update self.assertEqual(3, len(child.actions)) # create + update + index
def test_simple_delete(self): factory = CaseFactory() case = factory.create_case() [case] = factory.create_or_update_case( CaseStructure(case_id=case.case_id, attrs={'update': {'foo': 'bar'}}) ) self.assertIsNotNone(self.casedb.get_case(case.case_id)) self.assertEqual(2, len(case.xform_ids)) for form_id in case.xform_ids: self.assertIsNotNone(self.formdb.get_form(form_id)) with capture_kafka_changes_context(topics.FORM_SQL, topics.CASE_SQL) as change_context: safe_hard_delete(case) if should_use_sql_backend(case.domain): self.assertEqual(3, len(change_context.changes)) expected_ids = {case.case_id} | set(case.xform_ids) self.assertEqual(expected_ids, {change.id for change in change_context.changes}) for change in change_context.changes: self.assertTrue(change.deleted) with self.assertRaises(CaseNotFound): self.casedb.get_case(case.case_id) for form_id in case.xform_ids: with self.assertRaises(XFormNotFound): self.formdb.get_form(form_id)
def test_deleted_indices_removed(self): factory = CaseFactory( self.domain, case_defaults={ 'user_id': self.commcare_user._id, 'owner_id': self.commcare_user._id, 'case_type': 'a-case', 'create': True, }, ) # create a parent/child set of cases parent_id, child_id = [uuid.uuid4().hex for i in range(2)] child, parent = factory.create_or_update_case(CaseStructure( case_id=child_id, indices=[ CaseIndex(CaseStructure(case_id=parent_id)) ] )) # confirm the child has an index, and 1 form self.assertEqual(1, len(child.indices)) self.assertEqual(parent_id, child.indices[0].referenced_id) self.assertEqual(1, len(child.xform_ids)) # simulate parent deletion parent.soft_delete() # call the remove index task remove_indices_from_deleted_cases(self.domain, [parent_id]) # check that the index is removed via a new form child = CaseAccessors(self.domain).get_case(child_id) self.assertEqual(0, len(child.indices)) self.assertEqual(2, len(child.xform_ids))
class TestIndexedCaseIds(TestCase): def setUp(self): super(TestIndexedCaseIds, self).setUp() self.domain = 'domain' self.factory = CaseFactory(self.domain) def tearDown(self): FormProcessorTestUtils.delete_all_cases() FormProcessorTestUtils.delete_all_xforms() super(TestIndexedCaseIds, self).tearDown() def test_indexed_case_ids_returns_extensions(self): """ When getting indices, also return extensions """ host_id = uuid.uuid4().hex extension_id = uuid.uuid4().hex host = CaseStructure(case_id=host_id, attrs={'create': True}) self.factory.create_or_update_case( CaseStructure( case_id=extension_id, indices=[ CaseIndex(host, relationship=CASE_INDEX_EXTENSION) ], attrs={'create': True} ) ) returned_cases = CaseAccessors(self.domain).get_indexed_case_ids([extension_id]) self.assertItemsEqual(returned_cases, [host_id])
def test_extension_index(self): factory = CaseFactory() standard_case_id = uuid.uuid4().hex [case] = factory.create_or_update_case( CaseStructure(case_id=standard_case_id, attrs={'case_type': "standard_type", 'create': True}) ) extension_case_id = uuid.uuid4().hex factory.create_or_update_case( CaseStructure( case_id=extension_case_id, attrs={'case_type': "extension_type", 'create': True}, indices=[ CaseIndex( CaseStructure(case_id=standard_case_id), related_type='standard_type', relationship=CASE_INDEX_EXTENSION ) ], walk_related=False ) ) hierarchy = get_case_hierarchy(case, {}) self.assertEqual(2, len(hierarchy['case_list'])) self.assertEqual(1, len(hierarchy['child_cases']))
def setUp(self): super(GetChildCasesExpressionTest, self).setUp() self.domain = uuid.uuid4().hex factory = CaseFactory(domain=self.domain) self.test_case_id = uuid.uuid4().hex parent_case = CaseStructure( case_id='p-' + self.test_case_id, attrs={ 'case_type': 'parent_case', 'create': True, 'date_opened': datetime(2015, 1, 10), 'date_modified': datetime(2015, 3, 10), }, ) test_case = CaseStructure( case_id=self.test_case_id, attrs={ 'case_type': 'test', 'create': True, 'date_opened': datetime(2015, 1, 10), 'date_modified': datetime(2015, 3, 10), }, indices=[CaseIndex( parent_case, identifier='parent', relationship=CASE_INDEX_CHILD, related_type=parent_case.attrs['case_type'], )], ) child_case_1 = CaseStructure( case_id='c1-' + self.test_case_id, attrs={ 'case_type': 'child_1', 'create': True, 'date_opened': datetime(2015, 1, 10), 'date_modified': datetime(2015, 3, 10), }, indices=[CaseIndex( test_case, identifier='parent', relationship=CASE_INDEX_CHILD, related_type=test_case.attrs['case_type'], )], ) child_case_2 = CaseStructure( case_id='c2-' + self.test_case_id, attrs={ 'case_type': 'child_2', 'create': True, 'date_opened': datetime(2015, 1, 10), 'date_modified': datetime(2015, 3, 10), }, indices=[CaseIndex( test_case, identifier='parent', relationship=CASE_INDEX_CHILD, related_type=test_case.attrs['case_type'], )], ) factory.create_or_update_cases([parent_case, test_case, child_case_1, child_case_2])
def test_ledger_pillow(self): factory = CaseFactory(domain=self.domain) case = factory.create_case() consumer = get_test_kafka_consumer(topics.LEDGER) # have to get the seq id before the change is processed kafka_seq = get_topic_offset(topics.LEDGER) from corehq.apps.commtrack.tests.util import get_single_balance_block from corehq.apps.hqcase.utils import submit_case_blocks submit_case_blocks([ get_single_balance_block(case.case_id, self.product_id, 100)], self.domain ) ref = UniqueLedgerReference(case.case_id, 'stock', self.product_id) # confirm change made it to kafka message = consumer.next() change_meta = change_meta_from_kafka_message(message.value) if should_use_sql_backend(self.domain): self.assertEqual(ref.as_id(), change_meta.document_id) else: from corehq.apps.commtrack.models import StockState state = StockState.objects.all() self.assertEqual(1, len(state)) self.assertEqual(state[0].pk, change_meta.document_id) # self.assertEqual(self.domain, change_meta.domain) # send to elasticsearch self.pillow.process_changes(since=kafka_seq, forever=False) self.elasticsearch.indices.refresh(LEDGER_INDEX_INFO.index) # confirm change made it to elasticserach self._assert_ledger_in_es(ref)
def test_form_extras_override_defaults(self): domain = uuid.uuid4().hex token_id = uuid.uuid4().hex factory = CaseFactory(domain=domain, form_extras={'last_sync_token': token_id}) [case] = factory.create_or_update_case(CaseStructure(attrs={'create': True}), form_extras={'last_sync_token': 'differenttoken'}) form = FormAccessors(domain).get_form(case.xform_ids[0]) self.assertEqual('differenttoken', form.last_sync_token)
class TestIndexedCaseIds(TestCase): @classmethod def setUpClass(cls): delete_all_cases() def setUp(self): self.domain = 'domain' self.factory = CaseFactory(self.domain) def test_indexed_case_ids_returns_extensions(self): """ When getting indices, also return extensions """ host_id = uuid.uuid4().hex extension_id = uuid.uuid4().hex host = CaseStructure(case_id=host_id) self.factory.create_or_update_case( CaseStructure( case_id=extension_id, indices=[ CaseIndex(host, relationship=CASE_INDEX_EXTENSION) ] ) ) returned_cases = get_indexed_case_ids(self.domain, [extension_id]) self.assertItemsEqual(returned_cases, [host_id])
def post(self, request, *args, **kwargs): domain = request.GET.get('domain') case_type = request.GET.get('case_type') user_name = request.GET.get('user') properties = json.loads(request.body) case_id = properties['case_id'] properties.pop('case_id') couch_user = CommCareUser.get_by_username(user_name) if not couch_user.is_member_of(domain): return HttpResponseForbidden("This user does not have access to this domain.") case = get_case_or_404(domain, case_id) if not case.type == case_type: return HttpResponseBadRequest("Case type mismatch") factory = CaseFactory(domain=domain) factory.update_case( case_id=case_id, update=properties ) return HttpResponse("Case {case_id} updated".format(case_id=case_id))
def test_form_extras_override_defaults(self): domain = uuid.uuid4().hex LOOSE_SYNC_TOKEN_VALIDATION.set(domain, True, namespace="domain") token_id = uuid.uuid4().hex factory = CaseFactory(domain=domain, form_extras={"last_sync_token": token_id}) [case] = factory.create_or_update_case(CaseStructure(), form_extras={"last_sync_token": "differenttoken"}) form = FormAccessors(domain).get_form(case.xform_ids[0]) self.assertEqual("differenttoken", form.last_sync_token)
def setUpClass(cls): super(TestDemoUser, cls).setUpClass() delete_all_users() cls.domain = 'main-domain' cls.project = create_domain(cls.domain) cls.user = CommCareUser.create(cls.domain, '*****@*****.**', 'secret') factory = CaseFactory() factory.create_case(owner_id=cls.user._id, update={'custom_prop': 'custom_value'})
def test_form_extras(self): domain = uuid.uuid4().hex LOOSE_SYNC_TOKEN_VALIDATION.set(domain, True, namespace='domain') token_id = uuid.uuid4().hex factory = CaseFactory(domain=domain) [case] = factory.create_or_update_case(CaseStructure(), form_extras={'last_sync_token': token_id}) form = FormProcessorInterface(domain).xform_model.get(case.xform_ids[0]) self.assertEqual(token_id, form.last_sync_token)
def test_form_extras_override_defaults(self): domain = uuid.uuid4().hex LOOSE_SYNC_TOKEN_VALIDATION.set(domain, True, namespace='domain') token_id = uuid.uuid4().hex factory = CaseFactory(domain=domain, form_extras={'last_sync_token': token_id}) [case] = factory.create_or_update_case(CaseStructure(), form_extras={'last_sync_token': 'differenttoken'}) form = XFormInstance.get(case.xform_ids[0]) self.assertEqual('differenttoken', form.last_sync_token)
def setUpClass(cls): super(TestFilterDslLookups, cls).setUpClass() with trap_extra_setup(ConnectionError): cls.es = get_es_new() initialize_index_and_mapping(cls.es, CASE_SEARCH_INDEX_INFO) cls.child_case_id = 'margaery' cls.parent_case_id = 'mace' cls.grandparent_case_id = 'olenna' cls.domain = "Tyrell" factory = CaseFactory(domain=cls.domain) grandparent_case = CaseStructure( case_id=cls.grandparent_case_id, attrs={ 'create': True, 'case_type': 'grandparent', 'update': { "name": "Olenna", "alias": "Queen of thorns", "house": "Tyrell", }, }) parent_case = CaseStructure( case_id=cls.parent_case_id, attrs={ 'create': True, 'case_type': 'parent', 'update': { "name": "Mace", "house": "Tyrell", }, }, indices=[CaseIndex( grandparent_case, identifier='mother', relationship='child', )]) child_case = CaseStructure( case_id=cls.child_case_id, attrs={ 'create': True, 'case_type': 'child', 'update': { "name": "Margaery", "house": "Tyrell", }, }, indices=[CaseIndex( parent_case, identifier='father', relationship='extension', )], ) for case in factory.create_or_update_cases([child_case]): send_to_elasticsearch('case_search', transform_case_for_elasticsearch(case.to_json())) cls.es.indices.refresh(CASE_SEARCH_INDEX_INFO.index)
def handle(self, domain, **options): base_query = PatientDetail.objects.all() start = options['start'] limit = options['limit'] chunk_size = options['chunk_size'] if limit is not None: patient_details = base_query[start:start + limit] else: patient_details = base_query[start:] total = patient_details.count() counter = 0 num_succeeded = 0 num_failed = 0 logger.info('Starting migration of %d patient cases on domain %s.' % (total, domain)) nikshay_codes_to_location = get_nikshay_codes_to_location(domain) factory = CaseFactory(domain=domain) case_structures = [] for patient_detail in patient_details: counter += 1 try: case_factory = EnikshayCaseFactory( domain, patient_detail, nikshay_codes_to_location ) case_structures.extend(case_factory.get_case_structures_to_create()) except Exception: num_failed += 1 logger.error( 'Failed on %d of %d. Nikshay ID=%s' % ( counter, total, patient_detail.PregId ), exc_info=True, ) else: num_succeeded += 1 if num_succeeded % chunk_size == 0: logger.info('committing cases {}-{}...'.format(num_succeeded - chunk_size, num_succeeded)) factory.create_or_update_cases(case_structures) case_structures = [] logger.info('done') logger.info( 'Succeeded on %s of %d. Nikshay ID=%s' % ( counter, total, patient_detail.PregId ) ) if case_structures: logger.info('committing final cases...'.format(num_succeeded - chunk_size, num_succeeded)) factory.create_or_update_cases(case_structures) logger.info('Done creating cases for domain %s.' % domain) logger.info('Number of attempts: %d.' % counter) logger.info('Number of successes: %d.' % num_succeeded) logger.info('Number of failures: %d.' % num_failed)
def test_form_extras_default(self): domain = uuid.uuid4().hex # have to enable loose sync token validation for the domain or create actual SyncLog documents. # this is the easier path. token_id = uuid.uuid4().hex factory = CaseFactory(domain=domain, form_extras={'last_sync_token': token_id}) case = factory.create_case() form = FormAccessors(domain).get_form(case.xform_ids[0]) self.assertEqual(token_id, form.last_sync_token)
class TestGetSubcasesExpression(TestCase): def setUp(self): super(TestGetSubcasesExpression, self).setUp() self.domain = uuid.uuid4().hex self.factory = CaseFactory(domain=self.domain) self.expression = ExpressionFactory.from_spec({ "type": "get_subcases", "case_id_expression": { "type": "property_name", "property_name": "_id" }, }) self.context = EvaluationContext({"domain": self.domain}) def tearDown(self): delete_all_xforms() delete_all_cases() super(TestGetSubcasesExpression, self).tearDown() @run_with_all_backends def test_no_subcases(self): case = self.factory.create_case() subcases = self.expression(case.to_json(), self.context) self.assertEqual(len(subcases), 0) @run_with_all_backends def test_single_child(self): parent_id = uuid.uuid4().hex child_id = uuid.uuid4().hex [child, parent] = self.factory.create_or_update_case(CaseStructure( case_id=child_id, indices=[ CaseIndex(CaseStructure(case_id=parent_id, attrs={'create': True})) ] )) subcases = self.expression(parent.to_json(), self.context) self.assertEqual(len(subcases), 1) self.assertEqual(child.case_id, subcases[0]['_id']) @run_with_all_backends def test_single_extension(self): host_id = uuid.uuid4().hex extension_id = uuid.uuid4().hex [extension, host] = self.factory.create_or_update_case(CaseStructure( case_id=extension_id, indices=[ CaseIndex( CaseStructure(case_id=host_id, attrs={'create': True}), relationship=CASE_INDEX_EXTENSION ) ] )) subcases = self.expression(host.to_json(), self.context) self.assertEqual(len(subcases), 1) self.assertEqual(extension.case_id, subcases[0]['_id'])
def test_no_walk_related(self): factory = CaseFactory() parent = factory.create_case() child_updates = factory.create_or_update_case( CaseStructure(attrs={'create': True}, walk_related=False, relationships=[ CaseRelationship(CaseStructure(case_id=parent._id)) ]), ) self.assertEqual(1, len(child_updates)) self.assertEqual(parent._id, child_updates[0].indices[0].referenced_id)
def test_form_extras_default(self): domain = uuid.uuid4().hex # have to enable loose sync token validation for the domain or create actual SyncLog documents. # this is the easier path. LOOSE_SYNC_TOKEN_VALIDATION.set(domain, True, namespace='domain') token_id = uuid.uuid4().hex factory = CaseFactory(domain=domain, form_extras={'last_sync_token': token_id}) case = factory.create_case() form = XFormInstance.get(case.xform_ids[0]) self.assertEqual(token_id, form.last_sync_token)
def create_case(domain, case_type, **kwargs): case = CaseFactory(domain).create_case(case_type=case_type, **kwargs) try: yield case finally: if should_use_sql_backend(domain): CaseAccessorSQL.hard_delete_cases(domain, [case.case_id]) else: case.delete()
def test_simple_delete(self): factory = CaseFactory() case = factory.create_case() [case] = factory.create_or_update_case(CaseStructure(case_id=case._id, attrs={'update': {'foo': 'bar'}})) self.assertTrue(CommCareCase.get_db().doc_exist(case._id)) self.assertEqual(2, len(case.xform_ids)) for form_id in case.xform_ids: self.assertTrue(XFormInstance.get_db().doc_exist(form_id)) safe_hard_delete(case) self.assertFalse(CommCareCase.get_db().doc_exist(case._id)) for form_id in case.xform_ids: self.assertFalse(XFormInstance.get_db().doc_exist(form_id))
def setUp(self): # can't do this in setUpClass until Django 1.9 since @override_settings # doesn't apply to classmethods from corehq.apps.commtrack.tests import get_single_balance_block factory = CaseFactory(domain=self.domain) self.case = factory.create_case() submit_case_blocks([ get_single_balance_block(self.case.case_id, self.product._id, 10) ], self.domain) ledger_values = LedgerAccessorSQL.get_ledger_values_for_case(self.case.case_id) self.assertEqual(1, len(ledger_values))
def test_recursive_indexes(self): factory = CaseFactory() [case] = factory.create_or_update_case(CaseStructure( case_id='infinite-recursion', attrs={'case_type': 'bug'}, indices=[CaseIndex(CaseStructure(case_id='infinite-recursion'), related_type='bug')], walk_related=False )) # this call used to fail with infinite recursion hierarchy = get_case_hierarchy(case, {}) self.assertEqual(1, len(hierarchy['case_list']))
def test_ledger_pillow_sql(self): factory = CaseFactory(domain=self.domain) case = factory.create_case() consumer = get_test_kafka_consumer(topics.LEDGER) # have to get the seq id before the change is processed kafka_seq = consumer.offsets()['fetch'][(topics.LEDGER, 0)] from corehq.apps.commtrack.tests import get_single_balance_block from corehq.apps.hqcase.utils import submit_case_blocks submit_case_blocks([ get_single_balance_block(case.case_id, self.product_id, 100)], self.domain ) ref = UniqueLedgerReference(case.case_id, 'stock', self.product_id) # confirm change made it to kafka message = consumer.next() change_meta = change_meta_from_kafka_message(message.value) if should_use_sql_backend(self.domain): self.assertEqual(ref.as_id(), change_meta.document_id) else: from corehq.apps.commtrack.models import StockState state = StockState.objects.all() self.assertEqual(1, len(state)) self.assertEqual(state[0].pk, change_meta.document_id) # self.assertEqual(self.domain, change_meta.domain) # send to elasticsearch self.pillow.process_changes(since=kafka_seq, forever=False) self.elasticsearch.indices.refresh(LEDGER_INDEX_INFO.index) # confirm change made it to elasticserach results = self.elasticsearch.search( LEDGER_INDEX_INFO.index, LEDGER_INDEX_INFO.type, body={ "query": { "bool": { "must": [{ "match_all": {} }] } } } ) self.assertEqual(1, results['hits']['total']) ledger_doc = results['hits']['hits'][0]['_source'] self.assertEqual(self.domain, ledger_doc['domain']) self.assertEqual(ref.case_id, ledger_doc['case_id']) self.assertEqual(ref.section_id, ledger_doc['section_id']) self.assertEqual(ref.entry_id, ledger_doc['entry_id'])
def test_delete_sharing_form(self): factory = CaseFactory() c1, c2 = factory.create_or_update_cases([ CaseStructure(attrs={'create': True}), CaseStructure(attrs={'create': True}), ]) with self.assertRaises(CommCareCaseError): safe_hard_delete(c1) with self.assertRaises(CommCareCaseError): safe_hard_delete(c2) self.assertIsNotNone(self.casedb.get_case(c1.case_id)) self.assertIsNotNone(self.casedb.get_case(c2.case_id))
def test_get_call_center_cases_all(self): factory = CaseFactory(domain=TEST_DOMAIN, case_defaults={ 'user_id': self.user_id, 'owner_id': self.user_id, 'case_type': CASE_TYPE, 'update': {'hq_user_id': self.user_id} }) factory.create_or_update_cases([ CaseStructure(attrs={'create': True}), CaseStructure(attrs={'create': True}), CaseStructure(attrs={'create': True, 'owner_id': 'another_user'}), ]) cases = get_call_center_cases(TEST_DOMAIN, CASE_TYPE) self.assertEqual(len(cases), 3)
def _with_case(domain, case_type, last_modified): with drop_connected_signals(case_post_save): case = CaseFactory(domain).create_case(case_type=case_type) _update_case(domain, case.case_id, last_modified) accessors = CaseAccessors(domain) case = accessors.get_case(case.case_id) try: yield case finally: if should_use_sql_backend(domain): CaseAccessorSQL.hard_delete_cases(domain, [case.case_id]) else: case.delete()
def test_delete_sharing_form(self): factory = CaseFactory() c1, c2 = factory.create_or_update_cases([ CaseStructure(attrs={'create': True}), CaseStructure(attrs={'create': True}), ]) with self.assertRaises(CommCareCaseError): FormProcessorInterface.hard_delete_case(c1) with self.assertRaises(CommCareCaseError): FormProcessorInterface.hard_delete_case(c2) self.assertIsNotNone(FormProcessorInterface.get_case(c1.id)) self.assertIsNotNone(FormProcessorInterface.get_case(c2.id))
def other_domain_factory(other_domain_name): domain_obj = create_domain(other_domain_name) factory = CaseFactory(domain=other_domain_name) try: yield factory finally: domain_obj.delete()
def test_user_recipient(self): reminder = (CaseReminderHandler .create(self.domain, 'test') .set_case_criteria_start_condition('participant', 'status', MATCH_EXACT, 'green') .set_case_criteria_start_date() .set_last_submitting_user_recipient() .set_sms_content_type('en') .set_daily_schedule(fire_time=time(12, 0), message={'en': "{case.name}'s test result was normal."}) .set_stop_condition(max_iteration_count=REPEAT_SCHEDULE_INDEFINITELY) .set_advanced_options()) reminder.save() self.assertEqual(self.get_reminders(), []) with create_test_case(self.domain, 'participant', 'bob', drop_signals=False) as case, \ patch('corehq.apps.reminders.models.CaseReminderHandler.get_now') as now_mock: self.assertEqual(self.get_reminders(), []) now_mock.return_value = datetime(2016, 1, 1, 10, 0) # There should still be no reminder instance since this is submitted by the system user update_case(self.domain, case.case_id, case_properties={'status': 'green'}) self.assertEqual(self.get_reminders(), []) # Update the user id on the case CaseFactory(self.domain).create_or_update_case( CaseStructure( case_id=case.case_id, attrs={'user_id': self.user.get_id} ) ) reminder_instance = self.assertOneReminder()
def setUp(self): super(ImporterTest, self).setUp() self.domain_obj = create_domain("importer-test") self.domain = self.domain_obj.name self.default_case_type = 'importer-test-casetype' self.couch_user = WebUser.create(None, "test", "foobar") self.couch_user.add_domain_membership(self.domain, is_admin=True) self.couch_user.save() self.accessor = CaseAccessors(self.domain) self.factory = CaseFactory(domain=self.domain, case_defaults={ 'case_type': self.default_case_type, }) delete_all_cases()
class ZapierUpdateCase(View): urlname = 'zapier_update_case' @method_decorator(login_or_api_key) @method_decorator(csrf_exempt) def dispatch(self, request, *args, **kwargs): domain = args[0] if not domain_has_privilege(domain, privileges.ZAPIER_INTEGRATION): return HttpResponseForbidden() return super(ZapierUpdateCase, self).dispatch(request, *args, **kwargs) def post(self, request, *args, **kwargs): domain = request.GET.get('domain') case_type = request.GET.get('case_type') user_name = request.GET.get('user') properties = json.loads(request.body.decode('utf-8')) case_id = properties['case_id'] properties.pop('case_id') couch_user = CommCareUser.get_by_username(user_name) if not couch_user.is_member_of(domain): return HttpResponseForbidden( "This user does not have access to this domain.") case = get_case_or_404(domain, case_id) if not case.type == case_type: return HttpResponseBadRequest("Case type mismatch") factory = CaseFactory(domain=domain) factory.update_case(case_id=case_id, update=properties) return HttpResponse("Case {case_id} updated".format(case_id=case_id))
def test_call_center_not_default_case_owner(self): """ call center case owner should not change on sync """ factory = CaseFactory(domain=TEST_DOMAIN, case_defaults={ 'user_id': self.user_id, 'owner_id': 'another_user', 'case_type': CASE_TYPE, 'update': {'hq_user_id': self.user_id} }) cases = factory.create_or_update_cases([ CaseStructure(attrs={'create': True}) ]) sync_call_center_user_case(self.user) case = self._get_user_case() self.assertEqual(case.owner_id, cases[0].owner_id)
class StockTestBase(TestCase): @classmethod def setUpClass(cls): cls.domain = create_domain("stock-report-test") @classmethod def tearDownClass(cls): cls.domain.delete() def setUp(self): # create case case = CaseFactory(domain=self.domain.name).create_case() self.case_id = case.case_id self.product_id = uuid.uuid4().hex SQLProduct(product_id=self.product_id, domain=self.domain.name).save() self._stock_report = functools.partial(_stock_report, self.domain.name, self.case_id, self.product_id) self._receipt_report = functools.partial(_receipt_report, self.domain.name, self.case_id, self.product_id) self._test_config = ConsumptionConfiguration.test_config() self._compute_consumption = functools.partial( compute_daily_consumption, self.domain.name, self.case_id, self.product_id, now, configuration=self._test_config)
def setUp(self): super(ENikshayCaseStructureMixin, self).setUp() delete_all_users() self.domain = getattr(self, 'domain', 'fake-domain-from-mixin') self.factory = CaseFactory(domain=self.domain) self.user = CommCareUser.create( self.domain, "jon-snow@user", "123", ) self.person_id = u"person" self.occurrence_id = u"occurrence" self.episode_id = u"episode" self.primary_phone_number = "0123456789" self.secondary_phone_number = "0999999999" self.treatment_supporter_phone = "066000666"
def setUp(self): super(TestFormsExpressionSpec, self).setUp() self.domain = uuid.uuid4().hex factory = CaseFactory(domain=self.domain) [self.case] = factory.create_or_update_case(CaseStructure(attrs={'create': True})) self.forms = [f.to_json() for f in FormAccessors(self.domain).get_forms(self.case.xform_ids)] # redundant case to create extra forms that shouldn't be in the results for self.case [self.case_b] = factory.create_or_update_case(CaseStructure(attrs={'create': True})) self.expression = ExpressionFactory.from_spec({ "type": "get_case_forms", "case_id_expression": { "type": "property_name", "property_name": "_id" }, })
def setUpClass(cls): super(TestSQLDumpLoadShardedModels, cls).setUpClass() cls.factory = CaseFactory(domain=cls.domain_name) cls.form_accessors = FormAccessors(cls.domain_name) cls.case_accessors = CaseAccessors(cls.domain_name) cls.product = make_product(cls.domain_name, 'A Product', 'prodcode_a') cls.default_objects_counts.update({SQLProduct: 1})
def update_case(self, case_id, case_properties): followup_id = int(case_properties['migration_created_from_id']) followup = Followup.objects.get(id=followup_id) try: nikshay_codes = ( followup.DmcStoCode, followup.DmcDtoCode, followup.DmcTbuCode, str(followup.DMC), ) dmc = self._loc_code_to_location()[nikshay_codes] except KeyError: self.missing_nikshay_codes.add(nikshay_codes) return CaseFactory(self.domain).update_case( case_id, update={ 'testing_facility_id': dmc.location_id, 'testing_facility_name': dmc.name, 'legacy_DmcStoCode': followup.DmcStoCode, 'legacy_DmcDtoCode': followup.DmcDtoCode, 'legacy_DmcTbuCode': followup.DmcTbuCode, 'legacy_DMC': followup.DMC, }, )
def setUpClass(cls): super().setUpClass() cls.domain = 'test' cls.domain_obj = create_domain(cls.domain) cls.setup_subscription(cls.domain, SoftwarePlanEdition.PRO) cls.factory = CaseFactory(cls.domain) url = 'fake-url' cls.connection = ConnectionSettings.objects.create(domain=cls.domain, name=url, url=url) cls.repeater = CaseExpressionRepeater( domain=cls.domain, connection_settings_id=cls.connection.id, configured_filter={ "type": "or", "filters": [{ "type": "boolean_expression", "expression": { "type": "reduce_items", "aggregation_fn": "count", "items_expression": { "type": "get_case_forms", "case_id_expression": { "property_name": "case_id", "type": "property_name" } } }, "operator": "gt", "property_value": 1 }, { "type": "boolean_expression", "expression": { "type": "property_name", "property_name": "type", }, "operator": "eq", "property_value": "forward-me", }] }, configured_expression={ "type": "dict", "properties": { "case_id": { "type": "property_name", "property_name": "case_id", }, "a-constant": { "type": "constant", "constant": "foo", } } }) cls.repeater.save()
def test_ledger_reindexer(self): factory = CaseFactory(domain=self.domain) case = factory.create_case() from corehq.apps.commtrack.tests.util import get_single_balance_block from corehq.apps.hqcase.utils import submit_case_blocks submit_case_blocks([ get_single_balance_block(case.case_id, self.product_id, 100)], self.domain ) ref = UniqueLedgerReference(case.case_id, 'stock', self.product_id) index_id = 'ledger-v2' if settings.TESTS_SHOULD_USE_SQL_BACKEND else 'ledger-v1' call_command('ptop_reindexer_v2', index_id, cleanup=True, noinput=True, reset=True) self._assert_ledger_in_es(ref)
def test_normal_index(self): factory = CaseFactory() [cp] = factory.create_or_update_case( CaseStructure(case_id='parent', attrs={'case_type': 'parent'})) factory.create_or_update_case( CaseStructure(case_id='child', attrs={'case_type': 'child'}, indices=[ CaseIndex(CaseStructure(case_id='parent'), related_type='parent') ], walk_related=False)) hierarchy = get_case_hierarchy(cp, {}) self.assertEqual(2, len(hierarchy['case_list'])) self.assertEqual(1, len(hierarchy['child_cases']))
def test_deleted_index(self): hierarchy = self.test_normal_index() parent, child = hierarchy['case_list'] factory = CaseFactory() ref = CaseStructure() ref.case_id = "" # reset case_id to empty factory.create_or_update_case( CaseStructure(case_id=child.case_id, indices=[CaseIndex(ref, related_type='parent')], walk_related=False), ) # re-fetch case to clear memoized properties parent = CommCareCase.objects.get_case(parent.case_id, parent.domain) hierarchy = get_case_hierarchy(parent, {}) self.assertEqual(1, len(hierarchy['case_list'])) self.assertEqual(0, len(hierarchy['child_cases']))
def setUpClass(cls): cls.domain = Domain(name='foo') cls.domain.save() cls.user = CommCareUser.create(cls.domain.name, 'somebody', 'password') cls.user_id = cls.user._id cls.factory = CaseFactory(domain='foo', case_defaults={'owner_id': cls.user_id}) ENABLE_LOADTEST_USERS.set('foo', True, namespace='domain')
def setUpClass(cls): super(LoadtestUserTest, cls).setUpClass() cls.domain = Domain(name='foo') cls.domain.save() cls.user = CommCareUser.create(cls.domain.name, 'somebody', 'password', None, None) cls.user_id = cls.user._id cls.factory = CaseFactory(domain='foo', case_defaults={'owner_id': cls.user_id}) ENABLE_LOADTEST_USERS.set('foo', True, namespace=NAMESPACE_DOMAIN)
def setUpClass(cls): super(NinetyNineDotsCaseTests, cls).setUpClass() FormProcessorTestUtils.delete_all_cases() cls.domain = 'enikshay-test' cls.factory = CaseFactory(domain=cls.domain) cls.person_id = "person" cls.occurrence_id = "occurrence" cls.episode_id = "episode"
def handle(self, domain, log_path, **options): commit = options['commit'] factory = CaseFactory(domain) logger.info("Starting {} migration on {} at {}".format( "real" if commit else "fake", domain, datetime.datetime.utcnow())) cases = (CaseSearchES().domain(domain).case_type( "episode").case_property_query("case_version", "20", "must").scroll()) with open(log_path, "w") as f: for case in cases: case_props = { prop['key']: prop['value'] for prop in case['case_properties'] } referred_by_id = case_props.get('referred_by_id') updated_by_migration = case_props.get('updated_by_migration') if ((updated_by_migration == 'enikshay_2b_case_properties' or updated_by_migration == 'enikshay_2b_treatment_status_fix') and referred_by_id): case_id = case['_id'] f.write(case_id + "\n") logger.info(case_id) case_structure = CaseStructure( case_id=case_id, walk_related=False, attrs={ "create": False, "update": { "referred_outside_enikshay_by_id": referred_by_id, "updated_by_migration": "enikshay_2b_referred_by_id_fix", }, }, ) if commit: factory.create_or_update_case(case_structure) logger.info("Migration finished at {}".format( datetime.datetime.utcnow()))
def test_matching_case_not_migrated(self): call_command('create_enikshay_cases', self.domain, 'test_migration') episode_case_ids = self.case_accessor.get_case_ids_in_domain(type='episode') CaseFactory(self.domain).update_case(episode_case_ids[0], update={'migration_created_case': ''}) with self.assertRaises(MatchingNikshayIdCaseNotMigrated): EnikshayCaseFactory( self.domain, 'test_migration', self.patient_detail, {}, 'test_phi' ).get_case_structures_to_create()
def test_legacy_support_toggle(self): restore_config = RestoreConfig(self.project, restore_user=self.user) factory = CaseFactory(domain=self.project.name, case_defaults={'owner_id': self.user_id}) # create a parent and child case (with index) from one user parent_id, child_id = [uuid.uuid4().hex for i in range(2)] factory.create_or_update_cases([ CaseStructure( case_id=child_id, attrs={'create': True}, indices=[ CaseIndex( CaseStructure(case_id=parent_id, attrs={'create': True}), relationship='child', related_type='parent', ) ], ) ]) restore_payload = restore_config.get_payload().as_string().decode( 'utf-8') self.assertTrue(child_id in restore_payload) self.assertTrue(parent_id in restore_payload) sync_log = deprecated_synclog_from_restore_payload(restore_payload) self.assertEqual(SimplifiedSyncLog, type(sync_log)) # make both cases irrelevant by changing the owner ids factory.create_or_update_cases([ CaseStructure(case_id=parent_id, attrs={'owner_id': 'different'}), CaseStructure(case_id=child_id, attrs={'owner_id': 'different'}), ], form_extras={ 'last_sync_token': sync_log._id }) # doing it again should fail since they are no longer relevant # todo: add this back in when we add the assertion back. see SimplifiedSyncLog.prune_case # with self.assertRaises(SimplifiedSyncAssertionError): # factory.create_or_update_cases([ # CaseStructure(case_id=child_id, attrs={'owner_id': 'different'}), # CaseStructure(case_id=parent_id, attrs={'owner_id': 'different'}), # ], form_extras={'last_sync_token': sync_log._id}) # enabling the toggle should prevent the failure the second time # though we also need to hackily set the request object in the threadlocals LEGACY_SYNC_SUPPORT.set(self.domain, True, namespace=NAMESPACE_DOMAIN) request = JsonObject(domain=self.domain, path='testsubmit') set_request(request) factory.create_or_update_cases([ CaseStructure(case_id=child_id, attrs={'owner_id': 'different'}), CaseStructure(case_id=parent_id, attrs={'owner_id': 'different'}), ], form_extras={ 'last_sync_token': sync_log._id })
def test_delete_with_related(self): factory = CaseFactory() parent = factory.create_case() [child] = factory.create_or_update_case( CaseStructure( attrs={'create': True}, walk_related=False, indices=[CaseIndex(CaseStructure(case_id=parent.case_id))]), ) # deleting the parent should not be allowed because the child still references it with self.assertRaises(CommCareCaseError): safe_hard_delete(parent) # deleting the child is ok safe_hard_delete(child) self.assertIsNotNone(self.casedb.get_case(parent.case_id)) with self.assertRaises(CaseNotFound): self.casedb.get_case(child.case_id)
def handle(self, domain, log_path, log_errors, **options): commit = options['commit'] accessor = CaseAccessors(domain) factory = CaseFactory(domain) headers = [ 'case_id', 'diagnosis_test_result_date', 'diagnosis_lab_facility_name', 'diagnosis_test_lab_serial_number', 'diagnosis_test_summary', 'datamigration_diagnosis_test_information', ] print("Starting {} migration on {} at {}".format( "real" if commit else "fake", domain, datetime.datetime.utcnow() )) with open(log_errors, 'w') as log_errors_file: error_logger = csv.writer(log_errors_file) error_logger.writerow(['case_id']) with open(log_path, "w") as log_file: writer = csv.writer(log_file) writer.writerow(headers) for episode_case_id in accessor.get_case_ids_in_domain(type='episode'): print('Looking at {}'.format(episode_case_id)) episode_case = accessor.get_case(episode_case_id) case_properties = episode_case.dynamic_case_properties() if self.should_migrate_case(case_properties): test = self.get_relevant_test_case(domain, episode_case, error_logger) if test is not None: update = self.get_updates(test) print('Updating {}...'.format(episode_case_id)) writer.writerow([episode_case_id] + [update[key] for key in headers[1:]]) if commit: factory.update_case(case_id=episode_case_id, update=update) else: print('No relevant test found for episode {}'.format(episode_case_id)) else: print('Do not migrate {}'.format(episode_case_id)) print('Migration complete at {}'.format(datetime.datetime.utcnow()))
def close_all_usercases(self): usercase_ids = CommCareCase.objects.get_case_ids_in_domain(self.domain, USERCASE_TYPE) for usercase_id in usercase_ids: CaseFactory(self.domain).close_case(usercase_id) usercase = CommCareCase.objects.get_case(usercase_id, self.domain) send_to_elasticsearch( "case_search", transform_case_for_elasticsearch(usercase.to_json()) ) self.es.indices.refresh(CASE_SEARCH_INDEX_INFO.index)
def test_delete_with_related(self): factory = CaseFactory() parent = factory.create_case() [child] = factory.create_or_update_case( CaseStructure(attrs={'create': True}, walk_related=False, relationships=[ CaseRelationship( CaseStructure(case_id=parent._id)) ]), ) # deleting the parent should not be allowed because the child still references it with self.assertRaises(CommCareCaseError): safe_hard_delete(parent) # deleting the child is ok safe_hard_delete(child) self.assertTrue(CommCareCase.get_db().doc_exist(parent._id)) self.assertFalse(CommCareCase.get_db().doc_exist(child._id))
def _test_case_deletion(self): for domain_name in [self.domain.name, self.domain2.name]: CaseFactory(domain_name).create_case() self.assertEqual(len(CaseAccessors(domain_name).get_case_ids_in_domain()), 1) self.domain.delete() self.assertEqual(len(CaseAccessors(self.domain.name).get_case_ids_in_domain()), 0) self.assertEqual(len(CaseAccessors(self.domain2.name).get_case_ids_in_domain()), 1)
def _setup_casedata(cls): cls.episode_id = "episode" factory = CaseFactory(domain=cls.domain) person = get_person_case_structure( "person", cls.user.user_id, ) occurrence = get_occurrence_case_structure("occurence", person) episode_structure = get_episode_case_structure(cls.episode_id, occurrence) cases = { case.case_id: case for case in factory.create_or_update_cases([episode_structure]) }
def test_ledger_reindexer(self): factory = CaseFactory(domain=self.domain) case = factory.create_case() from corehq.apps.commtrack.tests.util import get_single_balance_block from corehq.apps.hqcase.utils import submit_case_blocks submit_case_blocks( [get_single_balance_block(case.case_id, self.product_id, 100)], self.domain) ref = UniqueLedgerReference(case.case_id, 'stock', self.product_id) use_sql = should_use_sql_backend(self.domain) index_id = 'ledger-v2' if use_sql else 'ledger-v1' options = {'reset': True} if use_sql else {} reindex_and_clean(index_id, **options) self._assert_ledger_in_es(ref)
def test_custom_action(self): checkin_case = self.make_checkin_case() rule = create_empty_rule( self.domain, AutomaticUpdateRule.WORKFLOW_CASE_UPDATE, case_type="checkin", ) case_properties = { "assigned_to_primary_checkin_case_id": checkin_case.case_id, "is_assigned_primary": "foo", "assigned_to_primary_name": "bar", "assigned_to_primary_username": "******", } patient_case = CaseFactory(self.domain).create_case( case_type="patient", owner_id=self.mobile_worker.get_id, update=case_properties, ) other_patient_case = CaseFactory(self.domain).create_case( case_type="patient", owner_id=self.mobile_worker.get_id, update={"assigned_to_primary_checkin_case_id": "123"}, ) other_case = CaseFactory(self.domain).create_case( case_type="other", owner_id=self.mobile_worker.get_id, update={"assigned_to_primary_checkin_case_id": checkin_case.case_id}, ) for case in [patient_case, other_patient_case, other_case]: send_to_elasticsearch("case_search", transform_case_for_elasticsearch(case.to_json())) self.es.indices.refresh(CASE_SEARCH_INDEX_INFO.index) close_cases_assigned_to_checkin(checkin_case, rule) self.assertTrue(CommCareCase.objects.get_case(checkin_case.case_id).closed, self.domain) patient_case = CommCareCase.objects.get_case(patient_case.case_id, self.domain) self.assertFalse(patient_case.closed) for prop in case_properties: self.assertEqual(patient_case.get_case_property(prop), "") other_case = CommCareCase.objects.get_case(other_case.case_id, self.domain) self.assertFalse(other_case.closed) self.assertEqual( other_case.get_case_property("assigned_to_primary_checkin_case_id"), checkin_case.case_id, ) other_patient_case = CommCareCase.objects.get_case(other_patient_case.case_id, self.domain) self.assertFalse(other_patient_case.closed) self.assertEqual( other_patient_case.get_case_property("assigned_to_primary_checkin_case_id"), "123", )
def test_update_cases(self): builder1 = (IntentCaseBuilder(self.registry_slug).target_case( self.target_domain, self.target_case_id_1).case_properties(new_prop="new_val_case1")) builder2 = (IntentCaseBuilder(self.registry_slug).target_case( self.target_domain, self.target_case_id_2).case_properties(new_prop="new_val_case2")) factory = CaseFactory(self.domain) host = CaseStructure(attrs={ "create": True, "case_type": "registry_case_update", "update": builder1.props }, ) extension = CaseStructure( attrs={ "create": True, "case_type": "registry_case_update", "update": builder2.props }, indices=[CaseIndex( host, relationship=CASE_INDEX_EXTENSION, )]) cases = factory.create_or_update_case(extension, user_id=self.mobile_user.get_id) repeat_records = self.repeat_records(self.domain).all() self.assertEqual(len(repeat_records), 1) payload = repeat_records[0].get_payload() host_case = cases[1] form = DataRegistryUpdateForm(payload, host_case) form.assert_case_updates({ self.target_case_id_1: { "new_prop": "new_val_case1" }, self.target_case_id_2: { "new_prop": "new_val_case2" } }) url = self.repeater.get_url(repeat_records[0]) self.assertEqual(url, f"case-repeater-url/{self.target_domain}/") # check that the synchronous attempt of the repeat record happened self.assertEqual(1, len(repeat_records[0].attempts))
def test_excluded_case_types_are_not_forwarded(self): self.repeater.white_listed_case_types = ['planet'] self.repeater.save() white_listed_case = CaseBlock( case_id="a_case_id", create=True, case_type="planet", ).as_xml() CaseFactory(self.domain_name).post_case_blocks([white_listed_case]) self.assertEqual(1, len(self.repeat_records(self.domain_name).all())) non_white_listed_case = CaseBlock( case_id="b_case_id", create=True, case_type="cat", ).as_xml() CaseFactory(self.domain_name).post_case_blocks([non_white_listed_case]) self.assertEqual(1, len(self.repeat_records(self.domain_name).all()))