def test_old_then_new_sync(self): restore_config = RestoreConfig(self.project, user=self.user) case = CaseFactory(domain=self.project.name, case_defaults={ 'owner_id': self.user_id }).create_case() restore_payload = restore_config.get_payload().as_string() self.assertTrue(case._id in restore_payload) sync_log = synclog_from_restore_payload(restore_payload) self.assertEqual(SyncLog, type(sync_log)) restore_config = RestoreConfig( self.project, user=self.user, params=RestoreParams(sync_log_id=sync_log._id)) original_payload_back = restore_config.get_payload().as_string() self.assertFalse(case._id in original_payload_back) self.assertEqual( SyncLog, type(synclog_from_restore_payload(original_payload_back))) OWNERSHIP_CLEANLINESS_RESTORE.set(self.domain, enabled=True, namespace='domain') restore_config = RestoreConfig( self.project, user=self.user, params=RestoreParams(sync_log_id=sync_log._id), cache_settings=RestoreCacheSettings(overwrite_cache=True)) migrated_payload_back = restore_config.get_payload().as_string() self.assertFalse(case._id in migrated_payload_back) self.assertEqual( SimplifiedSyncLog, type(synclog_from_restore_payload(migrated_payload_back))) OWNERSHIP_CLEANLINESS_RESTORE.set(self.domain, enabled=False, namespace='domain')
def setUp(self): super(SyncPerformanceTest, self).setUp() # the other user is an "owner" of the original users cases as well, # for convenience self.project = Domain(name='sync-performance-tests') self.other_user = User(user_id=OTHER_USER_ID, username=OTHER_USERNAME, password="******", date_joined=datetime(2011, 6, 9), additional_owner_ids=[SHARED_ID], domain=self.project.name) self.referral_user = User(user_id=REFERRAL_USER_ID, username=REFERRAL_USERNAME, password="******", date_joined=datetime(2011, 6, 9), additional_owner_ids=[REFERRED_TO_GROUP], domain=self.project.name) # this creates the initial blank sync token in the database self.other_sync_log = synclog_from_restore_payload( generate_restore_payload(self.project, self.other_user)) self.referral_sync_log = synclog_from_restore_payload( generate_restore_payload(self.project, self.referral_user)) self.assertTrue(SHARED_ID in self.other_sync_log.owner_ids_on_phone) self.assertTrue( OTHER_USER_ID in self.other_sync_log.owner_ids_on_phone) self.user.additional_owner_ids = [SHARED_ID] self.sync_log = synclog_from_restore_payload( generate_restore_payload(self.project, self.user)) self.assertTrue(SHARED_ID in self.sync_log.owner_ids_on_phone) self.assertTrue(USER_ID in self.sync_log.owner_ids_on_phone)
def testCaching(self): self.assertFalse(self.sync_log.has_cached_payload(V2)) # first request should populate the cache original_payload = RestoreConfig( self.user, version=V2, restore_id=self.sync_log._id, ).get_payload().as_string() next_sync_log = synclog_from_restore_payload(original_payload) self.sync_log = SyncLog.get(self.sync_log._id) self.assertTrue(self.sync_log.has_cached_payload(V2)) # a second request with the same config should be exactly the same cached_payload = RestoreConfig( self.user, version=V2, restore_id=self.sync_log._id, ).get_payload().as_string() self.assertEqual(original_payload, cached_payload) # caching a different version should also produce something new versioned_payload = RestoreConfig( self.user, version=V1, restore_id=self.sync_log._id, ).get_payload().as_string() self.assertNotEqual(original_payload, versioned_payload) versioned_sync_log = synclog_from_restore_payload(versioned_payload) self.assertNotEqual(next_sync_log._id, versioned_sync_log._id)
def setUp(self): super(SyncPerformanceTest, self).setUp() # the other user is an "owner" of the original users cases as well, # for convenience self.project = Domain(name='sync-performance-tests') self.other_user = User(user_id=OTHER_USER_ID, username=OTHER_USERNAME, password="******", date_joined=datetime(2011, 6, 9), additional_owner_ids=[SHARED_ID], domain=self.project.name) self.referral_user = User(user_id=REFERRAL_USER_ID, username=REFERRAL_USERNAME, password="******", date_joined=datetime(2011, 6, 9), additional_owner_ids=[REFERRED_TO_GROUP], domain=self.project.name) # this creates the initial blank sync token in the database self.other_sync_log = synclog_from_restore_payload(generate_restore_payload( self.project, self.other_user )) self.referral_sync_log = synclog_from_restore_payload(generate_restore_payload( self.project, self.referral_user )) self.assertTrue(SHARED_ID in self.other_sync_log.owner_ids_on_phone) self.assertTrue(OTHER_USER_ID in self.other_sync_log.owner_ids_on_phone) self.user.additional_owner_ids = [SHARED_ID] self.sync_log = synclog_from_restore_payload(generate_restore_payload( self.project, self.user )) self.assertTrue(SHARED_ID in self.sync_log.owner_ids_on_phone) self.assertTrue(USER_ID in self.sync_log.owner_ids_on_phone)
def testMultiUserEdits(self): time = datetime.now() # create a case from one user case_id = "multi_user_edits" self._createCaseStubs([case_id], owner_id=SHARED_ID) # both users syncs self.sync_log = synclog_from_restore_payload(generate_restore_payload(self.user)) self.other_sync_log = synclog_from_restore_payload(generate_restore_payload(self.other_user)) # update case from same user my_change = CaseBlock( create=False, date_modified=time, case_id=case_id, user_id=USER_ID, version=V2, update={'greeting': 'hello'} ).as_xml(format_datetime=json_format_datetime) self._postFakeWithSyncToken( my_change, self.sync_log.get_id ) # update from another user their_change = CaseBlock( create=False, date_modified=time, case_id=case_id, user_id=USER_ID, version=V2, update={'greeting_2': 'hello'} ).as_xml(format_datetime=json_format_datetime) self._postFakeWithSyncToken( their_change, self.other_sync_log.get_id ) # original user syncs again # make sure updates both appear (and merge?) joint_change = CaseBlock( create=False, date_modified=time, case_id=case_id, user_id=USER_ID, version=V2, update={ 'greeting': 'hello', 'greeting_2': 'hello' }, owner_id=SHARED_ID, case_name='', case_type='mother', ).as_xml(format_datetime=json_format_datetime) check_user_has_case(self, self.user, joint_change, restore_id=self.sync_log.get_id, version=V2) check_user_has_case(self, self.other_user, joint_change, restore_id=self.other_sync_log.get_id, version=V2)
def setUp(self): super(SyncPerformanceTest, self).setUp() # the other user is an "owner" of the original users cases as well, # for convenience self.project = Domain(name='sync-performance-tests') self.project.save() self.factory.domain = self.project.name self.other_user = create_restore_user( domain=self.project.name, username=OTHER_USERNAME, ) self.referral_user = create_restore_user( domain=self.project.name, username=REFERRAL_USERNAME, ) self.shared_group = Group( domain=self.project.name, name='shared_group', case_sharing=True, users=[self.other_user.user_id, self.user.user_id] ) self.shared_group.save() self.referral_group = Group( domain=self.project.name, name='referral_group', case_sharing=True, users=[self.referral_user.user_id] ) self.referral_group.save() # this creates the initial blank sync token in the database self.other_sync_log = synclog_from_restore_payload(generate_restore_payload( self.project, self.other_user )) self.referral_sync_log = synclog_from_restore_payload(generate_restore_payload( self.project, self.referral_user )) self.assertTrue(self.shared_group._id in self.other_sync_log.owner_ids_on_phone) self.assertTrue(self.other_user.user_id in self.other_sync_log.owner_ids_on_phone) self.sync_log = synclog_from_restore_payload(generate_restore_payload( self.project, self.user )) self.assertTrue(self.shared_group._id in self.sync_log.owner_ids_on_phone) self.assertTrue(self.user.user_id in self.sync_log.owner_ids_on_phone)
def setUp(self): super(SyncPerformanceTest, self).setUp() # the other user is an "owner" of the original users cases as well, # for convenience self.project = Domain(name='sync-performance-tests') self.project.save() self.factory.domain = self.project.name self.other_user = create_restore_user( domain=self.project.name, username=OTHER_USERNAME, ) self.referral_user = create_restore_user( domain=self.project.name, username=REFERRAL_USERNAME, ) self.shared_group = Group( domain=self.project.name, name='shared_group', case_sharing=True, users=[self.other_user.user_id, self.user.user_id]) self.shared_group.save() self.referral_group = Group(domain=self.project.name, name='referral_group', case_sharing=True, users=[self.referral_user.user_id]) self.referral_group.save() # this creates the initial blank sync token in the database self.other_sync_log = synclog_from_restore_payload( generate_restore_payload(self.project, self.other_user)) self.referral_sync_log = synclog_from_restore_payload( generate_restore_payload(self.project, self.referral_user)) self.assertTrue( self.shared_group._id in self.other_sync_log.owner_ids_on_phone) self.assertTrue( self.other_user.user_id in self.other_sync_log.owner_ids_on_phone) self.sync_log = synclog_from_restore_payload( generate_restore_payload(self.project, self.user)) self.assertTrue( self.shared_group._id in self.sync_log.owner_ids_on_phone) self.assertTrue(self.user.user_id in self.sync_log.owner_ids_on_phone)
def setUp(self): super(MultiUserSyncTest, self).setUp() # the other user is an "owner" of the original users cases as well, # for convenience self.other_user = User(user_id=OTHER_USER_ID, username="******", password="******", date_joined=datetime(2011, 6, 9), additional_owner_ids=[SHARED_ID]) # this creates the initial blank sync token in the database self.other_sync_log = synclog_from_restore_payload(generate_restore_payload(self.other_user)) self.assertTrue(SHARED_ID in self.other_sync_log.owner_ids_on_phone) self.assertTrue(OTHER_USER_ID in self.other_sync_log.owner_ids_on_phone) self.user.additional_owner_ids = [SHARED_ID] self.sync_log = synclog_from_restore_payload(generate_restore_payload(self.user)) self.assertTrue(SHARED_ID in self.sync_log.owner_ids_on_phone) self.assertTrue(USER_ID in self.sync_log.owner_ids_on_phone)
def test_new_then_old_sync(self): OWNERSHIP_CLEANLINESS_RESTORE.set(self.domain, enabled=True, namespace="domain") restore_config = RestoreConfig(self.project, user=self.user) sync_log = synclog_from_restore_payload(restore_config.get_payload().as_string()) self.assertEqual(SimplifiedSyncLog, type(sync_log)) OWNERSHIP_CLEANLINESS_RESTORE.set(self.domain, enabled=False, namespace="domain") restore_config = RestoreConfig(self.project, user=self.user, params=RestoreParams(sync_log_id=sync_log._id)) with self.assertRaises(IncompatibleSyncLogType): restore_config.get_payload()
def testCaching(self): self.assertFalse(self.sync_log.has_cached_payload(V2)) # first request should populate the cache original_payload = RestoreConfig( self.user, version=V2, caching_enabled=True, restore_id=self.sync_log._id, ).get_payload() next_sync_log = synclog_from_restore_payload(original_payload) self.sync_log = SyncLog.get(self.sync_log._id) self.assertTrue(self.sync_log.has_cached_payload(V2)) # a second request with the same config should be exactly the same cached_payload = RestoreConfig( self.user, version=V2, caching_enabled=True, restore_id=self.sync_log._id, ).get_payload() self.assertEqual(original_payload, cached_payload) # a second request without caching should be different (generate a new id) uncached_payload = RestoreConfig( self.user, version=V2, caching_enabled=False, restore_id=self.sync_log._id, ).get_payload() self.assertNotEqual(original_payload, uncached_payload) uncached_sync_log = synclog_from_restore_payload(uncached_payload) self.assertNotEqual(next_sync_log._id, uncached_sync_log._id) # caching a different version should also produce something new versioned_payload = RestoreConfig( self.user, version=V1, caching_enabled=True, restore_id=self.sync_log._id, ).get_payload() self.assertNotEqual(original_payload, versioned_payload) versioned_sync_log = synclog_from_restore_payload(versioned_payload) self.assertNotEqual(next_sync_log._id, versioned_sync_log._id)
def setUp(self): delete_all_cases() delete_all_xforms() delete_all_sync_logs() self.user = User(user_id=USER_ID, username="******", password="******", date_joined=datetime(2011, 6, 9)) # this creates the initial blank sync token in the database restore_config = RestoreConfig(self.user) self.sync_log = synclog_from_restore_payload(restore_config.get_payload())
def test_legacy_support_toggle(self): restore_config = RestoreConfig(self.project, 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() self.assertTrue(child_id in restore_payload) self.assertTrue(parent_id in restore_payload) sync_log = 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="domain") request = JsonObject(domain=self.domain) 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_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() self.assertTrue(child_id in restore_payload) self.assertTrue(parent_id in restore_payload) sync_log = 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='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 testComplicatedGatesBug(self): # found this bug in the wild, used the real (test) forms to fix it # just running through this test used to fail hard, even though there # are no asserts self.assertEqual(0, len(CommCareCase.view("case/by_user", reduce=False).all())) folder_path = os.path.join("bugs", "dependent_case_conflicts") files = ["reg1.xml", "reg2.xml", "cf.xml", "close.xml"] for f in files: form = self._postWithSyncToken(os.path.join(folder_path, f), self.sync_log.get_id) form = XFormInstance.get(form.get_id) self.assertFalse(hasattr(form, "problem")) self.sync_log = synclog_from_restore_payload(generate_restore_payload(self.user, version="2.0"))
def test_old_then_new_sync(self): restore_config = RestoreConfig(self.project, user=self.user) case = CaseFactory(domain=self.project.name, case_defaults={'owner_id': self.user_id}).create_case() restore_payload = restore_config.get_payload().as_string() self.assertTrue(case._id in restore_payload) sync_log = synclog_from_restore_payload(restore_payload) self.assertEqual(SyncLog, type(sync_log)) restore_config = RestoreConfig(self.project, user=self.user, params=RestoreParams(sync_log_id=sync_log._id)) original_payload_back = restore_config.get_payload().as_string() self.assertFalse(case._id in original_payload_back) self.assertEqual(SyncLog, type(synclog_from_restore_payload(original_payload_back))) OWNERSHIP_CLEANLINESS_RESTORE.set(self.domain, enabled=True, namespace='domain') restore_config = RestoreConfig(self.project, user=self.user, params=RestoreParams(sync_log_id=sync_log._id), cache_settings=RestoreCacheSettings(overwrite_cache=True)) migrated_payload_back = restore_config.get_payload().as_string() self.assertFalse(case._id in migrated_payload_back) self.assertEqual(SimplifiedSyncLog, type(synclog_from_restore_payload(migrated_payload_back))) OWNERSHIP_CLEANLINESS_RESTORE.set(self.domain, enabled=False, namespace='domain')
def setUp(self): delete_all_cases() delete_all_xforms() delete_all_sync_logs() self.user = User(user_id=USER_ID, username="******", password="******", date_joined=datetime(2011, 6, 9)) # this creates the initial blank sync token in the database restore_config = RestoreConfig(self.user) self.sync_log = synclog_from_restore_payload( restore_config.get_payload())
def setUp(self): super(MultiUserSyncTest, self).setUp() # the other user is an "owner" of the original users cases as well, # for convenience self.other_user = User(user_id=OTHER_USER_ID, username="******", password="******", date_joined=datetime(2011, 6, 9), additional_owner_ids=[SHARED_ID]) # this creates the initial blank sync token in the database self.other_sync_log = synclog_from_restore_payload( generate_restore_payload(self.other_user)) self.assertTrue(SHARED_ID in self.other_sync_log.owner_ids_on_phone) self.assertTrue( OTHER_USER_ID in self.other_sync_log.owner_ids_on_phone) self.user.additional_owner_ids = [SHARED_ID] self.sync_log = synclog_from_restore_payload( generate_restore_payload(self.user)) self.assertTrue(SHARED_ID in self.sync_log.owner_ids_on_phone) self.assertTrue(USER_ID in self.sync_log.owner_ids_on_phone)
def testComplicatedGatesBug(self): # found this bug in the wild, used the real (test) forms to fix it # just running through this test used to fail hard, even though there # are no asserts self.assertEqual( 0, len(CommCareCase.view("case/by_user", reduce=False).all())) folder_path = os.path.join("bugs", "dependent_case_conflicts") files = ["reg1.xml", "reg2.xml", "cf.xml", "close.xml"] for f in files: form = self._postWithSyncToken(os.path.join(folder_path, f), self.sync_log.get_id) form = XFormInstance.get(form.get_id) self.assertFalse(hasattr(form, "problem")) self.sync_log = synclog_from_restore_payload( generate_restore_payload(self.user, version="2.0"))
def test_new_then_old_sync(self): OWNERSHIP_CLEANLINESS_RESTORE.set(self.domain, enabled=True, namespace='domain') restore_config = RestoreConfig(self.project, user=self.user) sync_log = synclog_from_restore_payload( restore_config.get_payload().as_string()) self.assertEqual(SimplifiedSyncLog, type(sync_log)) OWNERSHIP_CLEANLINESS_RESTORE.set(self.domain, enabled=False, namespace='domain') restore_config = RestoreConfig( self.project, user=self.user, params=RestoreParams(sync_log_id=sync_log._id)) with self.assertRaises(IncompatibleSyncLogType): restore_config.get_payload()
def testOtherUserCloses(self): # create a case from one user case_id = "other_user_closes" self._createCaseStubs([case_id], owner_id=SHARED_ID) # sync then close case from another user self.other_sync_log = synclog_from_restore_payload( generate_restore_payload(self.other_user)) close_block = CaseBlock(create=False, case_id=case_id, user_id=USER_ID, version=V2, close=True).as_xml() self._postFakeWithSyncToken(close_block, self.other_sync_log.get_id) # original user syncs again # make sure close block appears assert_user_has_case(self, self.user, case_id, restore_id=self.sync_log.get_id)
def testOtherUserCloses(self): # create a case from one user case_id = "other_user_closes" self._createCaseStubs([case_id], owner_id=SHARED_ID) # sync then close case from another user self.other_sync_log = synclog_from_restore_payload(generate_restore_payload(self.other_user)) close_block = CaseBlock( create=False, case_id=case_id, user_id=USER_ID, version=V2, close=True ).as_xml() self._postFakeWithSyncToken( close_block, self.other_sync_log.get_id ) # original user syncs again # make sure close block appears assert_user_has_case(self, self.user, case_id, restore_id=self.sync_log.get_id)
def testUserLoggedIntoMultipleDevices(self): # test that a child case created by the same user from a different device # gets included in the sync parent_id = "parent" child_id = "child" self._createCaseStubs([parent_id]) # create child case using a different sync log ID other_sync_log = synclog_from_restore_payload(generate_restore_payload(self.user, version="2.0")) child = CaseBlock( create=True, case_id=child_id, user_id=USER_ID, owner_id=USER_ID, version=V2, index={'mother': ('mother', parent_id)} ).as_xml() self._postFakeWithSyncToken(child, other_sync_log.get_id) # ensure child case is included in sync using original sync log ID assert_user_has_case(self, self.user, child_id, restore_id=self.sync_log.get_id)
def testOtherUserReassignsIndexed(self): # create a parent and child case (with index) from one user parent_id = "other_reassigns_index_parent" case_id = "other_reassigns_index_child" self._createCaseStubs([parent_id]) child = CaseBlock( create=True, case_id=case_id, user_id=USER_ID, owner_id=SHARED_ID, version=V2, index={'mother': ('mother', parent_id)} ).as_xml() self._postFakeWithSyncToken(child, self.sync_log.get_id) # assign the parent case away from the same user parent_update = CaseBlock( create=False, case_id=parent_id, user_id=USER_ID, owner_id=OTHER_USER_ID, update={"greeting": "hello"}, version=V2).as_xml() self._postFakeWithSyncToken(parent_update, self.sync_log.get_id) # sync cases to second user self.other_sync_log = synclog_from_restore_payload(generate_restore_payload(self.other_user)) # change the child's owner from another user child_reassignment = CaseBlock( create=False, case_id=case_id, user_id=OTHER_USER_ID, owner_id=OTHER_USER_ID, version=V2, update={"childgreeting": "hi!"}, ).as_xml() self._postFakeWithSyncToken(child_reassignment, self.other_sync_log.get_id) # also change the parent from the second user other_parent_update = CaseBlock( create=False, case_id=parent_id, user_id=OTHER_USER_ID, owner_id=OTHER_USER_ID, update={"other_greeting": "something new"}, version=V2).as_xml() self._postFakeWithSyncToken(other_parent_update, self.other_sync_log.get_id) # original user syncs again self.sync_log = SyncLog.last_for_user(self.user.user_id) # both cases should sync to original user with updated ownership / edits assert_user_has_case(self, self.user, case_id, restore_id=self.sync_log.get_id) assert_user_has_case(self, self.user, parent_id, restore_id=self.sync_log.get_id) # Ghetto payload = generate_restore_payload(self.user, self.sync_log.get_id, version=V2) self.assertTrue("something new" in payload) self.assertTrue("hi!" in payload) # change the parent again from the second user other_parent_update = CaseBlock( create=False, case_id=parent_id, user_id=OTHER_USER_ID, owner_id=OTHER_USER_ID, update={"other_greeting": "something different"}, version=V2).as_xml() self._postFakeWithSyncToken(other_parent_update, self.other_sync_log.get_id) # original user syncs again self.sync_log = SyncLog.last_for_user(self.user.user_id) # should be no changes assert_user_doesnt_have_case(self, self.user, case_id, restore_id=self.sync_log.get_id) assert_user_doesnt_have_case(self, self.user, parent_id, restore_id=self.sync_log.get_id) # change the child again from the second user other_child_update = CaseBlock( create=False, case_id=case_id, user_id=OTHER_USER_ID, owner_id=OTHER_USER_ID, version=V2, update={"childgreeting": "hi changed!"}, ).as_xml() self._postFakeWithSyncToken(other_child_update, self.other_sync_log.get_id) # original user syncs again self.sync_log = SyncLog.last_for_user(self.user.user_id) # should be no changes assert_user_doesnt_have_case(self, self.user, case_id, restore_id=self.sync_log.get_id) assert_user_doesnt_have_case(self, self.user, parent_id, restore_id=self.sync_log.get_id) # change owner of child back to orginal user from second user child_reassignment = CaseBlock( create=False, case_id=case_id, user_id=OTHER_USER_ID, owner_id=USER_ID, version=V2 ).as_xml() self._postFakeWithSyncToken(child_reassignment, self.other_sync_log.get_id) # original user syncs again self.sync_log = SyncLog.last_for_user(self.user.user_id) # both cases should now sync assert_user_has_case(self, self.user, case_id, restore_id=self.sync_log.get_id) assert_user_has_case(self, self.user, parent_id, restore_id=self.sync_log.get_id) # ghetto payload = generate_restore_payload(self.user, self.sync_log.get_id, version=V2) self.assertTrue("something different" in payload) self.assertTrue("hi changed!" in payload)
def testMultiUserEdits(self): time = datetime.now() # create a case from one user case_id = "multi_user_edits" self._createCaseStubs([case_id], owner_id=SHARED_ID) # both users syncs self.sync_log = synclog_from_restore_payload( generate_restore_payload(self.user)) self.other_sync_log = synclog_from_restore_payload( generate_restore_payload(self.other_user)) # update case from same user my_change = CaseBlock(create=False, date_modified=time, case_id=case_id, user_id=USER_ID, version=V2, update={ 'greeting': 'hello' }).as_xml(format_datetime=json_format_datetime) self._postFakeWithSyncToken(my_change, self.sync_log.get_id) # update from another user their_change = CaseBlock( create=False, date_modified=time, case_id=case_id, user_id=USER_ID, version=V2, update={ 'greeting_2': 'hello' }).as_xml(format_datetime=json_format_datetime) self._postFakeWithSyncToken(their_change, self.other_sync_log.get_id) # original user syncs again # make sure updates both appear (and merge?) joint_change = CaseBlock( create=False, date_modified=time, case_id=case_id, user_id=USER_ID, version=V2, update={ 'greeting': 'hello', 'greeting_2': 'hello' }, owner_id=SHARED_ID, case_name='', case_type='mother', ).as_xml(format_datetime=json_format_datetime) check_user_has_case(self, self.user, joint_change, restore_id=self.sync_log.get_id, version=V2) check_user_has_case(self, self.other_user, joint_change, restore_id=self.other_sync_log.get_id, version=V2)
def testOtherUserReassignsIndexed(self): # create a parent and child case (with index) from one user parent_id = "other_reassigns_index_parent" case_id = "other_reassigns_index_child" self._createCaseStubs([parent_id]) child = CaseBlock(create=True, case_id=case_id, user_id=USER_ID, owner_id=SHARED_ID, version=V2, index={ 'mother': ('mother', parent_id) }).as_xml() self._postFakeWithSyncToken(child, self.sync_log.get_id) # assign the parent case away from the same user parent_update = CaseBlock(create=False, case_id=parent_id, user_id=USER_ID, owner_id=OTHER_USER_ID, update={ "greeting": "hello" }, version=V2).as_xml() self._postFakeWithSyncToken(parent_update, self.sync_log.get_id) # sync cases to second user self.other_sync_log = synclog_from_restore_payload( generate_restore_payload(self.other_user)) # change the child's owner from another user child_reassignment = CaseBlock( create=False, case_id=case_id, user_id=OTHER_USER_ID, owner_id=OTHER_USER_ID, version=V2, update={ "childgreeting": "hi!" }, ).as_xml() self._postFakeWithSyncToken(child_reassignment, self.other_sync_log.get_id) # also change the parent from the second user other_parent_update = CaseBlock(create=False, case_id=parent_id, user_id=OTHER_USER_ID, owner_id=OTHER_USER_ID, update={ "other_greeting": "something new" }, version=V2).as_xml() self._postFakeWithSyncToken(other_parent_update, self.other_sync_log.get_id) # original user syncs again self.sync_log = SyncLog.last_for_user(self.user.user_id) # both cases should sync to original user with updated ownership / edits assert_user_has_case(self, self.user, case_id, restore_id=self.sync_log.get_id) assert_user_has_case(self, self.user, parent_id, restore_id=self.sync_log.get_id) # Ghetto payload = generate_restore_payload(self.user, self.sync_log.get_id, version=V2) self.assertTrue("something new" in payload) self.assertTrue("hi!" in payload) # change the parent again from the second user other_parent_update = CaseBlock(create=False, case_id=parent_id, user_id=OTHER_USER_ID, owner_id=OTHER_USER_ID, update={ "other_greeting": "something different" }, version=V2).as_xml() self._postFakeWithSyncToken(other_parent_update, self.other_sync_log.get_id) # original user syncs again self.sync_log = SyncLog.last_for_user(self.user.user_id) # should be no changes assert_user_doesnt_have_case(self, self.user, case_id, restore_id=self.sync_log.get_id) assert_user_doesnt_have_case(self, self.user, parent_id, restore_id=self.sync_log.get_id) # change the child again from the second user other_child_update = CaseBlock( create=False, case_id=case_id, user_id=OTHER_USER_ID, owner_id=OTHER_USER_ID, version=V2, update={ "childgreeting": "hi changed!" }, ).as_xml() self._postFakeWithSyncToken(other_child_update, self.other_sync_log.get_id) # original user syncs again self.sync_log = SyncLog.last_for_user(self.user.user_id) # should be no changes assert_user_doesnt_have_case(self, self.user, case_id, restore_id=self.sync_log.get_id) assert_user_doesnt_have_case(self, self.user, parent_id, restore_id=self.sync_log.get_id) # change owner of child back to orginal user from second user child_reassignment = CaseBlock(create=False, case_id=case_id, user_id=OTHER_USER_ID, owner_id=USER_ID, version=V2).as_xml() self._postFakeWithSyncToken(child_reassignment, self.other_sync_log.get_id) # original user syncs again self.sync_log = SyncLog.last_for_user(self.user.user_id) # both cases should now sync assert_user_has_case(self, self.user, case_id, restore_id=self.sync_log.get_id) assert_user_has_case(self, self.user, parent_id, restore_id=self.sync_log.get_id) # ghetto payload = generate_restore_payload(self.user, self.sync_log.get_id, version=V2) self.assertTrue("something different" in payload) self.assertTrue("hi changed!" in payload)