def test_get_sobject_ids_for_reference_returns_correct_ids(self): connection = Mock() oc = amaxa.ExtractOperation(connection) oc.file_store = MockFileStore() oc.get_field_map = Mock( return_value={"Lookup__c": {"referenceTo": ["Account", "Contact"]}} ) oc.store_result( "Account", {"Id": "001000000000000", "Name": "University of Caprica"} ) oc.store_result("Contact", {"Id": "003000000000000", "Name": "Gaius Baltar"}) oc.store_result( "Opportunity", {"Id": "006000000000000", "Name": "Defense Mainframe"} ) self.assertEqual( set( [ amaxa.SalesforceId("001000000000000"), amaxa.SalesforceId("003000000000000"), ] ), oc.get_sobject_ids_for_reference("Account", "Lookup__c"), )
def test_execute_transforms_and_loads_records_without_lookups(self): record_list = [ { "Name": "Test", "Id": "001000000000000" }, { "Name": "Test 2", "Id": "001000000000001" }, ] clean_record_list = [{"Name": "Test"}, {"Name": "Test 2"}] connection = MockConnection(bulk_insert_results=[ UploadResult("001000000000002", True, True, ""), UploadResult("001000000000003", True, True, ""), ]) op = amaxa.LoadOperation(Mock(wraps=connection)) op.file_store = MockFileStore() op.register_new_id = Mock() op.file_store.records["Account"] = record_list op.mappers["Account"] = Mock() op.mappers["Account"].transform_record = Mock(side_effect=lambda x: x) load_step = amaxa.LoadStep("Account", ["Name"]) op.add_step(load_step) load_step.primitivize = Mock(side_effect=lambda x: x) load_step.populate_lookups = Mock(side_effect=lambda x, y, z: x) load_step.initialize() load_step.execute() op.mappers["Account"].transform_record.assert_has_calls( [unittest.mock.call(x) for x in record_list]) load_step.primitivize.assert_has_calls( [unittest.mock.call(x) for x in clean_record_list]) load_step.populate_lookups.assert_has_calls([ unittest.mock.call(x, set(), y["Id"]) for (x, y) in zip(clean_record_list, record_list) ]) op.connection.bulk_api_insert.assert_called_once_with( "Account", clean_record_list, load_step.get_option("bulk-api-timeout"), load_step.get_option("bulk-api-poll-interval"), load_step.get_option("bulk-api-batch-size"), load_step.get_option("bulk-api-mode"), ) op.register_new_id.assert_has_calls([ unittest.mock.call( "Account", amaxa.SalesforceId("001000000000000"), amaxa.SalesforceId("001000000000002"), ), unittest.mock.call( "Account", amaxa.SalesforceId("001000000000001"), amaxa.SalesforceId("001000000000003"), ), ])
def test_resolve_registered_dependencies_loads_records(self): oc = Mock() id_set = set([ amaxa.SalesforceId("001000000000001"), amaxa.SalesforceId("001000000000002"), ]) oc.get_dependencies = Mock(side_effect=[ id_set, set([amaxa.SalesforceId("001000000000002")]), ]) oc.connection.retrieve_records_by_id = Mock( return_value=[{ "Id": amaxa.SalesforceId("001000000000001") }]) step = amaxa.ExtractionStep("Account", amaxa.ExtractionScope.ALL_RECORDS, ["Id"]) step.context = oc step.store_result = Mock() step.resolve_registered_dependencies() oc.connection.retrieve_records_by_id.assert_called_once_with( "Account", id_set, ["Id"]) step.store_result.assert_called_once_with( {"Id": amaxa.SalesforceId("001000000000001")}) oc.get_dependencies.assert_has_calls( [unittest.mock.call("Account"), unittest.mock.call("Account")]) assert step.errors == [ "Unable to resolve dependencies for sObject Account. The following Ids could not be found: 001000000000002AAA" ]
def test_execute_loads_high_volume_records(self): connection = MockConnection(bulk_insert_results=[ UploadResult("001000000{:06d}".format(i + 1), True, True, "") for i in range(20000) ]) op = amaxa.LoadOperation(Mock(wraps=connection)) op.file_store = MockFileStore() op.register_new_id = Mock() record_list = [{ "Id": "001000000{:06d}".format(i), "Name": "Account {:06d}".format(i) } for i in range(20000)] op.file_store.records["Account"] = record_list op.get_result_file = Mock() load_step = amaxa.LoadStep("Account", ["Name"]) op.add_step(load_step) load_step.initialize() load_step.execute() self.assertEqual(20000, op.register_new_id.call_count) # Validate that the correct Ids were mapped # Each Id should be mapped to itself plus one. for index, each_call in enumerate(op.register_new_id.call_args_list): self.assertEqual( unittest.mock.call( "Account", amaxa.SalesforceId("001000000{:06d}".format(index)), amaxa.SalesforceId("001000000{:06d}".format(index + 1)), ), each_call, )
def test_execute_dependent_updates_handles_errors(self): record_list = [ { "Name": "Test", "Id": "001000000000000", "ParentId": "001000000000001" }, { "Name": "Test 2", "Id": "001000000000001", "ParentId": "001000000000000" }, ] error = [{ "statusCode": "DUPLICATES_DETECTED", "message": "There are duplicates", "fields": [], "extendedErrorDetails": None, }] connection = MockConnection(bulk_update_results=[ UploadResult(None, False, False, error), UploadResult(None, False, False, error), ]) op = amaxa.LoadOperation(Mock(wraps=connection)) op.file_store = MockFileStore() op.register_new_id( "Account", amaxa.SalesforceId("001000000000000"), amaxa.SalesforceId("001000000000002"), ) op.register_new_id( "Account", amaxa.SalesforceId("001000000000001"), amaxa.SalesforceId("001000000000003"), ) op.register_new_id = Mock() op.register_error = Mock() op.file_store.records["Account"] = record_list load_step = amaxa.LoadStep("Account", ["Name", "ParentId"]) op.add_step(load_step) load_step.initialize() load_step.execute_dependent_updates() self.assertEqual( [ unittest.mock.call("Account", record_list[0]["Id"], load_step.format_error(error)), unittest.mock.call("Account", record_list[1]["Id"], load_step.format_error(error)), ], op.register_error.call_args_list, )
def test_add_dependency_tracks_dependencies(self): connection = Mock() oc = amaxa.ExtractOperation(connection) self.assertEqual(set(), oc.get_dependencies("Account")) oc.add_dependency("Account", amaxa.SalesforceId("001000000000000")) self.assertEqual( set([amaxa.SalesforceId("001000000000000")]), oc.get_dependencies("Account") )
def test_execute_dependent_updates_uses_bulk_api_options(self): record_list = [ {"Name": "Test", "Id": "001000000000000", "ParentId": "001000000000001"}, {"Name": "Test 2", "Id": "001000000000001", "ParentId": "001000000000000"}, ] cleaned_record_list = [ {"Id": "001000000000002AAA", "ParentId": "001000000000003AAA"}, {"Id": "001000000000003AAA", "ParentId": "001000000000002AAA"}, ] connection = MockConnection( bulk_update_results=[ UploadResult("001000000000002", True, True, ""), UploadResult("001000000000003", True, True, ""), ] ) op = amaxa.LoadOperation(Mock(wraps=connection)) op.file_store = MockFileStore() op.register_new_id( "Account", amaxa.SalesforceId("001000000000000"), amaxa.SalesforceId("001000000000002"), ) op.register_new_id( "Account", amaxa.SalesforceId("001000000000001"), amaxa.SalesforceId("001000000000003"), ) op.register_new_id = Mock() op.register_error = Mock() op.file_store.records["Account"] = record_list load_step = amaxa.LoadStep( "Account", ["Name", "ParentId"], options={ "bulk-api-poll-interval": 10, "bulk-api-timeout": 600, "bulk-api-batch-size": 5000, "bulk-api-mode": "Serial", }, ) op.add_step(load_step) load_step.initialize() load_step.execute_dependent_updates() op.connection.bulk_api_update.assert_called_once_with( "Account", cleaned_record_list, 600, 10, 5000, "Serial" )
def test_main_saves_state_on_error(self, operation_mock, credential_mock): context = Mock() op = Mock() op.run = Mock(return_value=-1) op.stage = amaxa.LoadStage.INSERTS op.global_id_map = { amaxa.SalesforceId("001000000000001"): amaxa.SalesforceId("001000000000002") } credential_mock.return_value = Mock() credential_mock.return_value.result = context credential_mock.return_value.errors = [] operation_mock.return_value = Mock() operation_mock.return_value.result = op operation_mock.return_value.errors = [] state_file.close = Mock() m = Mock(side_effect=select_file) with unittest.mock.patch("builtins.open", m): with unittest.mock.patch( "sys.argv", [ "amaxa", "-c", "credentials-good.yaml", "--load", "extraction-good.yaml", ], ): return_value = main() self.assertEqual(-1, return_value) contents = state_file.getvalue() self.assertLess(0, len(contents)) state_file.close.assert_called_once_with() yaml_state = yaml.safe_load(io.StringIO(contents)) self.assertIn("state", yaml_state) self.assertIn("id-map", yaml_state["state"]) self.assertIn("stage", yaml_state["state"]) self.assertEqual(amaxa.LoadStage.INSERTS.value, yaml_state["state"]["stage"]) self.assertEqual( {str(k): str(v) for k, v in op.global_id_map.items()}, yaml_state["state"]["id-map"], )
def test_maps_record_ids(self): connection = Mock() op = amaxa.LoadOperation(connection) op.file_store = MockFileStore() op.register_new_id( "Account", amaxa.SalesforceId("001000000000000"), amaxa.SalesforceId("001000000000001"), ) self.assertEqual( amaxa.SalesforceId("001000000000001"), op.get_new_id(amaxa.SalesforceId("001000000000000")), )
def test_query_records_by_reference_field(self): sf = Mock() sf.bulk_url = "https://salesforce.com" conn = Connection(sf) id_set = [] for i in range(400): new_id = str(amaxa.SalesforceId("00100000000" + str(i + 1).zfill(4))) id_set.append(new_id) api_return_value = { "records": [ {"Id": "001000000000001", "Name": "test", "Industry": "Finance"} ] } sf.query_all.return_value = api_return_value retval = list( conn.query_records_by_reference_field( "Account", ["Name", "Industry"], "ParentId", id_set ) ) self.assertGreater(sf.query_all.call_count, 1) self.assertEqual(api_return_value["records"] * sf.query_all.call_count, retval) # Validate that the WHERE clause length limits were respected # and that all of the Ids were queried total_ids = 0 for each_call in sf.query_all.call_args_list: argument = each_call[0][0] self.assertLessEqual(len(argument[argument.find("WHERE") :]), 4000) total_ids += argument.count("'001") self.assertEqual(len(id_set), total_ids)
def test_store_result_registers_self_lookup_dependencies(self): connection = Mock() oc = amaxa.ExtractOperation(connection) oc.store_result = Mock() oc.add_dependency = Mock() oc.get_field_map = Mock( return_value={ "Lookup__c": { "name": "Lookup__c", "type": "reference", "referenceTo": ["Account"], } }) oc.get_sobject_list = Mock(return_value=["Account"]) step = amaxa.ExtractionStep("Account", amaxa.ExtractionScope.ALL_RECORDS, ["Lookup__c"]) oc.add_step(step) step.initialize() step.store_result({ "Id": "001000000000000", "Lookup__c": "001000000000001", "Name": "Picon Fleet Headquarters", }) oc.add_dependency.assert_called_once_with( "Account", amaxa.SalesforceId("001000000000001"))
def test_hashing(self): id_set = set() for i in range(400): new_id = amaxa.SalesforceId("001000000000" + str(i + 1).zfill(3)) self.assertNotIn(new_id, id_set) id_set.add(new_id) self.assertIn(new_id, id_set)
def test_store_result_clears_dependencies(self): connection = Mock() oc = amaxa.ExtractOperation(connection) oc.file_store = MockFileStore() oc.add_dependency("Account", amaxa.SalesforceId("001000000000000")) oc.store_result("Account", {"Id": "001000000000000", "Name": "Caprica Steel"}) self.assertEqual(set(), oc.get_dependencies("Account"))
def test_get_value_for_lookup_with_parent_available(self): connection = Mock() op = amaxa.LoadOperation(connection) op.file_store = Mock() op.register_new_id( "Account", amaxa.SalesforceId("001000000000000"), amaxa.SalesforceId("001000000000001"), ) load_step = amaxa.LoadStep("Account", ["Name", "ParentId"]) op.add_step(load_step) self.assertEqual( load_step.get_value_for_lookup("ParentId", "001000000000000", "001000000000002"), str(amaxa.SalesforceId("001000000000001")), )
def test_store_result_retains_ids(self): connection = Mock() oc = amaxa.ExtractOperation(connection) oc.file_store = MockFileStore() oc.store_result("Account", {"Id": "001000000000000", "Name": "Caprica Steel"}) self.assertEqual( set([amaxa.SalesforceId("001000000000000")]), oc.extracted_ids["Account"] )
def test_main_loads_state_with_use_state_option( self, operation_mock, credential_mock ): context = Mock() op = Mock() op.run = Mock(return_value=0) credential_mock.return_value = Mock() credential_mock.return_value.result = context credential_mock.return_value.errors = [] operation_mock.return_value = Mock() operation_mock.return_value.result = op operation_mock.return_value.errors = [] m = Mock(side_effect=select_file) with unittest.mock.patch("builtins.open", m): with unittest.mock.patch( "sys.argv", [ "amaxa", "-c", "credentials-good.yaml", "--load", "extraction-good.yaml", "--use-state", "state-good.yaml", ], ): return_value = main() self.assertEqual(0, return_value) self.assertEqual(amaxa.LoadStage.INSERTS, op.stage) self.assertEqual( { amaxa.SalesforceId("001000000000001"): amaxa.SalesforceId( "001000000000002" ), amaxa.SalesforceId("001000000000003"): amaxa.SalesforceId( "001000000000004" ), }, op.global_id_map, )
def test_register_new_id_writes_result_entries(self): connection = Mock() op = amaxa.LoadOperation(connection) op.file_store = MockFileStore() op.register_new_id( "Account", amaxa.SalesforceId("001000000000000"), amaxa.SalesforceId("001000000000001"), ) op.file_store.get_csv( "Account", amaxa.FileType.RESULT ).writerow.assert_called_once_with( { constants.ORIGINAL_ID: str(amaxa.SalesforceId("001000000000000")), constants.NEW_ID: str(amaxa.SalesforceId("001000000000001")), } )
def test_resolve_registered_dependencies_registers_error_for_missing_ids( self): connection = Mock() oc = amaxa.ExtractOperation(connection) oc.get_field_map = Mock( return_value={ "Lookup__c": { "name": "Lookup__c", "type": "reference", "referenceTo": ["Account"], } }) oc.get_dependencies = Mock(side_effect=[ set([ amaxa.SalesforceId("001000000000001"), amaxa.SalesforceId("001000000000002"), ]), set([amaxa.SalesforceId("001000000000002")]), ]) step = amaxa.ExtractionStep("Account", amaxa.ExtractionScope.ALL_RECORDS, ["Lookup__c"]) connection.retrieve_records_by_id = Mock(return_value=[]) oc.add_step(step) step.initialize() step.resolve_registered_dependencies() self.assertEqual( [ "Unable to resolve dependencies for sObject {}. The following Ids could not be found: {}" .format( step.sobjectname, ", ".join([ str(i) for i in [amaxa.SalesforceId("001000000000002")] ]), ) ], step.errors, )
def test_execute_does_not_run_bulk_job_if_all_records_inserted(self): record_list = [{"Name": "Test", "Id": "001000000000000"}] connection = MockConnection() op = amaxa.LoadOperation(Mock(wraps=connection)) op.file_store = MockFileStore() op.register_new_id( "Account", amaxa.SalesforceId("001000000000000"), amaxa.SalesforceId("001000000000005"), ) op.register_new_id = Mock() op.file_store.records["Account"] = record_list load_step = amaxa.LoadStep("Account", ["Name"]) op.add_step(load_step) load_step.initialize() load_step.execute() op.connection.bulk_api_insert.assert_not_called()
def test_retrieve_records_by_id(self): id_set = [] # Generate enough mock Ids to require two queries. for i in range(2005): new_id = str( amaxa.SalesforceId("00100000000" + str(i + 1).zfill(4))) id_set.append(new_id) self.assertEqual(2005, len(id_set)) complete_return_value = [{"Id": each_id} for each_id in id_set] api_return_value = [ complete_return_value[:2000], complete_return_value[2000:] ] api_return_value[0].append(None) sf = Mock() sf.bulk_url = "https://salesforce.com" sf.restful = Mock(side_effect=api_return_value) conn = Connection(sf) retval = conn.retrieve_records_by_id("Account", id_set, ["Name"]) self.assertEqual(complete_return_value, list(retval)) self.assertEqual(2, sf.restful.call_count) self.assertEqual( sf.restful.call_args_list, [ call( "composite/sobjects/Account", method="POST", data=json.dumps({ "ids": id_set[:2000], "fields": ["Name"] }), ), call( "composite/sobjects/Account", method="POST", data=json.dumps({ "ids": id_set[2000:], "fields": ["Name"] }), ), ], )
def test_execute_dependent_updates_handles_lookups(self): record_list = [ { "Name": "Test", "Id": "001000000000000", "ParentId": "001000000000004" }, { "Name": "Test 2", "Id": "001000000000001", "ParentId": "001000000000005" }, ] transformed_record_list = [ { "Id": str(amaxa.SalesforceId("001000000000002")), "ParentId": str(amaxa.SalesforceId("001000000000006")), }, { "Id": str(amaxa.SalesforceId("001000000000003")), "ParentId": str(amaxa.SalesforceId("001000000000007")), }, ] connection = MockConnection(bulk_update_results=[ UploadResult("001000000000002", True, True, ""), UploadResult("001000000000003", True, True, ""), ]) op = amaxa.LoadOperation(Mock(wraps=connection)) op.file_store = MockFileStore() op.register_new_id( "Account", amaxa.SalesforceId("001000000000004"), amaxa.SalesforceId("001000000000006"), ) op.register_new_id( "Account", amaxa.SalesforceId("001000000000005"), amaxa.SalesforceId("001000000000007"), ) op.register_new_id( "Account", amaxa.SalesforceId("001000000000000"), amaxa.SalesforceId("001000000000002"), ) op.register_new_id( "Account", amaxa.SalesforceId("001000000000001"), amaxa.SalesforceId("001000000000003"), ) op.register_new_id = Mock() op.register_error = Mock() op.file_store.records["Account"] = record_list load_step = amaxa.LoadStep("Account", ["Name", "ParentId"]) op.add_step(load_step) load_step.initialize() load_step.execute_dependent_updates() op.register_error.assert_not_called() op.connection.bulk_api_update.assert_called_once_with( "Account", transformed_record_list, load_step.get_option("bulk-api-timeout"), load_step.get_option("bulk-api-poll-interval"), load_step.get_option("bulk-api-batch-size"), )
from unittest.mock import Mock from ..loader import StateLoader, save_state EXAMPLE_DICT = { "version": 1, "state": { "stage": "inserts", "id-map": { "001000000000000AAA": "001000000000001AAA", "001000000000002AAA": "001000000000003AAA", }, }, } EXAMPLE_ID_MAP = { amaxa.SalesforceId(k): amaxa.SalesforceId(v) for k, v in EXAMPLE_DICT["state"]["id-map"].items() } class test_StateLoader(unittest.TestCase): def test_loads_state(self): sl = StateLoader(EXAMPLE_DICT, Mock()) sl.load() self.assertEqual(EXAMPLE_ID_MAP, sl.result.global_id_map) self.assertEqual(amaxa.LoadStage.INSERTS, sl.result.stage) def test_saves_state_json(self): operation = Mock()
def test_execute_resolves_self_lookups(self): connection = Mock() oc = amaxa.ExtractOperation(connection) oc.get_field_map = Mock( return_value={ "Name": { "name": "Name", "type": "text" }, "ParentId": { "name": "ParentId", "type": "reference", "referenceTo": ["Account"], }, }) oc.get_extracted_ids = Mock(side_effect=[ set([amaxa.SalesforceId("001000000000001")]), set([ amaxa.SalesforceId("001000000000001"), amaxa.SalesforceId("001000000000002"), ]), set([ amaxa.SalesforceId("001000000000001"), amaxa.SalesforceId("001000000000002"), ]), set([ amaxa.SalesforceId("001000000000001"), amaxa.SalesforceId("001000000000002"), ]), ]) step = amaxa.ExtractionStep( "Account", amaxa.ExtractionScope.QUERY, ["Name", "ParentId"], "Name = 'ACME'", ) step.perform_bulk_api_pass = Mock() step.perform_lookup_pass = Mock() step.resolve_registered_dependencies = Mock() oc.add_step(step) step.initialize() self.assertEqual(set(["ParentId"]), step.self_lookups) step.execute() step.perform_bulk_api_pass.assert_called_once_with( "SELECT Name, ParentId FROM Account WHERE Name = 'ACME'") oc.get_extracted_ids.assert_has_calls([ unittest.mock.call("Account"), unittest.mock.call("Account"), unittest.mock.call("Account"), unittest.mock.call("Account"), ]) step.perform_lookup_pass.assert_has_calls( [unittest.mock.call("ParentId"), unittest.mock.call("ParentId")]) step.resolve_registered_dependencies.assert_has_calls( [unittest.mock.call(), unittest.mock.call()])
def test_raises_valueerror(self): with self.assertRaises(ValueError): amaxa.SalesforceId("test")
def test_store_result_handles_polymorphic_lookups(self): connection = Mock() oc = amaxa.ExtractOperation(connection) oc.store_result = Mock() oc.add_dependency = Mock() oc.get_field_map = Mock( return_value={ "Lookup__c": { "name": "Lookup__c", "type": "reference", "referenceTo": ["Opportunity", "Account", "Task"], } }) oc.get_sobject_list = Mock( return_value=["Account", "Contact", "Opportunity"]) oc.get_extracted_ids = Mock(return_value=["001000000000001"]) oc.get_sobject_name_for_id = Mock(side_effect=lambda id: { "001": "Account", "006": "Opportunity", "00T": "Task", }[id[:3]]) step = amaxa.ExtractionStep("Contact", amaxa.ExtractionScope.ALL_RECORDS, ["Lookup__c"]) oc.add_step(step) step.initialize() # Validate that the polymorphic lookup is treated properly when the content is a dependent reference step.store_result({ "Id": "001000000000000", "Lookup__c": "006000000000001", "Name": "Kara Thrace", }) oc.add_dependency.assert_called_once_with( "Opportunity", amaxa.SalesforceId("006000000000001")) oc.store_result.assert_called_once_with( "Contact", { "Id": "001000000000000", "Lookup__c": "006000000000001", "Name": "Kara Thrace", }, ) oc.add_dependency.reset_mock() oc.store_result.reset_mock() # Validate that the polymorphic lookup is treated properly when the content is a descendent reference step.store_result({ "Id": "001000000000000", "Lookup__c": "001000000000001", "Name": "Kara Thrace", }) oc.add_dependency.assert_not_called() oc.store_result.assert_called_once_with( "Contact", { "Id": "001000000000000", "Lookup__c": "001000000000001", "Name": "Kara Thrace", }, ) oc.add_dependency.reset_mock() oc.store_result.reset_mock() # Validate that the polymorphic lookup is treated properly when the content is a off-extraction reference step.store_result({ "Id": "001000000000000", "Lookup__c": "00T000000000001", "Name": "Kara Thrace", }) oc.add_dependency.assert_not_called() oc.store_result.assert_called_once_with( "Contact", { "Id": "001000000000000", "Lookup__c": "00T000000000001", "Name": "Kara Thrace", }, )
def test_equals_other_id(self): the_id = amaxa.SalesforceId("001000000000000") self.assertEqual(the_id, amaxa.SalesforceId(the_id))
def test_does_not_equal_other_value(self): the_id = amaxa.SalesforceId("001000000000000") self.assertNotEqual(the_id, 1)
def test_str_repr_equal_18_char_id(self): the_id = amaxa.SalesforceId("001000000000000") self.assertEqual(the_id.id, str(the_id)) self.assertEqual(the_id.id, repr(the_id))
def test_converts_real_id_pairs(self): known_good_ids = { "01Q36000000RXX5": "01Q36000000RXX5EAO", "005360000016xkG": "005360000016xkGAAQ", "01I36000002zD9R": "01I36000002zD9REAU", "0013600001ohPTp": "0013600001ohPTpAAM", "0033600001gyv5B": "0033600001gyv5BAAQ", } for id_15 in known_good_ids: self.assertEqual(known_good_ids[id_15], str(amaxa.SalesforceId(id_15))) self.assertEqual(known_good_ids[id_15], amaxa.SalesforceId(id_15)) self.assertEqual(amaxa.SalesforceId(id_15), known_good_ids[id_15]) self.assertEqual(id_15, amaxa.SalesforceId(id_15)) self.assertNotEqual(id_15, str(amaxa.SalesforceId(id_15))) self.assertEqual(amaxa.SalesforceId(id_15), amaxa.SalesforceId(id_15)) self.assertEqual( amaxa.SalesforceId(str(amaxa.SalesforceId(id_15))), amaxa.SalesforceId(str(amaxa.SalesforceId(id_15))), ) self.assertEqual( known_good_ids[id_15], amaxa.SalesforceId(known_good_ids[id_15]) ) self.assertEqual( known_good_ids[id_15], str(amaxa.SalesforceId(known_good_ids[id_15])) ) self.assertEqual( hash(known_good_ids[id_15]), hash(amaxa.SalesforceId(id_15)) )