Beispiel #1
0
    def test_transform_records_runs_transform_before_cleaning(self):
        connection = Mock()
        op = amaxa.LoadOperation(connection)
        op.mappers["Account"] = Mock()
        op.mappers["Account"].transform_record = Mock(return_value={
            "Name": "Test2",
            "ParentId": "001000000000001",
            "Excess__c": True,
        })

        load_step = amaxa.LoadStep("Account", ["Name", "ParentId"])
        op.add_step(load_step)
        load_step.dependent_lookups = set()
        load_step.self_lookups = set()

        self.assertEqual(
            {
                "Name": "Test2",
                "ParentId": "001000000000001"
            },
            load_step.transform_record({
                "Account Name": "Test2",
                "ParentId": "001000000000001",
                "Excess__c": True,
            }),
        )
Beispiel #2
0
    def test_get_option_default(self):
        step = amaxa.LoadStep("Account", ["Name"], options={})

        self.assertEqual(
            constants.OPTION_DEFAULTS["bulk-api-batch-size"],
            step.get_option("bulk-api-batch-size"),
        )
Beispiel #3
0
    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,
            )
Beispiel #4
0
    def test_transform_records_calls_context_mapper(self):
        connection = Mock()
        op = amaxa.LoadOperation(connection)
        op.mappers["Account"] = Mock()
        op.mappers["Account"].transform_record = Mock(
            return_value={
                "Name": "Test2",
                "ParentId": "001000000000001"
            })

        load_step = amaxa.LoadStep("Account", ["Name", "ParentId"])
        op.add_step(load_step)
        load_step.dependent_lookups = set()
        load_step.self_lookups = set()

        self.assertEqual(
            {
                "Name": "Test2",
                "ParentId": "001000000000001"
            },
            load_step.transform_record({
                "Name": "Test1",
                "ParentId": "001000000000000"
            }),
        )
        op.mappers["Account"].transform_record.assert_called_once_with({
            "Name":
            "Test1",
            "ParentId":
            "001000000000000"
        })
    def test_loads_and_extracts_high_data_volume(self):
        # This is a single unit test rather than multiple to save on execution time.
        records = []

        for i in range(100000):
            records.append({
                "Id": "00Q000000{:06d}".format(i),
                "Company": "[not provided]",
                "LastName": "Lead {:06d}".format(i),
            })

        op = amaxa.LoadOperation(Connection(self.connection, "52.0"))
        op.file_store = MockFileStore()
        op.file_store.records["Lead"] = records
        op.add_step(amaxa.LoadStep("Lead", set(["LastName", "Company"])))

        op.initialize()
        op.execute()

        self.assertEqual(
            100000,
            self.connection.query("SELECT count() FROM Lead").get("totalSize"))

        oc = amaxa.ExtractOperation(Connection(self.connection, "52.0"))
        oc.file_store = MockFileStore()

        extraction = amaxa.ExtractionStep("Lead",
                                          amaxa.ExtractionScope.ALL_RECORDS,
                                          ["Id", "LastName"])
        oc.add_step(extraction)

        extraction.initialize()
        extraction.execute()

        self.assertEqual(100000, len(oc.get_extracted_ids("Lead")))
Beispiel #6
0
    def test_execute_dependent_updates_handles_exceptions__outside_lookups(self):
        record_list = [
            {"Name": "Test", "Id": "001000000000000", "ParentId": ""},
            {"Name": "Test 2", "Id": "001000000000001", "ParentId": "001000000000002"},
        ]
        connection = MockConnection()
        op = amaxa.LoadOperation(Mock(wraps=connection))
        op.file_store = MockFileStore()
        op.file_store.records["Account"] = record_list
        op.register_new_id = Mock()
        op.register_error = Mock()

        load_step = amaxa.LoadStep("Account", ["Name", "ParentId"])
        load_step.set_lookup_behavior_for_field(
            "ParentId", amaxa.OutsideLookupBehavior.ERROR
        )
        op.add_step(load_step)

        load_step.initialize()
        load_step.execute_dependent_updates()

        self.assertEqual(
            [
                unittest.mock.call(
                    "Account",
                    record_list[1]["Id"],
                    f"Account {record_list[1]['Id']} has an outside reference in field ParentId (001000000000002), which is not allowed by the extraction configuration.",
                ),
            ],
            op.register_error.call_args_list,
        )
Beispiel #7
0
    def test_execute_does_not_insert_records_prepopulated_in_id_map(self):
        record_list = [
            {
                "Name": "Test",
                "Id": "001000000000000"
            },
            {
                "Name": "Test 2",
                "Id": "001000000000001"
            },
            {
                "Name": "Test 3",
                "Id": "001000000000002"
            },
        ]
        clean_record_list = [{"Name": "Test 2"}, {"Name": "Test 3"}]
        connection = MockConnection(bulk_insert_results=[
            UploadResult("001000000000007", True, True, ""),
            UploadResult("001000000000008", True, True, ""),
        ])
        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
        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.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"),
        )
        op.register_new_id.assert_has_calls([
            unittest.mock.call(
                "Account",
                amaxa.SalesforceId("001000000000001"),
                amaxa.SalesforceId("001000000000007"),
            ),
            unittest.mock.call(
                "Account",
                amaxa.SalesforceId("001000000000002"),
                amaxa.SalesforceId("001000000000008"),
            ),
        ])
Beispiel #8
0
    def test_execute_handles_exceptions__bad_data(self):
        record_list = [
            {"Name": "Test", "Id": "001000000000000", "IsDeleted": "false"},
            {"Name": "Test 2", "Id": "001000000000001", "IsDeleted": "foo"},
        ]
        connection = MockConnection()
        op = amaxa.LoadOperation(Mock(wraps=connection))
        op.file_store = MockFileStore()
        op.file_store.records["Account"] = record_list
        op.register_new_id = Mock()
        op.register_error = Mock()

        load_step = amaxa.LoadStep("Account", ["Name", "IsDeleted"])
        op.add_step(load_step)

        load_step.initialize()
        load_step.execute()

        self.assertEqual(
            [
                unittest.mock.call(
                    "Account",
                    record_list[1]["Id"],
                    f"Bad data in record {record_list[1]['Id']}: Invalid Boolean value foo",
                ),
            ],
            op.register_error.call_args_list,
        )
Beispiel #9
0
    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,
        )
Beispiel #10
0
    def test_get_value_for_lookup_with_blank_input(self):
        connection = Mock()
        op = amaxa.LoadOperation(connection)

        load_step = amaxa.LoadStep("Account", ["Name", "ParentId"])
        op.add_step(load_step)

        self.assertEqual(
            load_step.get_value_for_lookup("ParentId", "", "001000000000002"),
            "")
Beispiel #11
0
    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"
        )
Beispiel #12
0
    def test_stores_lookup_behaviors(self):
        load_step = amaxa.LoadStep("Account", ["Name", "ParentId"])

        self.assertEqual(
            amaxa.OutsideLookupBehavior.INCLUDE,
            load_step.get_lookup_behavior_for_field("ParentId"),
        )

        load_step.set_lookup_behavior_for_field(
            "ParentId", amaxa.OutsideLookupBehavior.ERROR)
        self.assertEqual(
            amaxa.OutsideLookupBehavior.ERROR,
            load_step.get_lookup_behavior_for_field("ParentId"),
        )
Beispiel #13
0
    def test_populates_lookups(self):
        load_step = amaxa.LoadStep("Account", ["Name", "ParentId"])
        load_step.get_value_for_lookup = Mock(return_value="001000000000002")

        record = {
            "Id": "001000000000000",
            "Name": "Test",
            "ParentId": "001000000000001",
        }

        self.assertEqual(
            {"Id": "001000000000000", "Name": "Test", "ParentId": "001000000000002"},
            load_step.populate_lookups(record, ["ParentId"], "001000000000000"),
        )
Beispiel #14
0
    def test_transform_records_cleans_excess_fields(self):
        connection = Mock()
        op = amaxa.LoadOperation(connection)

        load_step = amaxa.LoadStep("Account", ["Name", "ParentId"])
        op.add_step(load_step)
        load_step.dependent_lookups = set()
        load_step.self_lookups = set()

        self.assertEqual(
            {"Name": "Test2", "ParentId": "001000000000001"},
            load_step.transform_record(
                {"Name": "Test2", "ParentId": "001000000000001", "Excess__c": True}
            ),
        )
Beispiel #15
0
    def test_get_value_for_lookup_with_drop_behavior(self):
        connection = Mock()
        op = amaxa.LoadOperation(connection)

        load_step = amaxa.LoadStep("Account", ["Name", "ParentId"])
        op.add_step(load_step)

        load_step.set_lookup_behavior_for_field(
            "ParentId", amaxa.OutsideLookupBehavior.DROP_FIELD)

        self.assertEqual(
            load_step.get_value_for_lookup("ParentId", "001000000000000",
                                           "001000000000002"),
            "",
        )
Beispiel #16
0
    def test_clean_dependent_lookups_returns_clean_record(self):
        load_step = amaxa.LoadStep("Account", ["Id", "Name", "ParentId"])
        load_step.self_lookups = set(["ParentId"])
        load_step.dependent_lookups = set()

        self.assertEqual(
            {"Name": "Gemenon Gastronomics", "Id": "001000000000001"},
            load_step.clean_dependent_lookups(
                {
                    "Name": "Gemenon Gastronomics",
                    "Id": "001000000000001",
                    "ParentId": "001000000000002",
                }
            ),
        )
Beispiel #17
0
    def test_converts_data_for_bulk_api(self):
        connection = Mock()
        op = amaxa.LoadOperation(connection)
        op.get_field_map = Mock(
            return_value={
                "Name": {"soapType": "xsd:string"},
                "Boolean__c": {"soapType": "xsd:boolean"},
                "Boolean_False__c": {"soapType": "xsd:boolean"},
                "Id": {"soapType": "tns:ID"},
                "Date__c": {"soapType": "xsd:date"},
                "DateTime__c": {"soapType": "xsd:dateTime"},
                "Int__c": {"soapType": "xsd:int"},
                "Double__c": {"soapType": "xsd:double"},
                "Random__c": {"soapType": "xsd:string"},
            }
        )

        load_step = amaxa.LoadStep("Account", ["Name", "ParentId"])
        op.add_step(load_step)

        record = {
            "Name": "Test",
            "Boolean__c": "yes",
            "Boolean_False__c": "no",
            "Id": "001000000000001",
            "Date__c": "2018-12-31",
            "DateTime__c": "2018-12-31T00:00:00.000Z",
            "Int__c": "100",
            "Double__c": "10.1",
            "Random__c": "",
        }

        self.assertEqual(
            {
                "Name": "Test",
                "Boolean__c": "true",
                "Boolean_False__c": "false",
                "Id": "001000000000001",
                "Date__c": "2018-12-31",
                "DateTime__c": "2018-12-31T00:00:00.000Z",
                "Int__c": "100",
                "Double__c": "10.1",
                "Random__c": None,
            },
            load_step.primitivize(record),
        )
    def test_loads_single_object(self):
        records = [
            {
                "Id": "01t000000000001",
                "Name": "Tauron Taffy",
                "IsActive": "True",
                "ProductCode": "TAFFY_TAUR",
            },
            {
                "Id": "01t000000000002",
                "Name": "Gemenese Goulash",
                "IsActive": "True",
                "ProductCode": "GLSH",
            },
            {
                "Id": "01t000000000003AAA",
                "Name": "Caprica Corn",
                "IsActive": "False",
                "ProductCode": "CPRCC",
            },
        ]

        op = amaxa.LoadOperation(Connection(self.connection))
        op.file_store = MockFileStore()
        op.file_store.records["Product2"] = records

        op.add_step(
            amaxa.LoadStep(
                "Product2", set(["Name", "IsActive", "ProductCode", "Description"])
            )
        )

        op.initialize()
        op.execute()

        loaded_products = self.connection.query_all(
            "SELECT Id, Name, IsActive, ProductCode FROM Product2"
        ).get("records")
        self.assertEqual(3, len(loaded_products))
        required_names = {x["Name"] for x in records}
        for r in loaded_products:
            self.register_case_record("Product2", r["Id"])
            self.assertIn(r["Name"], required_names)
            required_names.remove(r["Name"])

        self.assertEqual(0, len(required_names))
Beispiel #19
0
    def test_converts_data_for_bulk_api__failures(self):
        connection = Mock()
        op = amaxa.LoadOperation(connection)
        op.get_field_map = Mock(
            return_value={
                "Boolean__c": {"soapType": "xsd:boolean"},
                "Address__c": {"soapType": "xsd:address"},
            }
        )

        load_step = amaxa.LoadStep("Account", ["Name", "ParentId"])
        op.add_step(load_step)

        with pytest.raises(ValueError):
            load_step.primitivize({"Boolean__c": "blah"})

        assert load_step.primitivize({"Address__c": "foo"})["Address__c"] is None
Beispiel #20
0
    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")),
        )
Beispiel #21
0
    def test_get_value_for_lookup_with_error_behavior(self):
        connection = Mock()
        op = amaxa.LoadOperation(connection)

        load_step = amaxa.LoadStep("Account", ["Name", "ParentId"])
        op.add_step(load_step)

        load_step.set_lookup_behavior_for_field(
            "ParentId", amaxa.OutsideLookupBehavior.ERROR)

        with self.assertRaises(
                amaxa.AmaxaException,
                msg="{} {} has an outside reference in field {} ({}), "
                "which is not allowed by the extraction configuration.".format(
                    "Account", "001000000000002", "ParentId",
                    "001000000000000"),
        ):
            load_step.get_value_for_lookup("ParentId", "001000000000000",
                                           "001000000000002")
Beispiel #22
0
    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()
Beispiel #23
0
    def test_format_error_constructs_messages(self):
        step = amaxa.LoadStep("Account", ["Name"])

        self.assertEqual(
            "DUPLICATES_DETECTED: There are duplicates\nOTHER_ERROR: "
            "There are non-duplicates (Name, Id). More info",
            step.format_error([
                {
                    "statusCode": "DUPLICATES_DETECTED",
                    "message": "There are duplicates",
                    "fields": [],
                    "extendedErrorDetails": None,
                },
                {
                    "statusCode": "OTHER_ERROR",
                    "message": "There are non-duplicates",
                    "fields": ["Name", "Id"],
                    "extendedErrorDetails": "More info",
                },
            ]),
        )
Beispiel #24
0
    def test_execute_uses_custom_bulk_api_options(self):
        record_list = [
            {
                "Name": "Test",
                "Id": "001000000000000"
            },
            {
                "Name": "Test 2",
                "Id": "001000000000001"
            },
        ]
        cleaned_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

        step = amaxa.LoadStep(
            "Account",
            ["Name"],
            options={
                "bulk-api-poll-interval": 10,
                "bulk-api-timeout": 600,
                "bulk-api-batch-size": 5000,
                "bulk-api-mode": "Serial",
            },
        )
        step.context = op
        step.primitivize = Mock(side_effect=lambda x: x)
        step.populate_lookups = Mock(side_effect=lambda x, y, z: x)

        step.initialize()
        step.execute()

        op.connection.bulk_api_insert.assert_called_once_with(
            "Account", cleaned_record_list, 600, 10, 5000, "Serial")
Beispiel #25
0
    def test_get_option_set(self):
        step = amaxa.LoadStep("Account", ["Name"],
                              options={"bulk-api-batch-size": 1})

        self.assertEqual(1, step.get_option("bulk-api-batch-size"))
    def test_loads_complex_hierarchy(self):
        accounts = [
            {
                "Id": "001000000000001",
                "Name": "Tauron Tourist Commission",
                "ParentId": "",
            },
            {
                "Id": "001000000000002",
                "Name": "Emporion Enterprises",
                "ParentId": "001000000000001",
            },
            {
                "Id": "001000000000003AAA",
                "Name": "Caprica City Outreach",
                "ParentId": "001000000000001",
            },
        ]
        contacts = [
            {"Id": "003000000000000", "FirstName": "Joseph", "LastName": "Adama"},
            {"Id": "003000000000001", "FirstName": "Sam", "LastName": "Adama"},
        ]
        opportunities = [
            {
                "Id": "006000000000001",
                "AccountId": "001000000000001",
                "Name": "End-of-Year Promotion",
                "CloseDate": "2019-06-01",
                "StageName": "Closed Won",
            },
            {
                "Id": "006000000000002",
                "AccountId": "001000000000001",
                "Name": "New Initiative",
                "CloseDate": "2019-12-01",
                "StageName": "Closed Lost",
            },
        ]
        opportunity_contact_roles = [
            {
                "Id": "00K000000000001",
                "OpportunityId": "006000000000001",
                "ContactId": "003000000000000",
                "Role": "Decision Maker",
            },
            {
                "Id": "00K000000000001",
                "OpportunityId": "006000000000001",
                "ContactId": "003000000000000",
                "Role": "Influencer",
            },
            {
                "Id": "00K000000000002",
                "OpportunityId": "006000000000002",
                "ContactId": "003000000000001",
                "Role": "Decision Maker",
            },
        ]

        op = amaxa.LoadOperation(Connection(self.connection))
        op.file_store = MockFileStore()
        op.file_store.records["Account"] = accounts
        op.file_store.records["Contact"] = contacts
        op.file_store.records["Opportunity"] = opportunities
        op.file_store.records["OpportunityContactRole"] = opportunity_contact_roles

        op.add_step(amaxa.LoadStep("Account", set(["Name", "ParentId"])))
        op.add_step(
            amaxa.LoadStep("Contact", set(["AccountId", "FirstName", "LastName"]))
        )
        op.add_step(
            amaxa.LoadStep(
                "Opportunity", set(["AccountId", "Name", "CloseDate", "StageName"])
            )
        )
        op.add_step(
            amaxa.LoadStep(
                "OpportunityContactRole", set(["ContactId", "OpportunityId", "Role"])
            )
        )

        op.initialize()
        op.execute()

        loaded_accounts = self.connection.query_all(
            "SELECT Id, Name, (SELECT Name FROM ChildAccounts) FROM Account"
        ).get("records")
        self.assertEqual(len(accounts), len(loaded_accounts))
        required_names = [x["Name"] for x in accounts]
        for r in loaded_accounts:
            self.register_case_record("Account", r["Id"])
            self.assertIn(r["Name"], required_names)
            required_names.remove(r["Name"])
            if r["Name"] == "Tauron Tourist Commission":
                self.assertIsNotNone(r["ChildAccounts"])
                self.assertEqual(2, len(r["ChildAccounts"]["records"]))

        self.assertEqual(0, len(required_names))

        loaded_opportunities = self.connection.query_all(
            "SELECT Id, Name, (SELECT Id FROM OpportunityContactRoles) FROM Opportunity"
        ).get("records")
        self.assertEqual(len(opportunities), len(loaded_opportunities))
        required_names = [x["Name"] for x in opportunities]
        for r in loaded_opportunities:
            self.register_case_record("Opportunity", r["Id"])
            self.assertIn(r["Name"], required_names)
            required_names.remove(r["Name"])
            if r["Name"] == "End-of-Year Promotion":
                self.assertEqual(2, len(r["OpportunityContactRoles"]["records"]))
            else:
                self.assertEqual(1, len(r["OpportunityContactRoles"]["records"]))

        self.assertEqual(0, len(required_names))

        loaded_contacts = self.connection.query_all(
            "SELECT Id, FirstName, LastName, (SELECT Id FROM OpportunityContactRoles) FROM Contact"
        ).get("records")
        self.assertEqual(len(contacts), len(loaded_contacts))
        required_names = [x["LastName"] for x in contacts]
        for r in loaded_contacts:
            self.register_case_record("Contact", r["Id"])
            self.assertIn(r["LastName"], required_names)
            required_names.remove(r["LastName"])
            if r["FirstName"] == "Sam":
                self.assertEqual(1, len(r["OpportunityContactRoles"]["records"]))
            else:
                self.assertEqual(2, len(r["OpportunityContactRoles"]["records"]))

        self.assertEqual(0, len(required_names))
Beispiel #27
0
    def test_execute_transforms_and_loads_records_with_lookups(self):
        record_list = [
            {
                "Name": "Test",
                "Id": "001000000000000",
                "OwnerId": "500000000000000"
            },
            {
                "Name": "Test 2",
                "Id": "001000000000001",
                "OwnerId": "500000000000001"
            },
        ]
        transformed_record_list = [
            {
                "Name": "Test",
                "OwnerId": str(amaxa.SalesforceId("500000000000002"))
            },
            {
                "Name": "Test 2",
                "OwnerId": str(amaxa.SalesforceId("500000000000003"))
            },
        ]

        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(
            "User",
            amaxa.SalesforceId("500000000000000"),
            amaxa.SalesforceId("500000000000002"),
        )
        op.register_new_id(
            "User",
            amaxa.SalesforceId("500000000000001"),
            amaxa.SalesforceId("500000000000003"),
        )

        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", "OwnerId"])
        op.add_step(load_step)
        load_step.primitivize = Mock(side_effect=lambda x: x)

        load_step.initialize()
        load_step.descendent_lookups = set(["OwnerId"])

        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 transformed_record_list])

        op.connection.bulk_api_insert.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"),
        )
        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"),
            ),
        ])
Beispiel #28
0
    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"),
        )