<s> import uuid <EOL> from xml . etree import ElementTree <EOL> from couchdbkit import ResourceNotFound <EOL> from django . test . utils import override_settings <EOL> from django . test import TestCase <EOL> import os <EOL> from casexml . apps . case . util import post_case_blocks <EOL> from casexml . apps . phone . exceptions import MissingSyncLog , RestoreException <EOL> from casexml . apps . phone . tests . utils import get_exactly_one_wrapped_sync_log , generate_restore_payload <EOL> from casexml . apps . case . mock import CaseBlock , CaseFactory , CaseStructure , CaseIndex <EOL> from casexml . apps . phone . tests . utils import synclog_from_restore_payload , get_restore_config <EOL> from casexml . apps . phone . models import OwnershipCleanlinessFlag <EOL> from corehq . apps . domain . models import Domain <EOL> from corehq . apps . receiverwrapper import submit_form_locally <EOL> from corehq . form_processor . interfaces . dbaccessors import CaseAccessors <EOL> from corehq . form_processor . tests . utils import FormProcessorTestUtils , run_with_all_backends <EOL> from corehq . toggles import LOOSE_SYNC_TOKEN_VALIDATION <EOL> from corehq . util . test_utils import flag_enabled <EOL> from casexml . apps . case . tests . util import ( <EOL> check_user_has_case , assert_user_doesnt_have_case , <EOL> assert_user_has_case , TEST_DOMAIN_NAME , assert_user_has_cases ) <EOL> from casexml . apps . phone . models import SyncLog , User , get_properly_wrapped_sync_log , SimplifiedSyncLog , AbstractSyncLog <EOL> from casexml . apps . phone . restore import CachedResponse , RestoreConfig , RestoreParams , RestoreCacheSettings <EOL> from casexml . apps . case . xml import V2 , V1 <EOL> from casexml . apps . case . sharedmodels import CommCareCaseIndex <EOL> from datetime import datetime <EOL> USER_ID = "<STR_LIT>" <EOL> USERNAME = "<STR_LIT>" <EOL> OTHER_USER_ID = "<STR_LIT>" <EOL> OTHER_USERNAME = "<STR_LIT>" <EOL> SHARED_ID = "<STR_LIT>" <EOL> PARENT_TYPE = "<STR_LIT>" <EOL> CHILD_RELATIONSHIP = "<STR_LIT>" <EOL> @ override_settings ( CASEXML_FORCE_DOMAIN_CHECK = False ) <EOL> class SyncBaseTest ( TestCase ) : <EOL> """<STR_LIT>""" <EOL> def setUp ( self ) : <EOL> FormProcessorTestUtils . delete_all_cases ( ) <EOL> FormProcessorTestUtils . delete_all_xforms ( ) <EOL> FormProcessorTestUtils . delete_all_sync_logs ( ) <EOL> self . project = Domain ( name = TEST_DOMAIN_NAME ) <EOL> self . user = User ( user_id = USER_ID , username = USERNAME , <EOL> password = "<STR_LIT>" , date_joined = datetime ( <NUM_LIT> , <NUM_LIT:6> , <NUM_LIT:9> ) ) <EOL> restore_config = RestoreConfig ( self . project , user = self . user , <EOL> cache_settings = RestoreCacheSettings ( overwrite_cache = True ) ) <EOL> self . sync_log = synclog_from_restore_payload ( restore_config . get_payload ( ) . as_string ( ) ) <EOL> self . factory = CaseFactory ( <EOL> case_defaults = { <EOL> '<STR_LIT>' : USER_ID , <EOL> '<STR_LIT>' : USER_ID , <EOL> '<STR_LIT>' : PARENT_TYPE , <EOL> } , <EOL> form_extras = { <EOL> '<STR_LIT>' : self . sync_log . _id <EOL> } <EOL> ) <EOL> def tearDown ( self ) : <EOL> restore_config = RestoreConfig ( project = self . project , user = self . user ) <EOL> restore_config . cache . delete ( restore_config . _initial_cache_key ( ) ) <EOL> def _createCaseStubs ( self , id_list , ** kwargs ) : <EOL> case_attrs = { '<STR_LIT>' : True } <EOL> case_attrs . update ( kwargs ) <EOL> return self . factory . create_or_update_cases ( <EOL> [ CaseStructure ( case_id = case_id , attrs = case_attrs ) for case_id in id_list ] , <EOL> ) <EOL> def _postWithSyncToken ( self , filename , token_id ) : <EOL> file_path = os . path . join ( os . path . dirname ( __file__ ) , "<STR_LIT:data>" , filename ) <EOL> with open ( file_path , "<STR_LIT:rb>" ) as f : <EOL> xml_data = f . read ( ) <EOL> _ , form , _ = submit_form_locally ( xml_data , '<STR_LIT>' , last_sync_token = token_id ) <EOL> return form <EOL> def _postFakeWithSyncToken ( self , caseblocks , token_id ) : <EOL> if not isinstance ( caseblocks , list ) : <EOL> caseblocks = [ caseblocks ] <EOL> return post_case_blocks ( caseblocks , form_extras = { "<STR_LIT>" : token_id } ) <EOL> def _checkLists ( self , l1 , l2 , msg = None ) : <EOL> self . assertEqual ( set ( l1 ) , set ( l2 ) , msg ) <EOL> def _testUpdate ( self , sync_log_or_id , case_id_map , dependent_case_id_map = None ) : <EOL> dependent_case_id_map = dependent_case_id_map or { } <EOL> if isinstance ( sync_log_or_id , AbstractSyncLog ) : <EOL> sync_log = sync_log_or_id <EOL> else : <EOL> sync_log = get_properly_wrapped_sync_log ( sync_log_or_id ) <EOL> if isinstance ( sync_log , SimplifiedSyncLog ) : <EOL> all_ids = { } <EOL> all_ids . update ( case_id_map ) <EOL> all_ids . update ( dependent_case_id_map ) <EOL> self . assertEqual ( set ( all_ids ) , sync_log . case_ids_on_phone ) <EOL> self . assertEqual ( set ( dependent_case_id_map . keys ( ) ) , sync_log . dependent_case_ids_on_phone ) <EOL> for case_id , indices in case_id_map . items ( ) : <EOL> if indices : <EOL> index_ids = [ i . referenced_id for i in case_id_map [ case_id ] ] <EOL> self . _checkLists ( index_ids , sync_log . index_tree . indices [ case_id ] . values ( ) , <EOL> '<STR_LIT>' . format ( case_id ) ) <EOL> for case_id , indices in dependent_case_id_map . items ( ) : <EOL> if indices : <EOL> index_ids = [ i . referenced_id for i in case_id_map [ case_id ] ] <EOL> self . _checkLists ( index_ids , sync_log . index_tree . indices [ case_id ] . values ( ) ) <EOL> else : <EOL> self . assertEqual ( len ( case_id_map ) , len ( sync_log . cases_on_phone ) ) <EOL> for case_id , indices in case_id_map . items ( ) : <EOL> self . assertTrue ( sync_log . phone_has_case ( case_id ) ) <EOL> state = sync_log . get_case_state ( case_id ) <EOL> self . _checkLists ( indices , state . indices ) <EOL> self . assertEqual ( len ( dependent_case_id_map ) , len ( sync_log . dependent_cases_on_phone ) ) <EOL> for case_id , indices in dependent_case_id_map . items ( ) : <EOL> self . assertTrue ( sync_log . phone_has_dependent_case ( case_id ) ) <EOL> state = sync_log . get_dependent_case_state ( case_id ) <EOL> self . _checkLists ( indices , state . indices ) <EOL> migrated_sync_log = SimplifiedSyncLog . from_other_format ( sync_log ) <EOL> self . assertEqual ( sync_log . get_state_hash ( ) , migrated_sync_log . get_state_hash ( ) ) <EOL> self . _testUpdate ( migrated_sync_log , case_id_map , dependent_case_id_map ) <EOL> class SyncTokenUpdateTest ( SyncBaseTest ) : <EOL> """<STR_LIT>""" <EOL> @ run_with_all_backends <EOL> def testInitialEmpty ( self ) : <EOL> """<STR_LIT>""" <EOL> sync_log = get_exactly_one_wrapped_sync_log ( ) <EOL> self . _testUpdate ( sync_log . get_id , { } , { } ) <EOL> @ run_with_all_backends <EOL> def testOwnUpdatesDontSync ( self ) : <EOL> case_id = "<STR_LIT>" <EOL> self . _createCaseStubs ( [ case_id ] ) <EOL> assert_user_doesnt_have_case ( self , self . user , case_id , restore_id = self . sync_log . get_id ) <EOL> self . factory . create_or_update_case ( <EOL> CaseStructure ( case_id = case_id , attrs = { '<STR_LIT>' : { "<STR_LIT>" : "<STR_LIT:hello>" } } ) , <EOL> ) <EOL> assert_user_doesnt_have_case ( self , self . user , case_id , restore_id = self . sync_log . get_id ) <EOL> self . factory . create_or_update_case ( <EOL> CaseStructure ( case_id = case_id , attrs = { '<STR_LIT>' : OTHER_USER_ID } ) , <EOL> ) <EOL> assert_user_doesnt_have_case ( self , self . user , case_id , restore_id = self . sync_log . get_id ) <EOL> @ run_with_all_backends <EOL> def test_change_index_type ( self ) : <EOL> """<STR_LIT>""" <EOL> child_id , parent_id , index_id , parent_ref = self . _initialize_parent_child ( ) <EOL> updated_type = "<STR_LIT>" <EOL> child = CaseBlock ( <EOL> create = False , case_id = child_id , user_id = USER_ID , <EOL> index = { index_id : ( updated_type , parent_id ) } , <EOL> ) . as_xml ( ) <EOL> self . _postFakeWithSyncToken ( child , self . sync_log . get_id ) <EOL> parent_ref . referenced_type = updated_type <EOL> self . _testUpdate ( self . sync_log . get_id , { parent_id : [ ] , <EOL> child_id : [ parent_ref ] } ) <EOL> @ run_with_all_backends <EOL> def test_change_index_id ( self ) : <EOL> """<STR_LIT>""" <EOL> child_id , parent_id , index_id , parent_ref = self . _initialize_parent_child ( ) <EOL> updated_id = '<STR_LIT>' <EOL> self . factory . create_or_update_case ( CaseStructure ( <EOL> case_id = child_id , <EOL> indices = [ CaseIndex ( <EOL> CaseStructure ( case_id = updated_id , attrs = { '<STR_LIT>' : True } ) , <EOL> relationship = CHILD_RELATIONSHIP , <EOL> related_type = PARENT_TYPE , <EOL> identifier = index_id , <EOL> ) ] , <EOL> ) ) <EOL> parent_ref . referenced_id = updated_id <EOL> self . _testUpdate ( self . sync_log . get_id , { parent_id : [ ] , updated_id : [ ] , <EOL> child_id : [ parent_ref ] } ) <EOL> @ run_with_all_backends <EOL> def test_add_multiple_indices ( self ) : <EOL> """<STR_LIT>""" <EOL> child_id , parent_id , index_id , parent_ref = self . _initialize_parent_child ( ) <EOL> new_case_id = '<STR_LIT>' <EOL> new_index_identifier = '<STR_LIT>' <EOL> self . factory . create_or_update_case ( CaseStructure ( <EOL> case_id = child_id , <EOL> indices = [ CaseIndex ( <EOL> CaseStructure ( case_id = new_case_id , attrs = { '<STR_LIT>' : True } ) , <EOL> relationship = CHILD_RELATIONSHIP , <EOL> related_type = PARENT_TYPE , <EOL> identifier = new_index_identifier , <EOL> ) ] , <EOL> ) ) <EOL> new_index_ref = CommCareCaseIndex ( identifier = new_index_identifier , referenced_type = PARENT_TYPE , <EOL> referenced_id = new_case_id ) <EOL> self . _testUpdate ( self . sync_log . get_id , { parent_id : [ ] , new_case_id : [ ] , <EOL> child_id : [ parent_ref , new_index_ref ] } ) <EOL> @ run_with_all_backends <EOL> def test_delete_only_index ( self ) : <EOL> child_id , parent_id , index_id , parent_ref = self . _initialize_parent_child ( ) <EOL> child = CaseBlock ( create = False , case_id = child_id , user_id = USER_ID , <EOL> index = { index_id : ( PARENT_TYPE , "<STR_LIT>" ) } , <EOL> ) . as_xml ( ) <EOL> self . _postFakeWithSyncToken ( child , self . sync_log . get_id ) <EOL> self . _testUpdate ( self . sync_log . get_id , { parent_id : [ ] , child_id : [ ] } ) <EOL> @ run_with_all_backends <EOL> def test_delete_one_of_multiple_indices ( self ) : <EOL> uid = uuid . uuid4 ( ) . hex <EOL> child_id = '<STR_LIT>' . format ( uid ) <EOL> parent_id_1 = '<STR_LIT>' . format ( uid ) <EOL> index_id_1 = '<STR_LIT>' . format ( uid ) <EOL> parent_id_2 = '<STR_LIT>' . format ( uid ) <EOL> index_id_2 = '<STR_LIT>' . format ( uid ) <EOL> self . factory . create_or_update_case ( CaseStructure ( <EOL> case_id = child_id , <EOL> attrs = { '<STR_LIT>' : True } , <EOL> indices = [ <EOL> CaseIndex ( <EOL> CaseStructure ( case_id = parent_id_1 , attrs = { '<STR_LIT>' : True } ) , <EOL> relationship = CHILD_RELATIONSHIP , <EOL> related_type = PARENT_TYPE , <EOL> identifier = index_id_1 , <EOL> ) , <EOL> CaseIndex ( <EOL> CaseStructure ( case_id = parent_id_2 , attrs = { '<STR_LIT>' : True } ) , <EOL> relationship = CHILD_RELATIONSHIP , <EOL> related_type = PARENT_TYPE , <EOL> identifier = index_id_2 , <EOL> ) , <EOL> ] , <EOL> ) ) <EOL> parent_ref_1 = CommCareCaseIndex ( <EOL> identifier = index_id_1 , referenced_type = PARENT_TYPE , referenced_id = parent_id_1 ) <EOL> parent_ref_2 = CommCareCaseIndex ( <EOL> identifier = index_id_2 , referenced_type = PARENT_TYPE , referenced_id = parent_id_2 ) <EOL> self . _testUpdate ( self . sync_log . get_id , { parent_id_1 : [ ] , parent_id_2 : [ ] , <EOL> child_id : [ parent_ref_1 , parent_ref_2 ] } ) <EOL> child = CaseBlock ( create = False , case_id = child_id , user_id = USER_ID , <EOL> index = { index_id_1 : ( PARENT_TYPE , "<STR_LIT>" ) } , <EOL> ) . as_xml ( ) <EOL> self . _postFakeWithSyncToken ( child , self . sync_log . get_id ) <EOL> self . _testUpdate ( self . sync_log . get_id , { parent_id_1 : [ ] , parent_id_2 : [ ] , <EOL> child_id : [ parent_ref_2 ] } ) <EOL> def _initialize_parent_child ( self ) : <EOL> child_id = "<STR_LIT>" <EOL> parent_id = "<STR_LIT>" <EOL> index_id = '<STR_LIT>' <EOL> self . factory . create_or_update_case ( CaseStructure ( <EOL> case_id = child_id , <EOL> attrs = { '<STR_LIT>' : True } , <EOL> indices = [ CaseIndex ( <EOL> CaseStructure ( case_id = parent_id , attrs = { '<STR_LIT>' : True } ) , <EOL> relationship = CHILD_RELATIONSHIP , <EOL> related_type = PARENT_TYPE , <EOL> identifier = index_id , <EOL> ) ] , <EOL> ) ) <EOL> parent_ref = CommCareCaseIndex ( identifier = index_id , referenced_type = PARENT_TYPE , referenced_id = parent_id ) <EOL> self . _testUpdate ( self . sync_log . get_id , { parent_id : [ ] , child_id : [ parent_ref ] } ) <EOL> return ( child_id , parent_id , index_id , parent_ref ) <EOL> @ run_with_all_backends <EOL> def testClosedParentIndex ( self ) : <EOL> """<STR_LIT>""" <EOL> parent_id = "<STR_LIT>" <EOL> child_id = "<STR_LIT>" <EOL> index_id = '<STR_LIT>' <EOL> self . factory . create_or_update_cases ( [ <EOL> CaseStructure ( <EOL> case_id = child_id , <EOL> attrs = { '<STR_LIT>' : True } , <EOL> indices = [ CaseIndex ( <EOL> CaseStructure ( case_id = parent_id , attrs = { '<STR_LIT>' : True } ) , <EOL> relationship = CHILD_RELATIONSHIP , <EOL> related_type = PARENT_TYPE , <EOL> identifier = index_id , <EOL> ) ] , <EOL> ) <EOL> ] ) <EOL> index_ref = CommCareCaseIndex ( identifier = index_id , <EOL> referenced_type = PARENT_TYPE , <EOL> referenced_id = parent_id ) <EOL> self . _testUpdate ( self . sync_log . get_id , { parent_id : [ ] , <EOL> child_id : [ index_ref ] } ) <EOL> close = CaseBlock ( create = False , case_id = parent_id , user_id = USER_ID , close = True ) . as_xml ( ) <EOL> self . _postFakeWithSyncToken ( close , self . sync_log . get_id ) <EOL> self . _testUpdate ( self . sync_log . get_id , { child_id : [ index_ref ] } , <EOL> { parent_id : [ ] } ) <EOL> assert_user_has_cases ( self , self . user , [ parent_id , child_id ] ) <EOL> @ run_with_all_backends <EOL> def testAssignToNewOwner ( self ) : <EOL> parent_id = "<STR_LIT>" <EOL> child_id = "<STR_LIT>" <EOL> index_id = '<STR_LIT>' <EOL> self . factory . create_or_update_cases ( [ <EOL> CaseStructure ( <EOL> case_id = child_id , <EOL> attrs = { '<STR_LIT>' : True } , <EOL> indices = [ CaseIndex ( <EOL> CaseStructure ( case_id = parent_id , attrs = { '<STR_LIT>' : True } ) , <EOL> relationship = CHILD_RELATIONSHIP , <EOL> related_type = PARENT_TYPE , <EOL> identifier = index_id , <EOL> ) ] , <EOL> ) <EOL> ] ) <EOL> index_ref = CommCareCaseIndex ( identifier = index_id , <EOL> referenced_type = PARENT_TYPE , <EOL> referenced_id = parent_id ) <EOL> self . _testUpdate ( self . sync_log . get_id , { parent_id : [ ] , <EOL> child_id : [ index_ref ] } ) <EOL> new_owner = "<STR_LIT>" <EOL> self . _postFakeWithSyncToken ( <EOL> CaseBlock ( create = False , case_id = child_id , user_id = USER_ID , owner_id = new_owner ) . as_xml ( ) , <EOL> self . sync_log . get_id <EOL> ) <EOL> self . _testUpdate ( self . sync_log . get_id , { parent_id : [ ] } , { } ) <EOL> @ run_with_all_backends <EOL> def testArchiveUpdates ( self ) : <EOL> """<STR_LIT>""" <EOL> case_id = "<STR_LIT>" <EOL> self . _createCaseStubs ( [ case_id ] ) <EOL> assert_user_doesnt_have_case ( self , self . user , case_id , restore_id = self . sync_log . get_id ) <EOL> update_block = CaseBlock ( <EOL> create = False , <EOL> case_id = case_id , <EOL> user_id = USER_ID , <EOL> update = { "<STR_LIT>" : "<STR_LIT:hello>" } <EOL> ) . as_xml ( ) <EOL> form , _ = self . _postFakeWithSyncToken ( update_block , self . sync_log . get_id ) <EOL> assert_user_doesnt_have_case ( self , self . user , case_id , restore_id = self . sync_log . get_id ) <EOL> form . archive ( ) <EOL> assert_user_has_case ( self , self . user , case_id , restore_id = self . sync_log . get_id , purge_restore_cache = True ) <EOL> @ run_with_all_backends <EOL> def testUserLoggedIntoMultipleDevices ( self ) : <EOL> parent_id = "<STR_LIT>" <EOL> child_id = "<STR_LIT>" <EOL> self . _createCaseStubs ( [ parent_id ] ) <EOL> other_sync_log = synclog_from_restore_payload ( <EOL> generate_restore_payload ( self . project , self . user , version = "<STR_LIT>" ) <EOL> ) <EOL> child = CaseBlock ( <EOL> create = True , <EOL> case_id = child_id , <EOL> user_id = USER_ID , <EOL> owner_id = USER_ID , <EOL> index = { '<STR_LIT>' : ( '<STR_LIT>' , parent_id ) } <EOL> ) . as_xml ( ) <EOL> self . _postFakeWithSyncToken ( child , other_sync_log . get_id ) <EOL> assert_user_has_case ( self , self . user , child_id , restore_id = self . sync_log . get_id ) <EOL> @ run_with_all_backends <EOL> def test_tiered_parent_closing ( self ) : <EOL> all_ids = [ uuid . uuid4 ( ) . hex for i in range ( <NUM_LIT:3> ) ] <EOL> [ grandparent_id , parent_id , child_id ] = all_ids <EOL> self . factory . create_or_update_cases ( [ <EOL> CaseStructure ( <EOL> case_id = child_id , <EOL> attrs = { '<STR_LIT>' : True } , <EOL> indices = [ CaseIndex ( <EOL> CaseStructure ( <EOL> case_id = parent_id , <EOL> attrs = { '<STR_LIT>' : True } , <EOL> indices = [ CaseIndex ( <EOL> CaseStructure ( case_id = grandparent_id , attrs = { '<STR_LIT>' : True } ) , <EOL> relationship = CHILD_RELATIONSHIP , <EOL> related_type = PARENT_TYPE , <EOL> ) ] , <EOL> ) , <EOL> relationship = CHILD_RELATIONSHIP , <EOL> related_type = PARENT_TYPE , <EOL> ) ] , <EOL> ) <EOL> ] ) <EOL> self . factory . close_case ( grandparent_id ) <EOL> sync_log = get_properly_wrapped_sync_log ( self . sync_log . _id ) <EOL> for id in all_ids : <EOL> self . assertTrue ( sync_log . phone_is_holding_case ( id ) ) <EOL> self . factory . close_case ( parent_id ) <EOL> sync_log = get_properly_wrapped_sync_log ( self . sync_log . _id ) <EOL> for id in all_ids : <EOL> self . assertTrue ( sync_log . phone_is_holding_case ( id ) ) <EOL> self . factory . close_case ( child_id ) <EOL> sync_log = get_properly_wrapped_sync_log ( self . sync_log . _id ) <EOL> for id in all_ids : <EOL> self . assertFalse ( sync_log . phone_is_holding_case ( id ) ) <EOL> @ run_with_all_backends <EOL> def test_create_immediately_irrelevant_parent_case ( self ) : <EOL> """<STR_LIT>""" <EOL> parent_id , child_id = [ uuid . uuid4 ( ) . hex for i in range ( <NUM_LIT:2> ) ] <EOL> self . factory . create_or_update_cases ( [ <EOL> CaseStructure ( <EOL> case_id = child_id , <EOL> attrs = { '<STR_LIT>' : True } , <EOL> indices = [ CaseIndex ( <EOL> CaseStructure ( case_id = parent_id , attrs = { '<STR_LIT>' : True , '<STR_LIT>' : uuid . uuid4 ( ) . hex } ) , <EOL> relationship = CHILD_RELATIONSHIP , <EOL> related_type = PARENT_TYPE , <EOL> identifier = PARENT_TYPE , <EOL> ) ] , <EOL> ) <EOL> ] ) <EOL> index_ref = CommCareCaseIndex ( identifier = PARENT_TYPE , <EOL> referenced_type = PARENT_TYPE , <EOL> referenced_id = parent_id ) <EOL> self . _testUpdate ( self . sync_log . _id , { child_id : [ index_ref ] } , { parent_id : [ ] } ) <EOL> @ run_with_all_backends <EOL> def test_closed_case_not_in_next_sync ( self ) : <EOL> case_id = self . factory . create_case ( ) . case_id <EOL> restore_config = RestoreConfig ( <EOL> project = Domain ( name = self . project . name ) , <EOL> user = self . user , params = RestoreParams ( self . sync_log . _id , version = V2 ) <EOL> ) <EOL> next_sync = synclog_from_restore_payload ( restore_config . get_payload ( ) . as_string ( ) ) <EOL> self . assertTrue ( next_sync . phone_is_holding_case ( case_id ) ) <EOL> self . factory . create_or_update_case ( CaseStructure ( case_id = case_id , attrs = { '<STR_LIT>' : True } ) , <EOL> form_extras = { '<STR_LIT>' : next_sync . _id } ) <EOL> restore_config = RestoreConfig ( <EOL> project = Domain ( name = self . project . name ) , <EOL> user = self . user , params = RestoreParams ( next_sync . _id , version = V2 ) <EOL> ) <EOL> last_sync = synclog_from_restore_payload ( restore_config . get_payload ( ) . as_string ( ) ) <EOL> self . assertFalse ( last_sync . phone_is_holding_case ( case_id ) ) <EOL> @ run_with_all_backends <EOL> def test_sync_by_user_id ( self ) : <EOL> case_id = self . factory . create_case ( owner_id = '<STR_LIT>' , user_id = USER_ID ) . case_id <EOL> restore_config = RestoreConfig ( self . project , user = self . user ) <EOL> payload = restore_config . get_payload ( ) . as_string ( ) <EOL> self . assertTrue ( case_id in payload ) <EOL> sync_log = synclog_from_restore_payload ( payload ) <EOL> self . assertTrue ( sync_log . phone_is_holding_case ( case_id ) ) <EOL> @ run_with_all_backends <EOL> def test_create_irrelevant_owner_and_update_to_irrelevant_owner_in_same_form ( self ) : <EOL> self . factory . create_case ( owner_id = '<STR_LIT>' , update = { '<STR_LIT>' : '<STR_LIT>' } , strict = False ) <EOL> @ run_with_all_backends <EOL> def test_create_irrelevant_owner_and_update_to_relevant_owner_in_same_form ( self ) : <EOL> case = self . factory . create_case ( owner_id = '<STR_LIT>' , update = { '<STR_LIT>' : USER_ID } , strict = False ) <EOL> sync_log = get_properly_wrapped_sync_log ( self . sync_log . _id ) <EOL> if isinstance ( sync_log , SimplifiedSyncLog ) : <EOL> self . assertTrue ( sync_log . phone_is_holding_case ( case . case_id ) ) <EOL> @ run_with_all_backends <EOL> def test_create_relevant_owner_and_update_to_empty_owner_in_same_form ( self ) : <EOL> case = self . factory . create_case ( owner_id = USER_ID , update = { '<STR_LIT>' : '<STR_LIT>' } , strict = False ) <EOL> sync_log = get_properly_wrapped_sync_log ( self . sync_log . _id ) <EOL> if isinstance ( sync_log , SimplifiedSyncLog ) : <EOL> self . assertFalse ( sync_log . phone_is_holding_case ( case . case_id ) ) <EOL> @ run_with_all_backends <EOL> def test_create_irrelevant_owner_and_update_to_empty_owner_in_same_form ( self ) : <EOL> case = self . factory . create_case ( owner_id = '<STR_LIT>' , update = { '<STR_LIT>' : '<STR_LIT>' } , strict = False ) <EOL> sync_log = get_properly_wrapped_sync_log ( self . sync_log . _id ) <EOL> self . assertFalse ( sync_log . phone_is_holding_case ( case . case_id ) ) <EOL> @ run_with_all_backends <EOL> def test_create_relevant_owner_then_submit_again_with_no_owner ( self ) : <EOL> case = self . factory . create_case ( ) <EOL> sync_log = get_properly_wrapped_sync_log ( self . sync_log . _id ) <EOL> self . assertTrue ( sync_log . phone_is_holding_case ( case . case_id ) ) <EOL> self . factory . create_or_update_case ( CaseStructure ( <EOL> case_id = case . case_id , <EOL> attrs = { '<STR_LIT>' : None } <EOL> ) ) <EOL> sync_log = get_properly_wrapped_sync_log ( self . sync_log . _id ) <EOL> self . assertTrue ( sync_log . phone_is_holding_case ( case . case_id ) ) <EOL> @ run_with_all_backends <EOL> def test_create_irrelevant_owner_then_submit_again_with_no_owner ( self ) : <EOL> case = self . factory . create_case ( owner_id = '<STR_LIT>' ) <EOL> sync_log = get_properly_wrapped_sync_log ( self . sync_log . _id ) <EOL> self . assertFalse ( sync_log . phone_is_holding_case ( case . case_id ) ) <EOL> self . factory . create_or_update_case ( CaseStructure ( <EOL> case_id = case . case_id , <EOL> attrs = { '<STR_LIT>' : None } <EOL> ) ) <EOL> sync_log = get_properly_wrapped_sync_log ( self . sync_log . _id ) <EOL> self . assertFalse ( sync_log . phone_is_holding_case ( case . case_id ) ) <EOL> @ run_with_all_backends <EOL> def test_create_irrelevant_child_case_and_close_parent_in_same_form ( self ) : <EOL> parent_id = self . factory . create_case ( ) . case_id <EOL> child_id = uuid . uuid4 ( ) . hex <EOL> self . factory . create_or_update_cases ( [ <EOL> CaseStructure ( <EOL> case_id = child_id , <EOL> attrs = { <EOL> '<STR_LIT>' : True , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : { '<STR_LIT>' : '<STR_LIT>' } , <EOL> '<STR_LIT:strict>' : False <EOL> } , <EOL> indices = [ CaseIndex ( <EOL> CaseStructure ( case_id = parent_id , attrs = { '<STR_LIT>' : True } ) , <EOL> relationship = CHILD_RELATIONSHIP , <EOL> related_type = PARENT_TYPE , <EOL> ) ] , <EOL> ) <EOL> ] ) <EOL> self . _testUpdate ( self . sync_log . _id , { } , { } ) <EOL> @ run_with_all_backends <EOL> def test_create_closed_child_case_and_close_parent_in_same_form ( self ) : <EOL> parent_id = self . factory . create_case ( ) . case_id <EOL> child_id = uuid . uuid4 ( ) . hex <EOL> self . factory . create_or_update_cases ( [ <EOL> CaseStructure ( case_id = parent_id , attrs = { '<STR_LIT>' : True , '<STR_LIT>' : CaseBlock . undefined } ) , <EOL> CaseStructure ( <EOL> case_id = child_id , <EOL> attrs = { <EOL> '<STR_LIT>' : True , <EOL> '<STR_LIT>' : True , <EOL> '<STR_LIT>' : { '<STR_LIT:foo>' : '<STR_LIT:bar>' } , <EOL> } , <EOL> indices = [ CaseIndex ( <EOL> CaseStructure ( case_id = parent_id ) , <EOL> relationship = CHILD_RELATIONSHIP , <EOL> related_type = PARENT_TYPE , <EOL> ) ] , <EOL> walk_related = False , <EOL> ) <EOL> ] ) <EOL> self . _testUpdate ( self . sync_log . _id , { } , { } ) <EOL> @ run_with_all_backends <EOL> def test_create_irrelevant_owner_and_close_in_same_form ( self ) : <EOL> self . factory . create_case ( owner_id = '<STR_LIT>' , close = True ) <EOL> @ run_with_all_backends <EOL> def test_reassign_and_close_in_same_form ( self ) : <EOL> case_id = self . factory . create_case ( ) . case_id <EOL> self . factory . create_or_update_case ( <EOL> CaseStructure ( <EOL> case_id = case_id , <EOL> attrs = { '<STR_LIT>' : '<STR_LIT>' , '<STR_LIT>' : True } , <EOL> ) <EOL> ) <EOL> @ run_with_all_backends <EOL> def test_index_after_close ( self ) : <EOL> parent_id = self . factory . create_case ( ) . case_id <EOL> case_id = uuid . uuid4 ( ) . hex <EOL> case_xml = self . factory . get_case_block ( case_id , create = True , close = True ) <EOL> index_wrapper = ElementTree . Element ( '<STR_LIT:index>' ) <EOL> index_elem = ElementTree . Element ( '<STR_LIT>' ) <EOL> index_elem . set ( '<STR_LIT>' , '<STR_LIT:test>' ) <EOL> index_elem . set ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> index_elem . text = parent_id <EOL> index_wrapper . append ( index_elem ) <EOL> case_xml . append ( index_wrapper ) <EOL> self . factory . post_case_blocks ( [ case_xml ] ) <EOL> sync_log = get_properly_wrapped_sync_log ( self . sync_log . _id ) <EOL> self . assertFalse ( sync_log . phone_is_holding_case ( case_id ) ) <EOL> @ run_with_all_backends <EOL> def test_index_chain_with_closed_parents ( self ) : <EOL> grandparent = CaseStructure ( <EOL> case_id = uuid . uuid4 ( ) . hex , <EOL> attrs = { '<STR_LIT>' : True } <EOL> ) <EOL> parent = CaseStructure ( <EOL> case_id = uuid . uuid4 ( ) . hex , <EOL> attrs = { '<STR_LIT>' : True } , <EOL> indices = [ CaseIndex ( <EOL> grandparent , <EOL> relationship = CHILD_RELATIONSHIP , <EOL> related_type = PARENT_TYPE , <EOL> ) ] <EOL> ) <EOL> child = CaseStructure ( <EOL> case_id = uuid . uuid4 ( ) . hex , <EOL> indices = [ CaseIndex ( <EOL> parent , <EOL> relationship = CHILD_RELATIONSHIP , <EOL> related_type = PARENT_TYPE , <EOL> ) ] <EOL> ) <EOL> parent_ref = CommCareCaseIndex ( <EOL> identifier = PARENT_TYPE , <EOL> referenced_type = PARENT_TYPE , <EOL> referenced_id = parent . case_id ) <EOL> grandparent_ref = CommCareCaseIndex ( <EOL> identifier = PARENT_TYPE , <EOL> referenced_type = PARENT_TYPE , <EOL> referenced_id = grandparent . case_id ) <EOL> self . factory . create_or_update_cases ( [ child ] ) <EOL> self . _testUpdate ( <EOL> self . sync_log . _id , <EOL> { child . case_id : [ parent_ref ] , <EOL> parent . case_id : [ grandparent_ref ] , <EOL> grandparent . case_id : [ ] } , <EOL> { parent . case_id : [ grandparent . case_id ] , <EOL> grandparent . case_id : [ ] } <EOL> ) <EOL> @ run_with_all_backends <EOL> def test_reassign_case_and_sync ( self ) : <EOL> case = self . factory . create_case ( ) <EOL> self . factory . create_or_update_case ( <EOL> CaseStructure ( <EOL> case_id = case . case_id , <EOL> attrs = { '<STR_LIT>' : '<STR_LIT>' } , <EOL> ) , <EOL> form_extras = { '<STR_LIT>' : None } <EOL> ) <EOL> assert_user_has_case ( self , self . user , case . case_id , restore_id = self . sync_log . _id ) <EOL> payload = generate_restore_payload ( self . project , self . user , restore_id = self . sync_log . _id , version = V2 ) <EOL> next_sync_log = synclog_from_restore_payload ( payload ) <EOL> self . assertFalse ( next_sync_log . phone_is_holding_case ( case . case_id ) ) <EOL> @ run_with_all_backends <EOL> def test_cousins ( self ) : <EOL> """<STR_LIT>""" <EOL> other_owner_id = uuid . uuid4 ( ) . hex <EOL> grandparent = CaseStructure ( <EOL> case_id = "<STR_LIT>" , <EOL> attrs = { '<STR_LIT>' : other_owner_id } <EOL> ) <EOL> parent_1 = CaseStructure ( <EOL> case_id = "<STR_LIT>" , <EOL> attrs = { '<STR_LIT>' : other_owner_id } , <EOL> indices = [ CaseIndex ( grandparent ) ] <EOL> ) <EOL> parent_2 = CaseStructure ( <EOL> case_id = "<STR_LIT>" , <EOL> attrs = { '<STR_LIT>' : other_owner_id } , <EOL> indices = [ CaseIndex ( grandparent ) ] <EOL> ) <EOL> child_1 = CaseStructure ( <EOL> case_id = "<STR_LIT>" , <EOL> indices = [ CaseIndex ( parent_1 ) ] <EOL> ) <EOL> child_2 = CaseStructure ( <EOL> case_id = "<STR_LIT>" , <EOL> indices = [ CaseIndex ( parent_2 ) ] <EOL> ) <EOL> self . factory . create_or_update_cases ( [ grandparent , parent_1 , parent_2 , child_1 , child_2 ] ) <EOL> assert_user_has_cases ( self , self . user , [ <EOL> grandparent . case_id , <EOL> parent_1 . case_id , <EOL> parent_2 . case_id , <EOL> child_1 . case_id , <EOL> child_2 . case_id <EOL> ] ) <EOL> class SyncDeletedCasesTest ( SyncBaseTest ) : <EOL> @ run_with_all_backends <EOL> def test_deleted_case_doesnt_sync ( self ) : <EOL> case = self . factory . create_case ( ) <EOL> case . soft_delete ( ) <EOL> assert_user_doesnt_have_case ( self , self . user , case . case_id ) <EOL> @ run_with_all_backends <EOL> def test_deleted_parent_doesnt_sync ( self ) : <EOL> parent_id = uuid . uuid4 ( ) . hex <EOL> child_id = uuid . uuid4 ( ) . hex <EOL> self . factory . create_or_update_cases ( [ <EOL> CaseStructure ( <EOL> case_id = child_id , <EOL> attrs = { <EOL> '<STR_LIT>' : True , <EOL> } , <EOL> indices = [ CaseIndex ( <EOL> CaseStructure ( case_id = parent_id ) , <EOL> relationship = CHILD_RELATIONSHIP , <EOL> related_type = PARENT_TYPE , <EOL> ) ] , <EOL> ) <EOL> ] ) <EOL> CaseAccessors ( ) . get_case ( parent_id ) . soft_delete ( ) <EOL> assert_user_doesnt_have_case ( self , self . user , parent_id ) <EOL> assert_user_has_case ( self , self . user , child_id ) <EOL> class ExtensionCasesSyncTokenUpdates ( SyncBaseTest ) : <EOL> """<STR_LIT>""" <EOL> @ run_with_all_backends <EOL> def test_create_extension ( self ) : <EOL> """<STR_LIT>""" <EOL> case_type = '<STR_LIT>' <EOL> index_identifier = '<STR_LIT>' <EOL> host = CaseStructure ( case_id = '<STR_LIT:host>' , <EOL> attrs = { '<STR_LIT>' : True } ) <EOL> extension = CaseStructure ( <EOL> case_id = '<STR_LIT>' , <EOL> attrs = { '<STR_LIT>' : True , '<STR_LIT>' : '<STR_LIT:->' } , <EOL> indices = [ CaseIndex ( <EOL> host , <EOL> identifier = index_identifier , <EOL> relationship = '<STR_LIT>' , <EOL> related_type = case_type , <EOL> ) ] , <EOL> ) <EOL> self . factory . create_or_update_cases ( [ extension ] ) <EOL> sync_log = get_properly_wrapped_sync_log ( self . sync_log . _id ) <EOL> self . assertDictEqual ( sync_log . index_tree . indices , { } ) <EOL> self . assertDictEqual ( sync_log . extension_index_tree . indices , <EOL> { extension . case_id : { index_identifier : host . case_id } } ) <EOL> self . assertEqual ( sync_log . dependent_case_ids_on_phone , set ( [ extension . case_id ] ) ) <EOL> self . assertEqual ( sync_log . case_ids_on_phone , set ( [ extension . case_id , host . case_id ] ) ) <EOL> @ run_with_all_backends <EOL> def test_create_multiple_indices ( self ) : <EOL> """<STR_LIT>""" <EOL> case_type = '<STR_LIT>' <EOL> host = CaseStructure ( case_id = '<STR_LIT:host>' , <EOL> attrs = { '<STR_LIT>' : True } ) <EOL> extension = CaseStructure ( <EOL> case_id = '<STR_LIT>' , <EOL> attrs = { '<STR_LIT>' : True , '<STR_LIT>' : '<STR_LIT:->' } , <EOL> indices = [ CaseIndex ( <EOL> host , <EOL> identifier = '<STR_LIT:host>' , <EOL> relationship = '<STR_LIT>' , <EOL> related_type = case_type , <EOL> ) , CaseIndex ( <EOL> CaseStructure ( case_id = host . case_id , attrs = { '<STR_LIT>' : False } ) , <EOL> identifier = '<STR_LIT>' , <EOL> relationship = '<STR_LIT>' , <EOL> related_type = case_type , <EOL> ) ] , <EOL> ) <EOL> self . factory . create_or_update_cases ( [ extension ] ) <EOL> sync_log = get_properly_wrapped_sync_log ( self . sync_log . _id ) <EOL> self . assertDictEqual ( sync_log . index_tree . indices , <EOL> { extension . case_id : { '<STR_LIT>' : host . case_id } } ) <EOL> self . assertDictEqual ( sync_log . extension_index_tree . indices , <EOL> { extension . case_id : { '<STR_LIT:host>' : host . case_id } } ) <EOL> @ run_with_all_backends <EOL> def test_create_extension_with_extension ( self ) : <EOL> """<STR_LIT>""" <EOL> case_type = '<STR_LIT>' <EOL> host = CaseStructure ( case_id = '<STR_LIT:host>' , <EOL> attrs = { '<STR_LIT>' : True } ) <EOL> extension = CaseStructure ( <EOL> case_id = '<STR_LIT>' , <EOL> attrs = { '<STR_LIT>' : True , '<STR_LIT>' : '<STR_LIT:->' } , <EOL> indices = [ CaseIndex ( <EOL> host , <EOL> identifier = '<STR_LIT:host>' , <EOL> relationship = '<STR_LIT>' , <EOL> related_type = case_type , <EOL> ) ] , <EOL> ) <EOL> extension_extension = CaseStructure ( <EOL> case_id = '<STR_LIT>' , <EOL> attrs = { '<STR_LIT>' : True , '<STR_LIT>' : '<STR_LIT:->' } , <EOL> indices = [ CaseIndex ( <EOL> extension , <EOL> identifier = '<STR_LIT>' , <EOL> relationship = '<STR_LIT>' , <EOL> related_type = case_type , <EOL> ) ] <EOL> ) <EOL> self . factory . create_or_update_cases ( [ extension_extension ] ) <EOL> sync_log = get_properly_wrapped_sync_log ( self . sync_log . _id ) <EOL> expected_extension_tree = { extension . case_id : { '<STR_LIT:host>' : host . case_id } , <EOL> extension_extension . case_id : { '<STR_LIT>' : extension . case_id } } <EOL> self . assertDictEqual ( sync_log . index_tree . indices , { } ) <EOL> self . assertDictEqual ( sync_log . extension_index_tree . indices , expected_extension_tree ) <EOL> @ run_with_all_backends <EOL> def test_create_extension_then_delegate ( self ) : <EOL> """<STR_LIT>""" <EOL> case_type = '<STR_LIT>' <EOL> host = CaseStructure ( case_id = '<STR_LIT:host>' , <EOL> attrs = { '<STR_LIT>' : True } ) <EOL> extension = CaseStructure ( <EOL> case_id = '<STR_LIT>' , <EOL> attrs = { '<STR_LIT>' : True , '<STR_LIT>' : '<STR_LIT:->' } , <EOL> indices = [ CaseIndex ( <EOL> host , <EOL> identifier = '<STR_LIT:host>' , <EOL> relationship = '<STR_LIT>' , <EOL> related_type = case_type , <EOL> ) ] , <EOL> ) <EOL> self . factory . create_or_update_case ( extension ) <EOL> delegated_extension = CaseStructure ( case_id = extension . case_id , attrs = { '<STR_LIT>' : '<STR_LIT>' } ) <EOL> self . factory . create_or_update_case ( delegated_extension ) <EOL> expected_extension_tree = { extension . case_id : { '<STR_LIT:host>' : host . case_id } } <EOL> sync_log = get_properly_wrapped_sync_log ( self . sync_log . _id ) <EOL> self . assertDictEqual ( sync_log . extension_index_tree . indices , expected_extension_tree ) <EOL> self . assertEqual ( sync_log . dependent_case_ids_on_phone , set ( [ extension . case_id ] ) ) <EOL> self . assertEqual ( sync_log . case_ids_on_phone , set ( [ extension . case_id , host . case_id ] ) ) <EOL> @ run_with_all_backends <EOL> def test_create_delegated_extension ( self ) : <EOL> case_type = '<STR_LIT>' <EOL> host = CaseStructure ( case_id = '<STR_LIT:host>' , <EOL> attrs = { '<STR_LIT>' : True } ) <EOL> extension = CaseStructure ( <EOL> case_id = '<STR_LIT>' , <EOL> attrs = { '<STR_LIT>' : True , '<STR_LIT>' : '<STR_LIT>' } , <EOL> indices = [ CaseIndex ( <EOL> host , <EOL> identifier = '<STR_LIT:host>' , <EOL> relationship = '<STR_LIT>' , <EOL> related_type = case_type , <EOL> ) ] , <EOL> ) <EOL> self . factory . create_or_update_case ( extension ) <EOL> expected_extension_tree = { extension . case_id : { '<STR_LIT:host>' : host . case_id } } <EOL> sync_log = get_properly_wrapped_sync_log ( self . sync_log . _id ) <EOL> self . assertDictEqual ( sync_log . extension_index_tree . indices , expected_extension_tree ) <EOL> self . assertEqual ( sync_log . case_ids_on_phone , set ( [ host . case_id , extension . case_id ] ) ) <EOL> @ run_with_all_backends <EOL> def test_close_host ( self ) : <EOL> """<STR_LIT>""" <EOL> case_type = '<STR_LIT>' <EOL> index_identifier = '<STR_LIT>' <EOL> host = CaseStructure ( case_id = '<STR_LIT:host>' , <EOL> attrs = { '<STR_LIT>' : True } ) <EOL> extension = CaseStructure ( <EOL> case_id = '<STR_LIT>' , <EOL> attrs = { '<STR_LIT>' : True , '<STR_LIT>' : '<STR_LIT:->' } , <EOL> indices = [ CaseIndex ( <EOL> host , <EOL> identifier = index_identifier , <EOL> relationship = '<STR_LIT>' , <EOL> related_type = case_type , <EOL> ) ] , <EOL> ) <EOL> self . factory . create_or_update_cases ( [ extension ] ) <EOL> sync_log = get_properly_wrapped_sync_log ( self . sync_log . _id ) <EOL> self . assertDictEqual ( sync_log . extension_index_tree . indices , <EOL> { extension . case_id : { index_identifier : host . case_id } } ) <EOL> closed_host = CaseStructure ( case_id = host . case_id , attrs = { '<STR_LIT>' : True } ) <EOL> self . factory . create_or_update_case ( closed_host ) <EOL> sync_log = get_properly_wrapped_sync_log ( self . sync_log . _id ) <EOL> self . assertDictEqual ( sync_log . extension_index_tree . indices , { } ) <EOL> self . assertEqual ( sync_log . dependent_case_ids_on_phone , set ( [ ] ) ) <EOL> self . assertEqual ( sync_log . case_ids_on_phone , set ( [ ] ) ) <EOL> @ run_with_all_backends <EOL> def test_long_chain_with_children ( self ) : <EOL> """<STR_LIT>""" <EOL> case_type = '<STR_LIT>' <EOL> E1 = CaseStructure ( <EOL> case_id = '<STR_LIT>' , <EOL> attrs = { '<STR_LIT>' : True , '<STR_LIT>' : '<STR_LIT:->' } , <EOL> ) <EOL> C = CaseStructure ( <EOL> case_id = '<STR_LIT>' , <EOL> attrs = { '<STR_LIT>' : True , '<STR_LIT>' : '<STR_LIT:->' } , <EOL> indices = [ CaseIndex ( <EOL> E1 , <EOL> identifier = '<STR_LIT>' , <EOL> relationship = '<STR_LIT>' , <EOL> related_type = case_type , <EOL> ) ] <EOL> ) <EOL> O = CaseStructure ( <EOL> case_id = '<STR_LIT>' , <EOL> attrs = { '<STR_LIT>' : True } , <EOL> indices = [ CaseIndex ( <EOL> C , <EOL> identifier = '<STR_LIT>' , <EOL> relationship = '<STR_LIT>' , <EOL> related_type = case_type , <EOL> ) ] <EOL> ) <EOL> E2 = CaseStructure ( <EOL> case_id = '<STR_LIT>' , <EOL> attrs = { '<STR_LIT>' : True , '<STR_LIT>' : '<STR_LIT:->' } , <EOL> indices = [ CaseIndex ( <EOL> C , <EOL> identifier = '<STR_LIT>' , <EOL> relationship = '<STR_LIT>' , <EOL> related_type = case_type , <EOL> ) ] <EOL> ) <EOL> self . factory . create_or_update_cases ( [ O , E2 ] ) <EOL> sync_log = get_properly_wrapped_sync_log ( self . sync_log . _id ) <EOL> expected_dependent_ids = set ( [ C . case_id , E1 . case_id , E2 . case_id ] ) <EOL> self . assertEqual ( sync_log . dependent_case_ids_on_phone , expected_dependent_ids ) <EOL> all_ids = set ( [ E1 . case_id , E2 . case_id , O . case_id , C . case_id ] ) <EOL> self . assertEqual ( sync_log . case_ids_on_phone , all_ids ) <EOL> class ExtensionCasesFirstSync ( SyncBaseTest ) : <EOL> def setUp ( self ) : <EOL> super ( ExtensionCasesFirstSync , self ) . setUp ( ) <EOL> self . restore_config = RestoreConfig ( project = self . project , user = self . user ) <EOL> self . restore_state = self . restore_config . restore_state <EOL> @ run_with_all_backends <EOL> def test_is_first_extension_sync ( self ) : <EOL> """<STR_LIT>""" <EOL> with flag_enabled ( '<STR_LIT>' ) : <EOL> self . assertTrue ( self . restore_state . is_first_extension_sync ) <EOL> self . assertFalse ( self . restore_state . is_first_extension_sync ) <EOL> @ run_with_all_backends <EOL> def test_is_first_extension_sync_after_sync ( self ) : <EOL> """<STR_LIT>""" <EOL> self . factory . create_case ( ) <EOL> with flag_enabled ( '<STR_LIT>' ) : <EOL> config = get_restore_config ( self . project , self . user , restore_id = self . sync_log . _id ) <EOL> self . assertTrue ( get_properly_wrapped_sync_log ( self . sync_log . _id ) . extensions_checked ) <EOL> self . assertFalse ( config . restore_state . is_first_extension_sync ) <EOL> config = get_restore_config ( self . project , self . user , restore_id = self . sync_log . _id ) <EOL> self . assertTrue ( get_properly_wrapped_sync_log ( self . sync_log . _id ) . extensions_checked ) <EOL> self . assertFalse ( config . restore_state . is_first_extension_sync ) <EOL> class ChangingOwnershipTest ( SyncBaseTest ) : <EOL> def setUp ( self ) : <EOL> super ( ChangingOwnershipTest , self ) . setUp ( ) <EOL> self . extra_owner_id = '<STR_LIT>' <EOL> self . user . additional_owner_ids = [ self . extra_owner_id ] <EOL> self . sync_log = synclog_from_restore_payload ( <EOL> generate_restore_payload ( self . project , self . user ) <EOL> ) <EOL> self . assertTrue ( self . extra_owner_id in self . sync_log . owner_ids_on_phone ) <EOL> self . factory . form_extras = { '<STR_LIT>' : self . sync_log . _id } <EOL> @ run_with_all_backends <EOL> def test_change_owner_list ( self ) : <EOL> case_id = self . factory . create_case ( owner_id = self . extra_owner_id ) . case_id <EOL> sync_log = get_properly_wrapped_sync_log ( self . sync_log . _id ) <EOL> self . assertTrue ( sync_log . phone_is_holding_case ( case_id ) ) <EOL> def _get_incremental_synclog_for_user ( user , since ) : <EOL> incremental_restore_config = RestoreConfig ( <EOL> self . project , <EOL> user = self . user , <EOL> params = RestoreParams ( version = V2 , sync_log_id = since ) , <EOL> ) <EOL> return synclog_from_restore_payload ( incremental_restore_config . get_payload ( ) . as_string ( ) ) <EOL> incremental_sync_log = _get_incremental_synclog_for_user ( self . user , since = self . sync_log . _id ) <EOL> self . assertTrue ( self . extra_owner_id in incremental_sync_log . owner_ids_on_phone ) <EOL> self . assertTrue ( incremental_sync_log . phone_is_holding_case ( case_id ) ) <EOL> self . user . additional_owner_ids = [ ] <EOL> incremental_sync_log = _get_incremental_synclog_for_user ( self . user , since = incremental_sync_log . _id ) <EOL> self . assertFalse ( self . extra_owner_id in incremental_sync_log . owner_ids_on_phone ) <EOL> self . assertFalse ( incremental_sync_log . phone_is_holding_case ( case_id ) ) <EOL> class SyncTokenCachingTest ( SyncBaseTest ) : <EOL> @ run_with_all_backends <EOL> def testCaching ( self ) : <EOL> self . assertFalse ( self . sync_log . has_cached_payload ( V2 ) ) <EOL> original_payload = RestoreConfig ( <EOL> project = self . project , <EOL> user = self . user , <EOL> params = RestoreParams ( <EOL> version = V2 , <EOL> sync_log_id = self . sync_log . _id , <EOL> ) <EOL> ) . get_payload ( ) . as_string ( ) <EOL> next_sync_log = synclog_from_restore_payload ( original_payload ) <EOL> self . sync_log = get_properly_wrapped_sync_log ( self . sync_log . _id ) <EOL> self . assertTrue ( self . sync_log . has_cached_payload ( V2 ) ) <EOL> cached_payload = RestoreConfig ( <EOL> project = self . project , <EOL> user = self . user , <EOL> params = RestoreParams ( <EOL> version = V2 , <EOL> sync_log_id = self . sync_log . _id , <EOL> ) <EOL> ) . get_payload ( ) . as_string ( ) <EOL> self . assertEqual ( original_payload , cached_payload ) <EOL> versioned_payload = RestoreConfig ( <EOL> project = self . project , <EOL> user = self . user , <EOL> params = RestoreParams ( <EOL> version = V1 , <EOL> sync_log_id = self . sync_log . _id , <EOL> ) , <EOL> ) . get_payload ( ) . as_string ( ) <EOL> self . assertNotEqual ( original_payload , versioned_payload ) <EOL> versioned_sync_log = synclog_from_restore_payload ( versioned_payload ) <EOL> self . assertNotEqual ( next_sync_log . _id , versioned_sync_log . _id ) <EOL> @ run_with_all_backends <EOL> def test_initial_cache ( self ) : <EOL> restore_config = RestoreConfig ( <EOL> project = self . project , <EOL> user = self . user , <EOL> cache_settings = RestoreCacheSettings ( force_cache = True ) , <EOL> ) <EOL> original_payload = restore_config . get_payload ( ) <EOL> self . assertNotIsInstance ( original_payload , CachedResponse ) <EOL> restore_config = RestoreConfig ( project = self . project , user = self . user ) <EOL> cached_payload = restore_config . get_payload ( ) <EOL> self . assertIsInstance ( cached_payload , CachedResponse ) <EOL> @ run_with_all_backends <EOL> def testCacheInvalidation ( self ) : <EOL> original_payload = RestoreConfig ( <EOL> project = self . project , <EOL> user = self . user , <EOL> params = RestoreParams ( <EOL> version = V2 , <EOL> sync_log_id = self . sync_log . _id , <EOL> ) , <EOL> ) . get_payload ( ) . as_string ( ) <EOL> self . sync_log = get_properly_wrapped_sync_log ( self . sync_log . _id ) <EOL> self . assertTrue ( self . sync_log . has_cached_payload ( V2 ) ) <EOL> case_id = "<STR_LIT>" <EOL> self . _createCaseStubs ( [ case_id ] ) <EOL> self . sync_log = get_properly_wrapped_sync_log ( self . sync_log . _id ) <EOL> self . assertFalse ( self . sync_log . has_cached_payload ( V2 ) ) <EOL> next_payload = RestoreConfig ( <EOL> project = self . project , <EOL> user = self . user , <EOL> params = RestoreParams ( <EOL> version = V2 , <EOL> sync_log_id = self . sync_log . _id , <EOL> ) , <EOL> ) . get_payload ( ) . as_string ( ) <EOL> self . sync_log = get_properly_wrapped_sync_log ( self . sync_log . _id ) <EOL> self . assertTrue ( self . sync_log . has_cached_payload ( V2 ) ) <EOL> self . assertNotEqual ( original_payload , next_payload ) <EOL> self . assertFalse ( case_id in original_payload ) <EOL> self . assertFalse ( case_id in next_payload ) <EOL> self . assertTrue ( self . sync_log . phone_is_holding_case ( case_id ) ) <EOL> @ run_with_all_backends <EOL> def testCacheNonInvalidation ( self ) : <EOL> original_payload = RestoreConfig ( <EOL> project = self . project , <EOL> user = self . user , <EOL> params = RestoreParams ( <EOL> version = V2 , <EOL> sync_log_id = self . sync_log . _id , <EOL> ) , <EOL> ) . get_payload ( ) . as_string ( ) <EOL> self . sync_log = get_properly_wrapped_sync_log ( self . sync_log . _id ) <EOL> self . assertTrue ( self . sync_log . has_cached_payload ( V2 ) ) <EOL> case_id = "<STR_LIT>" <EOL> post_case_blocks ( [ CaseBlock ( <EOL> create = True , <EOL> case_id = case_id , <EOL> user_id = self . user . user_id , <EOL> owner_id = self . user . user_id , <EOL> case_type = PARENT_TYPE , <EOL> ) . as_xml ( ) ] ) <EOL> next_payload = RestoreConfig ( <EOL> project = self . project , <EOL> user = self . user , <EOL> params = RestoreParams ( <EOL> version = V2 , <EOL> sync_log_id = self . sync_log . _id , <EOL> ) , <EOL> ) . get_payload ( ) . as_string ( ) <EOL> self . assertEqual ( original_payload , next_payload ) <EOL> self . assertFalse ( case_id in next_payload ) <EOL> @ run_with_all_backends <EOL> def testCacheInvalidationAfterFileDelete ( self ) : <EOL> original_payload = RestoreConfig ( <EOL> project = self . project , <EOL> user = self . user , <EOL> cache_settings = RestoreCacheSettings ( force_cache = True ) <EOL> ) . get_payload ( ) <EOL> self . assertNotIsInstance ( original_payload , CachedResponse ) <EOL> os . remove ( original_payload . get_filename ( ) ) <EOL> next_file = RestoreConfig ( project = self . project , user = self . user ) . get_payload ( ) <EOL> self . assertNotIsInstance ( next_file , CachedResponse ) <EOL> self . assertNotEqual ( original_payload . get_filename ( ) , next_file . get_filename ( ) ) <EOL> class MultiUserSyncTest ( SyncBaseTest ) : <EOL> """<STR_LIT>""" <EOL> def setUp ( self ) : <EOL> super ( MultiUserSyncTest , self ) . setUp ( ) <EOL> self . other_user = User ( user_id = OTHER_USER_ID , username = OTHER_USERNAME , <EOL> password = "<STR_LIT>" , date_joined = datetime ( <NUM_LIT> , <NUM_LIT:6> , <NUM_LIT:9> ) , <EOL> additional_owner_ids = [ SHARED_ID ] ) <EOL> self . other_sync_log = synclog_from_restore_payload ( <EOL> generate_restore_payload ( self . project , self . other_user ) <EOL> ) <EOL> self . assertTrue ( SHARED_ID in self . other_sync_log . owner_ids_on_phone ) <EOL> self . assertTrue ( OTHER_USER_ID in self . other_sync_log . owner_ids_on_phone ) <EOL> self . user . additional_owner_ids = [ SHARED_ID ] <EOL> self . sync_log = synclog_from_restore_payload ( <EOL> generate_restore_payload ( self . project , self . user ) <EOL> ) <EOL> self . assertTrue ( SHARED_ID in self . sync_log . owner_ids_on_phone ) <EOL> self . assertTrue ( USER_ID in self . sync_log . owner_ids_on_phone ) <EOL> self . factory . form_extras = { '<STR_LIT>' : self . sync_log . _id } <EOL> self . factory . case_defaults . update ( { '<STR_LIT>' : SHARED_ID } ) <EOL> @ run_with_all_backends <EOL> def testSharedCase ( self ) : <EOL> case_id = "<STR_LIT>" <EOL> self . _createCaseStubs ( [ case_id ] , owner_id = SHARED_ID ) <EOL> assert_user_has_case ( self , self . other_user , case_id , restore_id = self . other_sync_log . get_id ) <EOL> @ run_with_all_backends <EOL> def testOtherUserEdits ( self ) : <EOL> case_id = "<STR_LIT>" <EOL> self . _createCaseStubs ( [ case_id ] , owner_id = SHARED_ID ) <EOL> assert_user_has_case ( self , self . other_user , case_id , restore_id = self . other_sync_log . get_id ) <EOL> latest_sync = SyncLog . last_for_user ( OTHER_USER_ID ) <EOL> self . _postFakeWithSyncToken ( <EOL> CaseBlock ( create = False , case_id = case_id , user_id = OTHER_USER_ID , <EOL> update = { '<STR_LIT>' : "<STR_LIT>" } <EOL> ) . as_xml ( ) , latest_sync . get_id ) <EOL> _ , match = assert_user_has_case ( self , self . user , case_id , restore_id = self . sync_log . get_id ) <EOL> self . assertTrue ( "<STR_LIT>" in match . to_string ( ) ) <EOL> @ run_with_all_backends <EOL> def testOtherUserAddsIndex ( self ) : <EOL> time = datetime . utcnow ( ) <EOL> case_id = "<STR_LIT>" <EOL> self . _createCaseStubs ( [ case_id ] , owner_id = SHARED_ID ) <EOL> assert_user_has_case ( self , self . other_user , case_id , restore_id = self . other_sync_log . get_id ) <EOL> latest_sync = SyncLog . last_for_user ( OTHER_USER_ID ) <EOL> mother_id = "<STR_LIT>" <EOL> parent_case = CaseBlock ( <EOL> create = True , <EOL> date_modified = time , <EOL> case_id = mother_id , <EOL> user_id = OTHER_USER_ID , <EOL> case_type = PARENT_TYPE , <EOL> ) . as_xml ( ) <EOL> self . _postFakeWithSyncToken ( <EOL> parent_case , <EOL> latest_sync . get_id <EOL> ) <EOL> assert_user_doesnt_have_case ( self , self . user , mother_id , restore_id = self . sync_log . get_id ) <EOL> self . _postFakeWithSyncToken ( <EOL> CaseBlock ( <EOL> create = False , <EOL> case_id = case_id , <EOL> user_id = OTHER_USER_ID , <EOL> owner_id = USER_ID , <EOL> index = { '<STR_LIT>' : ( '<STR_LIT>' , mother_id ) } <EOL> ) . as_xml ( ) , <EOL> latest_sync . get_id <EOL> ) <EOL> expected_parent_case = CaseBlock ( <EOL> create = True , <EOL> date_modified = time , <EOL> case_id = mother_id , <EOL> user_id = OTHER_USER_ID , <EOL> case_type = PARENT_TYPE , <EOL> owner_id = OTHER_USER_ID , <EOL> ) . as_xml ( ) <EOL> check_user_has_case ( self , self . user , expected_parent_case , <EOL> restore_id = self . sync_log . get_id , purge_restore_cache = True ) <EOL> _ , orig = assert_user_has_case ( self , self . user , case_id , restore_id = self . sync_log . get_id ) <EOL> self . assertTrue ( "<STR_LIT:index>" in orig . to_string ( ) ) <EOL> @ run_with_all_backends <EOL> def testMultiUserEdits ( self ) : <EOL> time = datetime . utcnow ( ) <EOL> case_id = "<STR_LIT>" <EOL> self . _createCaseStubs ( [ case_id ] , owner_id = SHARED_ID , date_modified = time ) <EOL> main_sync_log = synclog_from_restore_payload ( <EOL> generate_restore_payload ( self . project , self . user ) <EOL> ) <EOL> self . other_sync_log = synclog_from_restore_payload ( <EOL> generate_restore_payload ( self . project , self . other_user ) <EOL> ) <EOL> my_change = CaseBlock ( <EOL> create = False , <EOL> date_modified = time , <EOL> case_id = case_id , <EOL> user_id = USER_ID , <EOL> update = { '<STR_LIT>' : '<STR_LIT:hello>' } <EOL> ) . as_xml ( ) <EOL> self . _postFakeWithSyncToken ( <EOL> my_change , <EOL> main_sync_log . get_id <EOL> ) <EOL> their_change = CaseBlock ( <EOL> create = False , <EOL> date_modified = time , <EOL> case_id = case_id , <EOL> user_id = USER_ID , <EOL> update = { '<STR_LIT>' : '<STR_LIT:hello>' } <EOL> ) . as_xml ( ) <EOL> self . _postFakeWithSyncToken ( <EOL> their_change , <EOL> self . other_sync_log . get_id <EOL> ) <EOL> joint_change = CaseBlock ( <EOL> create = False , <EOL> date_modified = time , <EOL> case_id = case_id , <EOL> user_id = USER_ID , <EOL> update = { <EOL> '<STR_LIT>' : '<STR_LIT:hello>' , <EOL> '<STR_LIT>' : '<STR_LIT:hello>' <EOL> } , <EOL> owner_id = SHARED_ID , <EOL> case_name = '<STR_LIT>' , <EOL> case_type = '<STR_LIT>' , <EOL> ) . as_xml ( ) <EOL> check_user_has_case ( self , self . user , joint_change , restore_id = main_sync_log . get_id ) <EOL> check_user_has_case ( self , self . other_user , joint_change , restore_id = self . other_sync_log . get_id ) <EOL> @ run_with_all_backends <EOL> def testOtherUserCloses ( self ) : <EOL> case_id = "<STR_LIT>" <EOL> self . _createCaseStubs ( [ case_id ] , owner_id = SHARED_ID ) <EOL> other_sync_log = synclog_from_restore_payload ( <EOL> generate_restore_payload ( self . project , self . other_user ) <EOL> ) <EOL> close_block = CaseBlock ( <EOL> create = False , <EOL> case_id = case_id , <EOL> user_id = USER_ID , <EOL> close = True <EOL> ) . as_xml ( ) <EOL> self . _postFakeWithSyncToken ( <EOL> close_block , <EOL> other_sync_log . get_id <EOL> ) <EOL> assert_user_has_case ( self , self . user , case_id , restore_id = self . sync_log . _id ) <EOL> next_synclog = synclog_from_restore_payload ( <EOL> generate_restore_payload ( self . project , self . user , restore_id = self . sync_log . _id ) <EOL> ) <EOL> self . assertFalse ( next_synclog . phone_is_holding_case ( case_id ) ) <EOL> @ run_with_all_backends <EOL> def testOtherUserUpdatesUnowned ( self ) : <EOL> case_id = "<STR_LIT>" <EOL> self . _createCaseStubs ( [ case_id ] , owner_id = OTHER_USER_ID ) <EOL> assert_user_has_case ( self , self . other_user , case_id , restore_id = self . other_sync_log . get_id ) <EOL> self . other_sync_log = SyncLog . last_for_user ( OTHER_USER_ID ) <EOL> update = CaseBlock ( <EOL> create = False , <EOL> case_id = case_id , <EOL> user_id = OTHER_USER_ID , <EOL> update = { '<STR_LIT>' : '<STR_LIT:hello>' } <EOL> ) . as_xml ( ) <EOL> self . _postFakeWithSyncToken ( <EOL> update , <EOL> self . other_sync_log . get_id <EOL> ) <EOL> assert_user_doesnt_have_case ( self , self . user , case_id , restore_id = self . sync_log . get_id ) <EOL> @ run_with_all_backends <EOL> def testIndexesSync ( self ) : <EOL> parent_id = "<STR_LIT>" <EOL> case_id = "<STR_LIT>" <EOL> self . _createCaseStubs ( [ parent_id ] , owner_id = USER_ID ) <EOL> child = CaseBlock ( <EOL> create = True , <EOL> case_id = case_id , <EOL> user_id = USER_ID , <EOL> owner_id = USER_ID , <EOL> index = { '<STR_LIT>' : ( '<STR_LIT>' , parent_id ) } <EOL> ) . as_xml ( ) <EOL> self . _postFakeWithSyncToken ( child , self . sync_log . get_id ) <EOL> assert_user_doesnt_have_case ( self , self . other_user , parent_id , restore_id = self . other_sync_log . get_id ) <EOL> assert_user_doesnt_have_case ( self , self . other_user , case_id , restore_id = self . other_sync_log . get_id ) <EOL> child_update = CaseBlock ( <EOL> create = False , <EOL> case_id = case_id , <EOL> user_id = USER_ID , <EOL> owner_id = OTHER_USER_ID , <EOL> update = { "<STR_LIT>" : "<STR_LIT:hello>" } <EOL> ) . as_xml ( ) <EOL> self . _postFakeWithSyncToken ( child_update , self . sync_log . get_id ) <EOL> assert_user_has_case ( self , self . other_user , parent_id , restore_id = self . other_sync_log . get_id , <EOL> purge_restore_cache = True ) <EOL> assert_user_has_case ( self , self . other_user , case_id , restore_id = self . other_sync_log . get_id ) <EOL> @ run_with_all_backends <EOL> def testOtherUserUpdatesIndex ( self ) : <EOL> parent_id = "<STR_LIT>" <EOL> case_id = "<STR_LIT>" <EOL> self . _createCaseStubs ( [ parent_id ] ) <EOL> child = CaseBlock ( <EOL> create = True , <EOL> case_id = case_id , <EOL> user_id = USER_ID , <EOL> owner_id = USER_ID , <EOL> index = { '<STR_LIT>' : ( '<STR_LIT>' , parent_id ) } <EOL> ) . as_xml ( ) <EOL> self . _postFakeWithSyncToken ( child , self . sync_log . get_id ) <EOL> assert_user_doesnt_have_case ( self , self . user , parent_id , restore_id = self . sync_log . get_id ) <EOL> assert_user_doesnt_have_case ( self , self . user , case_id , restore_id = self . sync_log . get_id ) <EOL> parent_update = CaseBlock ( <EOL> create = False , <EOL> case_id = parent_id , <EOL> user_id = USER_ID , <EOL> owner_id = OTHER_USER_ID , <EOL> update = { "<STR_LIT>" : "<STR_LIT:hello>" } ) . as_xml ( ) <EOL> self . _postFakeWithSyncToken ( parent_update , self . sync_log . get_id ) <EOL> main_sync_log = get_properly_wrapped_sync_log ( self . sync_log . get_id ) <EOL> self . assertTrue ( main_sync_log . phone_is_holding_case ( case_id ) ) <EOL> self . assertTrue ( main_sync_log . phone_is_holding_case ( parent_id ) ) <EOL> assert_user_has_case ( self , self . other_user , parent_id , restore_id = self . other_sync_log . get_id , <EOL> purge_restore_cache = True ) <EOL> self . other_sync_log = SyncLog . last_for_user ( OTHER_USER_ID ) <EOL> other_parent_update = CaseBlock ( <EOL> create = False , <EOL> case_id = parent_id , <EOL> user_id = OTHER_USER_ID , <EOL> update = { "<STR_LIT>" : "<STR_LIT>" } , <EOL> ) . as_xml ( ) <EOL> self . _postFakeWithSyncToken ( other_parent_update , self . other_sync_log . get_id ) <EOL> latest_sync_log = SyncLog . last_for_user ( USER_ID ) <EOL> assert_user_has_case ( self , self . user , parent_id , restore_id = latest_sync_log . get_id , <EOL> purge_restore_cache = True ) <EOL> @ run_with_all_backends <EOL> def testOtherUserReassignsIndexed ( self ) : <EOL> parent_id = "<STR_LIT>" <EOL> case_id = "<STR_LIT>" <EOL> self . factory . create_or_update_cases ( [ <EOL> CaseStructure ( <EOL> case_id = case_id , <EOL> attrs = { '<STR_LIT>' : True } , <EOL> indices = [ CaseIndex ( <EOL> CaseStructure ( case_id = parent_id , attrs = { '<STR_LIT>' : True } ) , <EOL> relationship = CHILD_RELATIONSHIP , <EOL> related_type = PARENT_TYPE , <EOL> ) ] , <EOL> ) <EOL> ] ) <EOL> parent_update = CaseBlock ( <EOL> create = False , <EOL> case_id = parent_id , <EOL> user_id = USER_ID , <EOL> owner_id = OTHER_USER_ID , <EOL> update = { "<STR_LIT>" : "<STR_LIT:hello>" } ) . as_xml ( ) <EOL> self . _postFakeWithSyncToken ( parent_update , self . sync_log . get_id ) <EOL> other_sync_log = synclog_from_restore_payload ( <EOL> generate_restore_payload ( self . project , self . other_user ) <EOL> ) <EOL> child_reassignment = CaseBlock ( <EOL> create = False , <EOL> case_id = case_id , <EOL> user_id = OTHER_USER_ID , <EOL> owner_id = OTHER_USER_ID , <EOL> update = { "<STR_LIT>" : "<STR_LIT>" } , <EOL> ) . as_xml ( ) <EOL> self . _postFakeWithSyncToken ( child_reassignment , other_sync_log . get_id ) <EOL> other_parent_update = CaseBlock ( <EOL> create = False , <EOL> case_id = parent_id , <EOL> user_id = OTHER_USER_ID , <EOL> owner_id = OTHER_USER_ID , <EOL> update = { "<STR_LIT>" : "<STR_LIT>" } ) . as_xml ( ) <EOL> self . _postFakeWithSyncToken ( other_parent_update , other_sync_log . get_id ) <EOL> latest_sync_log = SyncLog . last_for_user ( self . user . user_id ) <EOL> assert_user_has_case ( self , self . user , case_id , restore_id = latest_sync_log . get_id ) <EOL> assert_user_has_case ( self , self . user , parent_id , restore_id = latest_sync_log . get_id ) <EOL> payload = generate_restore_payload ( self . project , self . user , latest_sync_log . get_id , version = V2 ) <EOL> self . assertTrue ( "<STR_LIT>" in payload ) <EOL> self . assertTrue ( "<STR_LIT>" in payload ) <EOL> log = synclog_from_restore_payload ( payload ) <EOL> self . assertFalse ( log . phone_is_holding_case ( case_id ) ) <EOL> self . assertFalse ( log . phone_is_holding_case ( parent_id ) ) <EOL> other_parent_update = CaseBlock ( <EOL> create = False , <EOL> case_id = parent_id , <EOL> user_id = OTHER_USER_ID , <EOL> owner_id = OTHER_USER_ID , <EOL> update = { "<STR_LIT>" : "<STR_LIT>" } ) . as_xml ( ) <EOL> self . _postFakeWithSyncToken ( other_parent_update , other_sync_log . get_id ) <EOL> latest_sync_log = SyncLog . last_for_user ( self . user . user_id ) <EOL> assert_user_doesnt_have_case ( self , self . user , case_id , restore_id = latest_sync_log . get_id ) <EOL> assert_user_doesnt_have_case ( self , self . user , parent_id , restore_id = latest_sync_log . get_id ) <EOL> other_child_update = CaseBlock ( <EOL> create = False , <EOL> case_id = case_id , <EOL> user_id = OTHER_USER_ID , <EOL> owner_id = OTHER_USER_ID , <EOL> update = { "<STR_LIT>" : "<STR_LIT>" } , <EOL> ) . as_xml ( ) <EOL> self . _postFakeWithSyncToken ( other_child_update , other_sync_log . get_id ) <EOL> latest_sync_log = SyncLog . last_for_user ( self . user . user_id ) <EOL> assert_user_doesnt_have_case ( self , self . user , case_id , restore_id = latest_sync_log . get_id ) <EOL> assert_user_doesnt_have_case ( self , self . user , parent_id , restore_id = latest_sync_log . get_id ) <EOL> child_reassignment = CaseBlock ( <EOL> create = False , <EOL> case_id = case_id , <EOL> user_id = OTHER_USER_ID , <EOL> owner_id = USER_ID , <EOL> ) . as_xml ( ) <EOL> self . _postFakeWithSyncToken ( child_reassignment , other_sync_log . get_id ) <EOL> latest_sync_log = SyncLog . last_for_user ( self . user . user_id ) <EOL> assert_user_has_case ( self , self . user , case_id , restore_id = latest_sync_log . get_id ) <EOL> assert_user_has_case ( self , self . user , parent_id , restore_id = latest_sync_log . get_id ) <EOL> payload = generate_restore_payload ( <EOL> self . project , self . user , latest_sync_log . get_id , version = V2 <EOL> ) <EOL> self . assertTrue ( "<STR_LIT>" in payload ) <EOL> self . assertTrue ( "<STR_LIT>" in payload ) <EOL> @ run_with_all_backends <EOL> def testComplicatedGatesBug ( self ) : <EOL> folder_path = os . path . join ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> files = [ "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" ] <EOL> for f in files : <EOL> form = self . _postWithSyncToken ( os . path . join ( folder_path , f ) , self . sync_log . get_id ) <EOL> self . assertFalse ( hasattr ( form , "<STR_LIT>" ) and form . problem ) <EOL> synclog_from_restore_payload ( <EOL> generate_restore_payload ( self . project , self . user , version = "<STR_LIT>" ) <EOL> ) <EOL> @ run_with_all_backends <EOL> def test_dependent_case_becomes_relevant_at_sync_time ( self ) : <EOL> """<STR_LIT>""" <EOL> parent_id , child_id = [ uuid . uuid4 ( ) . hex for i in range ( <NUM_LIT:2> ) ] <EOL> self . factory . create_or_update_cases ( [ <EOL> CaseStructure ( <EOL> case_id = child_id , <EOL> attrs = { '<STR_LIT>' : True } , <EOL> indices = [ CaseIndex ( <EOL> CaseStructure ( case_id = parent_id , attrs = { '<STR_LIT>' : True , '<STR_LIT>' : uuid . uuid4 ( ) . hex } ) , <EOL> relationship = CHILD_RELATIONSHIP , <EOL> related_type = PARENT_TYPE , <EOL> identifier = PARENT_TYPE , <EOL> ) ] , <EOL> ) <EOL> ] ) <EOL> index_ref = CommCareCaseIndex ( identifier = PARENT_TYPE , <EOL> referenced_type = PARENT_TYPE , <EOL> referenced_id = parent_id ) <EOL> self . _testUpdate ( self . sync_log . _id , { child_id : [ index_ref ] } , { parent_id : [ ] } ) <EOL> self . factory . create_or_update_cases ( <EOL> [ <EOL> CaseStructure ( <EOL> case_id = parent_id , <EOL> attrs = { '<STR_LIT>' : SHARED_ID } , <EOL> ) <EOL> ] , <EOL> form_extras = { '<STR_LIT>' : None } <EOL> ) <EOL> latest_sync_log = synclog_from_restore_payload ( <EOL> generate_restore_payload ( self . project , self . user , restore_id = self . sync_log . _id ) <EOL> ) <EOL> self . _testUpdate ( latest_sync_log . _id , { child_id : [ index_ref ] , parent_id : [ ] } ) <EOL> @ run_with_all_backends <EOL> def test_index_tree_conflict_handling ( self ) : <EOL> """<STR_LIT>""" <EOL> mom_id , dad_id , child_id = [ uuid . uuid4 ( ) . hex for i in range ( <NUM_LIT:3> ) ] <EOL> self . factory . create_or_update_cases ( [ <EOL> CaseStructure ( <EOL> case_id = child_id , <EOL> attrs = { '<STR_LIT>' : True } , <EOL> indices = [ <EOL> CaseIndex ( <EOL> CaseStructure ( case_id = mom_id , attrs = { '<STR_LIT>' : True } ) , <EOL> relationship = CHILD_RELATIONSHIP , <EOL> related_type = '<STR_LIT>' , <EOL> identifier = '<STR_LIT>' , <EOL> ) , <EOL> CaseIndex ( <EOL> CaseStructure ( case_id = dad_id , attrs = { '<STR_LIT>' : True } ) , <EOL> relationship = CHILD_RELATIONSHIP , <EOL> related_type = '<STR_LIT>' , <EOL> identifier = '<STR_LIT>' , <EOL> ) , <EOL> ] , <EOL> ) <EOL> ] ) <EOL> mom_ref = CommCareCaseIndex ( identifier = '<STR_LIT>' , referenced_type = '<STR_LIT>' , referenced_id = mom_id ) <EOL> dad_ref = CommCareCaseIndex ( identifier = '<STR_LIT>' , referenced_type = '<STR_LIT>' , referenced_id = dad_id ) <EOL> self . _testUpdate ( self . sync_log . _id , { child_id : [ mom_ref , dad_ref ] , mom_id : [ ] , dad_id : [ ] } ) <EOL> new_mom_id = uuid . uuid4 ( ) . hex <EOL> self . factory . create_or_update_cases ( <EOL> [ <EOL> CaseStructure ( <EOL> case_id = child_id , <EOL> indices = [ <EOL> CaseIndex ( <EOL> CaseStructure ( case_id = new_mom_id , attrs = { '<STR_LIT>' : True } ) , <EOL> relationship = CHILD_RELATIONSHIP , <EOL> related_type = '<STR_LIT>' , <EOL> identifier = '<STR_LIT>' , <EOL> ) , <EOL> ] <EOL> ) <EOL> ] , <EOL> form_extras = { '<STR_LIT>' : None } <EOL> ) <EOL> latest_sync_log = synclog_from_restore_payload ( <EOL> generate_restore_payload ( self . project , self . user , restore_id = self . sync_log . _id ) <EOL> ) <EOL> new_mom_ref = CommCareCaseIndex ( identifier = '<STR_LIT>' , referenced_type = '<STR_LIT>' , referenced_id = new_mom_id ) <EOL> self . _testUpdate ( latest_sync_log . _id , { <EOL> child_id : [ new_mom_ref , dad_ref ] , mom_id : [ ] , dad_id : [ ] , new_mom_id : [ ] <EOL> } ) <EOL> class SteadyStateExtensionSyncTest ( SyncBaseTest ) : <EOL> """<STR_LIT>""" <EOL> def setUp ( self ) : <EOL> super ( SteadyStateExtensionSyncTest , self ) . setUp ( ) <EOL> self . other_user = User ( user_id = OTHER_USER_ID , username = OTHER_USERNAME , <EOL> password = "<STR_LIT>" , date_joined = datetime ( <NUM_LIT> , <NUM_LIT:6> , <NUM_LIT:9> ) , <EOL> additional_owner_ids = [ SHARED_ID ] ) <EOL> self . _create_ownership_cleanliness ( USER_ID ) <EOL> self . _create_ownership_cleanliness ( OTHER_USER_ID ) <EOL> def _create_ownership_cleanliness ( self , user_id ) : <EOL> OwnershipCleanlinessFlag . objects . get_or_create ( <EOL> owner_id = USER_ID , <EOL> domain = self . project . name , <EOL> defaults = { '<STR_LIT>' : True } <EOL> ) <EOL> def _create_extension ( self ) : <EOL> host = CaseStructure ( case_id = '<STR_LIT:host>' , <EOL> attrs = { '<STR_LIT>' : True } ) <EOL> extension = CaseStructure ( <EOL> case_id = '<STR_LIT>' , <EOL> attrs = { '<STR_LIT>' : True , '<STR_LIT>' : '<STR_LIT:->' } , <EOL> indices = [ CaseIndex ( <EOL> host , <EOL> identifier = '<STR_LIT>' , <EOL> relationship = '<STR_LIT>' , <EOL> related_type = '<STR_LIT>' , <EOL> ) ] , <EOL> ) <EOL> self . factory . create_or_update_case ( extension ) <EOL> return host , extension <EOL> @ flag_enabled ( '<STR_LIT>' ) <EOL> @ run_with_all_backends <EOL> def test_delegating_extensions ( self ) : <EOL> """<STR_LIT>""" <EOL> host , extension = self . _create_extension ( ) <EOL> assert_user_has_case ( self , self . user , host . case_id ) <EOL> assert_user_doesnt_have_case ( self , self . other_user , host . case_id ) <EOL> re_assigned_extension = CaseStructure ( <EOL> case_id = '<STR_LIT>' , <EOL> attrs = { '<STR_LIT>' : OTHER_USER_ID } <EOL> ) <EOL> self . factory . create_or_update_case ( re_assigned_extension ) <EOL> assert_user_has_case ( self , self . other_user , host . case_id ) <EOL> sync_log_id = SyncLog . last_for_user ( USER_ID ) . _id <EOL> assert_user_has_case ( self , self . user , extension . case_id , <EOL> restore_id = sync_log_id ) <EOL> assert_user_doesnt_have_case ( self , self . user , host . case_id , <EOL> restore_id = sync_log_id ) <EOL> sync_again_id = SyncLog . last_for_user ( USER_ID ) . _id <EOL> assert_user_doesnt_have_case ( self , self . user , extension . case_id , <EOL> restore_id = sync_again_id ) <EOL> assert_user_doesnt_have_case ( self , self . user , host . case_id , <EOL> restore_id = sync_again_id ) <EOL> re_assigned_extension = CaseStructure ( <EOL> case_id = '<STR_LIT>' , <EOL> attrs = { '<STR_LIT>' : '<STR_LIT:->' } <EOL> ) <EOL> self . factory . create_or_update_case ( re_assigned_extension ) <EOL> assert_user_has_case ( self , self . other_user , extension . case_id , <EOL> restore_id = SyncLog . last_for_user ( OTHER_USER_ID ) . _id ) <EOL> assert_user_has_case ( self , self . user , extension . case_id , restore_id = SyncLog . last_for_user ( USER_ID ) . _id ) <EOL> assert_user_doesnt_have_case ( self , self . other_user , extension . case_id , <EOL> restore_id = SyncLog . last_for_user ( OTHER_USER_ID ) . _id ) <EOL> @ flag_enabled ( '<STR_LIT>' ) <EOL> @ run_with_all_backends <EOL> def test_multiple_syncs ( self ) : <EOL> host , extension = self . _create_extension ( ) <EOL> assert_user_has_case ( self , self . user , host . case_id ) <EOL> assert_user_has_case ( self , self . user , extension . case_id ) <EOL> sync_log = SyncLog . last_for_user ( USER_ID ) <EOL> self . assertItemsEqual ( sync_log . case_ids_on_phone , [ '<STR_LIT:host>' , '<STR_LIT>' ] ) <EOL> generate_restore_payload ( self . project , self . user , restore_id = sync_log . _id , version = V2 ) <EOL> second_sync_log = SyncLog . last_for_user ( USER_ID ) <EOL> self . assertItemsEqual ( second_sync_log . case_ids_on_phone , [ '<STR_LIT:host>' , '<STR_LIT>' ] ) <EOL> generate_restore_payload ( self . project , self . user , restore_id = second_sync_log . _id , version = V2 ) <EOL> third_sync_log = SyncLog . last_for_user ( USER_ID ) <EOL> self . assertItemsEqual ( third_sync_log . case_ids_on_phone , [ '<STR_LIT:host>' , '<STR_LIT>' ] ) <EOL> class SyncTokenReprocessingTest ( SyncBaseTest ) : <EOL> """<STR_LIT>""" <EOL> @ run_with_all_backends <EOL> def testUpdateNonExisting ( self ) : <EOL> case_id = '<STR_LIT>' <EOL> caseblock = CaseBlock ( <EOL> create = False , <EOL> case_id = case_id , <EOL> user_id = USER_ID , <EOL> owner_id = USER_ID , <EOL> case_type = PARENT_TYPE , <EOL> ) . as_xml ( ) <EOL> try : <EOL> self . _postFakeWithSyncToken ( caseblock , self . sync_log . get_id ) <EOL> self . fail ( '<STR_LIT>' ) <EOL> except AssertionError : <EOL> pass <EOL> @ run_with_all_backends <EOL> def testShouldHaveCase ( self ) : <EOL> case_id = "<STR_LIT>" <EOL> self . _createCaseStubs ( [ case_id ] ) <EOL> sync_log = get_properly_wrapped_sync_log ( self . sync_log . _id ) <EOL> cases_on_phone = sync_log . tests_only_get_cases_on_phone ( ) <EOL> self . assertEqual ( <NUM_LIT:1> , len ( cases_on_phone ) ) <EOL> self . assertEqual ( case_id , cases_on_phone [ <NUM_LIT:0> ] . case_id ) <EOL> sync_log . test_only_clear_cases_on_phone ( ) <EOL> sync_log . save ( ) <EOL> update = CaseBlock ( <EOL> create = False , <EOL> case_id = case_id , <EOL> user_id = USER_ID , <EOL> owner_id = USER_ID , <EOL> case_type = PARENT_TYPE , <EOL> update = { '<STR_LIT>' : "<STR_LIT>" } , <EOL> ) . as_xml ( ) <EOL> self . _postFakeWithSyncToken ( update , self . sync_log . get_id ) <EOL> sync_log = get_properly_wrapped_sync_log ( self . sync_log . _id ) <EOL> self . assertFalse ( getattr ( sync_log , '<STR_LIT>' , False ) ) <EOL> @ run_with_all_backends <EOL> def testCodependencies ( self ) : <EOL> case_id1 = '<STR_LIT>' <EOL> case_id2 = '<STR_LIT>' <EOL> initial_caseblocks = [ CaseBlock ( <EOL> create = True , <EOL> case_id = case_id , <EOL> user_id = '<STR_LIT>' , <EOL> owner_id = '<STR_LIT>' , <EOL> case_type = PARENT_TYPE , <EOL> ) . as_xml ( ) for case_id in [ case_id1 , case_id2 ] ] <EOL> post_case_blocks ( <EOL> initial_caseblocks , <EOL> ) <EOL> def _get_bad_caseblocks ( ids ) : <EOL> return [ CaseBlock ( <EOL> create = False , <EOL> case_id = id , <EOL> user_id = USER_ID , <EOL> owner_id = USER_ID , <EOL> case_type = PARENT_TYPE , <EOL> ) . as_xml ( ) for id in ids ] <EOL> try : <EOL> post_case_blocks ( <EOL> _get_bad_caseblocks ( [ case_id1 , case_id2 ] ) , <EOL> form_extras = { "<STR_LIT>" : self . sync_log . _id } <EOL> ) <EOL> self . fail ( '<STR_LIT>' ) <EOL> except AssertionError : <EOL> pass <EOL> try : <EOL> post_case_blocks ( <EOL> _get_bad_caseblocks ( [ case_id2 , case_id1 ] ) , <EOL> form_extras = { "<STR_LIT>" : self . sync_log . _id } <EOL> ) <EOL> self . fail ( '<STR_LIT>' ) <EOL> except AssertionError : <EOL> pass <EOL> class LooseSyncTokenValidationTest ( SyncBaseTest ) : <EOL> @ run_with_all_backends <EOL> def test_submission_with_bad_log_default ( self ) : <EOL> with self . assertRaises ( ResourceNotFound ) : <EOL> post_case_blocks ( <EOL> [ CaseBlock ( create = True , case_id = '<STR_LIT>' ) . as_xml ( ) ] , <EOL> form_extras = { "<STR_LIT>" : '<STR_LIT>' } , <EOL> domain = '<STR_LIT>' , <EOL> ) <EOL> @ run_with_all_backends <EOL> def test_submission_with_bad_log_toggle_enabled ( self ) : <EOL> domain = '<STR_LIT>' <EOL> def _test ( ) : <EOL> post_case_blocks ( <EOL> [ CaseBlock ( create = True , case_id = '<STR_LIT>' ) . as_xml ( ) ] , <EOL> form_extras = { "<STR_LIT>" : '<STR_LIT>' } , <EOL> domain = domain , <EOL> ) <EOL> LOOSE_SYNC_TOKEN_VALIDATION . set ( domain , False , namespace = '<STR_LIT>' ) <EOL> with self . assertRaises ( ResourceNotFound ) : <EOL> _test ( ) <EOL> LOOSE_SYNC_TOKEN_VALIDATION . set ( domain , True , namespace = '<STR_LIT>' ) <EOL> _test ( ) <EOL> @ run_with_all_backends <EOL> def test_restore_with_bad_log_default ( self ) : <EOL> with self . assertRaises ( MissingSyncLog ) : <EOL> RestoreConfig ( <EOL> project = Domain ( name = "<STR_LIT>" ) , <EOL> user = self . user , <EOL> params = RestoreParams ( <EOL> version = V2 , <EOL> sync_log_id = '<STR_LIT>' , <EOL> ) , <EOL> ) . get_payload ( ) <EOL> @ run_with_all_backends <EOL> def test_restore_with_bad_log_toggle_enabled ( self ) : <EOL> domain = '<STR_LIT>' <EOL> def _test ( ) : <EOL> RestoreConfig ( <EOL> project = Domain ( name = domain ) , <EOL> user = self . user , <EOL> params = RestoreParams ( <EOL> version = V2 , <EOL> sync_log_id = '<STR_LIT>' , <EOL> ) <EOL> ) . get_payload ( ) <EOL> LOOSE_SYNC_TOKEN_VALIDATION . set ( domain , False , namespace = '<STR_LIT>' ) <EOL> with self . assertRaises ( MissingSyncLog ) : <EOL> _test ( ) <EOL> LOOSE_SYNC_TOKEN_VALIDATION . set ( domain , True , namespace = '<STR_LIT>' ) <EOL> with self . assertRaises ( RestoreException ) : <EOL> _test ( ) </s>
