def test_skip_fixture(self): device = MockDevice(self.domain, self.restore_user) restore = device.sync().payload.decode('utf-8') self.assertIn('<fixture ', restore) restore_without_fixture = device.sync( skip_fixtures=True).payload.decode('utf-8') self.assertNotIn('<fixture ', restore_without_fixture)
def setUpClass(cls): super(AppStatusIntegrationTest, cls).setUpClass() delete_all_docs_by_doc_type(Domain.get_db(), ['Domain', 'Domain-Deleted']) delete_all_docs_by_doc_type(CommCareUser.get_db(), ['CommCareUser', 'WebUser']) delete_all_docs_by_doc_type(Application.get_db(), ['Application', 'Application-Deleted']) cls.domain_records = [ Domain(name=cls.domain, hr_name='One', creating_user_id='abc', is_active=True), ] for domain in cls.domain_records: domain.save() cls.user_records = [ # TODO: Handle WebUsers who have multiple domains # WebUser.create( # cls.domain, # 'web-user', # '***', # date_joined=datetime.utcnow(), # first_name='A', # last_name='B', # email='*****@*****.**', # is_active=True, # is_staff=False, # is_superuser=True, # ), CommCareUser.create( cls.domain, 'commcare-user', '***', date_joined=datetime.utcnow(), email='*****@*****.**', is_active=True, is_staff=True, is_superuser=False, ), ] cls.form_records = [ create_form_for_test(cls.domain, user_id=cls.user_records[0]._id), create_form_for_test(cls.domain, user_id=cls.user_records[0]._id), create_form_for_test(cls.domain, user_id=cls.user_records[0]._id), ] cls.sync_records = [] for user in cls.user_records: restore_user = OTARestoreCommCareUser(user.domain, user) device = MockDevice(cls.domain_records[0], restore_user) cls.sync_records.append(device.sync()) cls.batch = create_batch(cls.slug)
def test_previous_log_purged(self): device = MockDevice(self.project, self.restore_user) initial_sync = device.sync(items=True, version=V1, app=self.app) initial_synclog_id = initial_sync.restore_id self.assertIsNone(initial_sync.get_log().previous_log_id) # form submission success when there is no previous sync log form_xml = get_simple_form_xml(uuid.uuid4().hex) submit_form_locally(form_xml, self.domain, last_sync_token=initial_synclog_id) # second sync second_sync = device.sync(version=V1, app=self.app) third_sync = device.sync(version=V1, app=self.app) # form submission after second sync should remove first synclog form_xml = get_simple_form_xml(uuid.uuid4().hex) submit_form_locally(form_xml, self.domain, last_sync_token=third_sync.restore_id) third_synclog = third_sync.get_log() # re-fetch self.assertIsNone(third_synclog.previous_log_id) with self.assertRaises(MissingSyncLog): initial_sync.get_log() with self.assertRaises(MissingSyncLog): second_sync.get_log() # form submissions after purge don't fail form_xml = get_simple_form_xml(uuid.uuid4().hex) submit_form_locally(form_xml, self.domain, last_sync_token=third_sync.restore_id) # restores after purge don't fail fourth_sync = device.sync(version=V1, app=self.app) response = fourth_sync.config.get_response() self.assertEqual(response.status_code, 200)
def testUserRestoreWithCase(self): restore_user = create_restore_user(domain=self.domain) case_id = 'my-case-id' device = MockDevice(self.project, restore_user) device.change_cases(CaseBlock( create=True, case_id=case_id, user_id=restore_user.user_id, owner_id=restore_user.user_id, case_type='test-case-type', update={'external_id': 'someexternal'}, )) self.assertIn(case_id, device.sync().cases)
def test_user_restore(self): from casexml.apps.phone.utils import MockDevice from casexml.apps.case.xml import V3 from corehq.apps.userreports.reports.data_source import ConfigurableReportDataSource with patch.object(ConfigurableReportDataSource, 'get_data') as get_data_mock: get_data_mock.return_value = self.rows with mock_datasource_config(): device = MockDevice(self.domain_obj, self.user) restore = device.sync(version=V3).payload.decode('utf-8') self.assertIn('<fixture id="commcare:reports"', restore) self.assertIn('report_id="{id}"'.format(id=self.report_config1._id), restore) self.assertIn('report_id="{id}"'.format(id=self.report_config2._id), restore)
def test_previous_log_purged(self): device = MockDevice(self.project, self.restore_user) initial_sync = device.sync(items=True, version=V1) initial_synclog_id = initial_sync.restore_id # form submission success when there is no previous sync log form_xml = get_simple_form_xml(uuid.uuid4().hex) submit_form_locally(form_xml, self.domain, last_sync_token=initial_synclog_id) # second sync second_sync = device.sync(version=V1) synclog_id = second_sync.restore_id synclog = second_sync.get_log() self.assertEqual(synclog.previous_log_id, initial_synclog_id) self.assertFalse(synclog.previous_log_removed) # form submission after second sync should remove first synclog form_xml = get_simple_form_xml(uuid.uuid4().hex) submit_form_locally(form_xml, self.domain, last_sync_token=synclog_id) synclog = second_sync.get_log() self.assertEqual(synclog.previous_log_id, initial_synclog_id) self.assertTrue(synclog.previous_log_removed) with self.assertRaises(ResourceNotFound): initial_sync.get_log() # form submissions after purge don't fail form_xml = get_simple_form_xml(uuid.uuid4().hex) submit_form_locally(form_xml, self.domain, last_sync_token=synclog_id) # restores after purge don't fail third_sync = device.sync(version=V1) response = third_sync.config.get_response() self.assertEqual(response.status_code, 200)
def test_prune_formplayer_synclogs(self): device = MockDevice(self.project, self.restore_user) device.id = 'WebAppsLogin-' + device.id first_sync = device.sync() second_sync = device.sync() third_sync = device.sync() device2 = MockDevice(self.project, self.restore_user) device2.id = 'WebAppsLogin-' + device2.id other_sync = device2.sync() form_xml = get_simple_form_xml(uuid.uuid4().hex) submit_form_locally(form_xml, self.domain, last_sync_token=third_sync.restore_id) self.assertIsNone(third_sync.get_log().previous_log_id) with self.assertRaises(MissingSyncLog): first_sync.get_log() with self.assertRaises(MissingSyncLog): second_sync.get_log() # Other sync for same user but with different device ID is still there self.assertIsNotNone(other_sync.get_log()) # form submissions after purge don't fail form_xml = get_simple_form_xml(uuid.uuid4().hex) submit_form_locally(form_xml, self.domain, last_sync_token=third_sync.restore_id) # restores after purge don't fail fourth_sync = device.sync() response = fourth_sync.config.get_response() self.assertEqual(response.status_code, 200)
def test_user_restore(self): from casexml.apps.phone.utils import MockDevice from casexml.apps.case.xml import V3 from corehq.apps.userreports.reports.data_source import ConfigurableReportDataSource with patch.object(ConfigurableReportDataSource, 'get_data') as get_data_mock: get_data_mock.return_value = self.rows with mock_datasource_config(): device = MockDevice(self.domain_obj, self.user) restore = device.sync(version=V3).payload.decode('utf-8') self.assertIn('<fixture id="commcare:reports"', restore) self.assertIn( 'report_id="{id}"'.format(id=self.report_config1._id), restore) self.assertIn( 'report_id="{id}"'.format(id=self.report_config2._id), restore)
def test_clean_owners_after_livequery(self): device = MockDevice(self.project, self.user, {"case_sync": LIVEQUERY}) device.sync() with self.assertRaises(RestoreException): device.sync(case_sync=CLEAN_OWNERS)
def test_basic_properties(self): # kick off a restore to generate the sync log device = MockDevice(self.project, self.restore_user) sync_log = device.sync(version=V1, items=True).log self.assertEqual(self.restore_user.user_id, sync_log.user_id) self.assertEqual(self.restore_user.domain, sync_log.domain)
def get_ota_balance_xml(project, user): device = MockDevice(project, user.to_ota_restore_user()) return extract_balance_xml(device.sync().payload)
class StateHashTest(TestCase): @classmethod def setUpClass(cls): super(StateHashTest, cls).setUpClass() delete_all_users() cls.project = Domain(name='state-hash-tests-project') cls.project.save() cls.user = create_restore_user(domain=cls.project.name) def setUp(self): delete_all_cases() delete_all_xforms() delete_all_sync_logs() # this creates the initial blank sync token in the database self.device = MockDevice(self.project, self.user) self.device.sync(version=V1) @classmethod def tearDownClass(cls): cls.project.delete() delete_all_users() super(StateHashTest, cls).tearDownClass() def testEmpty(self): empty_hash = CaseStateHash(EMPTY_HASH) wrong_hash = CaseStateHash("thisisntright") self.assertEqual(empty_hash, self.device.last_sync.log.get_state_hash()) response = self.device.get_restore_config().get_response() self.assertEqual(200, response.status_code) config = self.device.get_restore_config(state_hash=str(wrong_hash)) try: config.get_payload() except BadStateException as e: self.assertEqual(empty_hash, e.server_hash) self.assertEqual(wrong_hash, e.phone_hash) self.assertEqual(0, len(e.case_ids)) else: self.fail( "Call to generate a payload with a bad hash should fail!") self.assertEqual(412, config.get_response().status_code) def testMismatch(self): sync = self.device.last_sync self.assertEqual(CaseStateHash(EMPTY_HASH), sync.log.get_state_hash()) c1 = CaseBlock(case_id="abc123", create=True, owner_id=self.user.user_id) c2 = CaseBlock(case_id="123abc", create=True, owner_id=self.user.user_id) self.device.post_changes([c1, c2]) real_hash = CaseStateHash("409c5c597fa2c2a693b769f0d2ad432b") bad_hash = CaseStateHash("thisisntright") self.assertEqual(real_hash, sync.get_log().get_state_hash()) self.device.sync(state_hash=str(real_hash)) self.device.last_sync = sync try: self.device.sync(state_hash=str(bad_hash)) except BadStateException as e: self.assertEqual(real_hash, e.server_hash) self.assertEqual(bad_hash, e.phone_hash) self.assertEqual(set(e.case_ids), {"abc123", "123abc"}) else: self.fail( "Call to generate a payload with a bad hash should fail!")
class StateHashTest(TestCase): @classmethod def setUpClass(cls): super(StateHashTest, cls).setUpClass() delete_all_users() cls.project = Domain(name='state-hash-tests-project') cls.project.save() cls.user = create_restore_user(domain=cls.project.name) def setUp(self): super(StateHashTest, self).setUp() delete_all_cases() delete_all_xforms() delete_all_sync_logs() # this creates the initial blank sync token in the database self.device = MockDevice(self.project, self.user) self.device.sync(version=V1) @classmethod def tearDownClass(cls): cls.project.delete() delete_all_users() super(StateHashTest, cls).tearDownClass() def testEmpty(self): empty_hash = CaseStateHash(EMPTY_HASH) wrong_hash = CaseStateHash("thisisntright") self.assertEqual(empty_hash, self.device.last_sync.log.get_state_hash()) response = self.device.get_restore_config().get_response() self.assertEqual(200, response.status_code) config = self.device.get_restore_config(state_hash=str(wrong_hash)) try: config.get_payload() except BadStateException as e: self.assertEqual(empty_hash, e.server_hash) self.assertEqual(wrong_hash, e.phone_hash) self.assertEqual(0, len(e.case_ids)) else: self.fail("Call to generate a payload with a bad hash should fail!") self.assertEqual(412, config.get_response().status_code) def testMismatch(self): sync = self.device.last_sync self.assertEqual(CaseStateHash(EMPTY_HASH), sync.log.get_state_hash()) c1 = CaseBlock(case_id="abc123", create=True, owner_id=self.user.user_id) c2 = CaseBlock(case_id="123abc", create=True, owner_id=self.user.user_id) self.device.post_changes([c1, c2]) real_hash = CaseStateHash("409c5c597fa2c2a693b769f0d2ad432b") bad_hash = CaseStateHash("thisisntright") self.assertEqual(real_hash, sync.get_log().get_state_hash()) self.device.sync(state_hash=str(real_hash)) self.device.last_sync = sync try: self.device.sync(state_hash=str(bad_hash)) except BadStateException as e: self.assertEqual(real_hash, e.server_hash) self.assertEqual(bad_hash, e.phone_hash) self.assertEqual(set(e.case_ids), {"abc123", "123abc"}) else: self.fail("Call to generate a payload with a bad hash should fail!")