|
6 | 6 | import json
|
7 | 7 | from typing import Any, Mapping
|
8 | 8 |
|
| 9 | +import pytest |
9 | 10 | from airbyte_cdk.models import OrchestratorType, Type
|
10 | 11 | from airbyte_cdk.sources import Source
|
11 |
| -from source_facebook_marketing.config_migrations import MigrateAccountIdToArray |
| 12 | +from source_facebook_marketing.config_migrations import MigrateAccountIdToArray, MigrateIncludeDeletedToStatusFilters |
12 | 13 | from source_facebook_marketing.source import SourceFacebookMarketing
|
13 | 14 |
|
14 | 15 | # BASE ARGS
|
15 | 16 | CMD = "check"
|
16 |
| -TEST_CONFIG_PATH = "unit_tests/test_migrations/test_old_config.json" |
17 |
| -NEW_TEST_CONFIG_PATH = "unit_tests/test_migrations/test_new_config.json" |
18 |
| -UPGRADED_TEST_CONFIG_PATH = "unit_tests/test_migrations/test_upgraded_config.json" |
19 |
| -SOURCE_INPUT_ARGS = [CMD, "--config", TEST_CONFIG_PATH] |
20 | 17 | SOURCE: Source = SourceFacebookMarketing()
|
21 | 18 |
|
22 | 19 |
|
23 | 20 | # HELPERS
|
24 |
| -def load_config(config_path: str = TEST_CONFIG_PATH) -> Mapping[str, Any]: |
| 21 | +def load_config(config_path: str) -> Mapping[str, Any]: |
25 | 22 | with open(config_path, "r") as config:
|
26 | 23 | return json.load(config)
|
27 | 24 |
|
28 | 25 |
|
29 |
| -def revert_migration(config_path: str = TEST_CONFIG_PATH) -> None: |
30 |
| - with open(config_path, "r") as test_config: |
31 |
| - config = json.load(test_config) |
32 |
| - config.pop("account_ids") |
33 |
| - with open(config_path, "w") as updated_config: |
34 |
| - config = json.dumps(config) |
35 |
| - updated_config.write(config) |
36 |
| - |
37 |
| - |
38 |
| -def test_migrate_config(): |
39 |
| - migration_instance = MigrateAccountIdToArray() |
40 |
| - original_config = load_config() |
41 |
| - # migrate the test_config |
42 |
| - migration_instance.migrate(SOURCE_INPUT_ARGS, SOURCE) |
43 |
| - # load the updated config |
44 |
| - test_migrated_config = load_config() |
45 |
| - # check migrated property |
46 |
| - assert "account_ids" in test_migrated_config |
47 |
| - assert isinstance(test_migrated_config["account_ids"], list) |
48 |
| - # check the old property is in place |
49 |
| - assert "account_id" in test_migrated_config |
50 |
| - assert isinstance(test_migrated_config["account_id"], str) |
51 |
| - # check the migration should be skipped, once already done |
52 |
| - assert not migration_instance.should_migrate(test_migrated_config) |
53 |
| - # load the old custom reports VS migrated |
54 |
| - assert [original_config["account_id"]] == test_migrated_config["account_ids"] |
55 |
| - # test CONTROL MESSAGE was emitted |
56 |
| - control_msg = migration_instance.message_repository._message_queue[0] |
57 |
| - assert control_msg.type == Type.CONTROL |
58 |
| - assert control_msg.control.type == OrchestratorType.CONNECTOR_CONFIG |
59 |
| - # old custom_reports are stil type(str) |
60 |
| - assert isinstance(control_msg.control.connectorConfig.config["account_id"], str) |
61 |
| - # new custom_reports are type(list) |
62 |
| - assert isinstance(control_msg.control.connectorConfig.config["account_ids"], list) |
63 |
| - # check the migrated values |
64 |
| - assert control_msg.control.connectorConfig.config["account_ids"] == ["01234567890"] |
65 |
| - # revert the test_config to the starting point |
66 |
| - revert_migration() |
67 |
| - |
68 |
| - |
69 |
| -def test_config_is_reverted(): |
70 |
| - # check the test_config state, it has to be the same as before tests |
71 |
| - test_config = load_config() |
72 |
| - # check the config no longer has the migarted property |
73 |
| - assert "account_ids" not in test_config |
74 |
| - # check the old property is still there |
75 |
| - assert "account_id" in test_config |
76 |
| - assert isinstance(test_config["account_id"], str) |
77 |
| - |
78 |
| - |
79 |
| -def test_should_not_migrate_new_config(): |
80 |
| - new_config = load_config(NEW_TEST_CONFIG_PATH) |
81 |
| - migration_instance = MigrateAccountIdToArray() |
82 |
| - assert not migration_instance.should_migrate(new_config) |
83 |
| - |
84 |
| - |
85 |
| -def test_should_not_migrate_upgraded_config(): |
86 |
| - new_config = load_config(UPGRADED_TEST_CONFIG_PATH) |
87 |
| - migration_instance = MigrateAccountIdToArray() |
88 |
| - assert not migration_instance.should_migrate(new_config) |
| 26 | +class TestMigrateAccountIdToArray: |
| 27 | + TEST_CONFIG_PATH = "unit_tests/test_migrations/account_id_to_array/test_old_config.json" |
| 28 | + NEW_TEST_CONFIG_PATH = "unit_tests/test_migrations/account_id_to_array/test_new_config.json" |
| 29 | + UPGRADED_TEST_CONFIG_PATH = "unit_tests/test_migrations/account_id_to_array/test_upgraded_config.json" |
| 30 | + |
| 31 | + @staticmethod |
| 32 | + def revert_migration(config_path: str = TEST_CONFIG_PATH) -> None: |
| 33 | + with open(config_path, "r") as test_config: |
| 34 | + config = json.load(test_config) |
| 35 | + config.pop("account_ids") |
| 36 | + with open(config_path, "w") as updated_config: |
| 37 | + config = json.dumps(config) |
| 38 | + updated_config.write(config) |
| 39 | + |
| 40 | + def test_migrate_config(self): |
| 41 | + migration_instance = MigrateAccountIdToArray() |
| 42 | + original_config = load_config(self.TEST_CONFIG_PATH) |
| 43 | + # migrate the test_config |
| 44 | + migration_instance.migrate([CMD, "--config", self.TEST_CONFIG_PATH], SOURCE) |
| 45 | + # load the updated config |
| 46 | + test_migrated_config = load_config(self.TEST_CONFIG_PATH) |
| 47 | + # check migrated property |
| 48 | + assert "account_ids" in test_migrated_config |
| 49 | + assert isinstance(test_migrated_config["account_ids"], list) |
| 50 | + # check the old property is in place |
| 51 | + assert "account_id" in test_migrated_config |
| 52 | + assert isinstance(test_migrated_config["account_id"], str) |
| 53 | + # check the migration should be skipped, once already done |
| 54 | + assert not migration_instance.should_migrate(test_migrated_config) |
| 55 | + # load the old custom reports VS migrated |
| 56 | + assert [original_config["account_id"]] == test_migrated_config["account_ids"] |
| 57 | + # test CONTROL MESSAGE was emitted |
| 58 | + control_msg = migration_instance.message_repository._message_queue[0] |
| 59 | + assert control_msg.type == Type.CONTROL |
| 60 | + assert control_msg.control.type == OrchestratorType.CONNECTOR_CONFIG |
| 61 | + # old custom_reports are stil type(str) |
| 62 | + assert isinstance(control_msg.control.connectorConfig.config["account_id"], str) |
| 63 | + # new custom_reports are type(list) |
| 64 | + assert isinstance(control_msg.control.connectorConfig.config["account_ids"], list) |
| 65 | + # check the migrated values |
| 66 | + assert control_msg.control.connectorConfig.config["account_ids"] == ["01234567890"] |
| 67 | + # revert the test_config to the starting point |
| 68 | + self.revert_migration() |
| 69 | + |
| 70 | + def test_config_is_reverted(self): |
| 71 | + # check the test_config state, it has to be the same as before tests |
| 72 | + test_config = load_config(self.TEST_CONFIG_PATH) |
| 73 | + # check the config no longer has the migarted property |
| 74 | + assert "account_ids" not in test_config |
| 75 | + # check the old property is still there |
| 76 | + assert "account_id" in test_config |
| 77 | + assert isinstance(test_config["account_id"], str) |
| 78 | + |
| 79 | + def test_should_not_migrate_new_config(self): |
| 80 | + new_config = load_config(self.NEW_TEST_CONFIG_PATH) |
| 81 | + migration_instance = MigrateAccountIdToArray() |
| 82 | + assert not migration_instance.should_migrate(new_config) |
| 83 | + |
| 84 | + def test_should_not_migrate_upgraded_config(self): |
| 85 | + new_config = load_config(self.UPGRADED_TEST_CONFIG_PATH) |
| 86 | + migration_instance = MigrateAccountIdToArray() |
| 87 | + assert not migration_instance.should_migrate(new_config) |
| 88 | + |
| 89 | + |
| 90 | +class TestMigrateIncludeDeletedToStatusFilters: |
| 91 | + OLD_TEST1_CONFIG_PATH = "unit_tests/test_migrations/include_deleted_to_status_filters/include_deleted_false/test_old_config.json" |
| 92 | + NEW_TEST1_CONFIG_PATH = "unit_tests/test_migrations/include_deleted_to_status_filters/include_deleted_false/test_new_config.json" |
| 93 | + OLD_TEST2_CONFIG_PATH = "unit_tests/test_migrations/include_deleted_to_status_filters/include_deleted_true/test_old_config.json" |
| 94 | + NEW_TEST2_CONFIG_PATH = "unit_tests/test_migrations/include_deleted_to_status_filters/include_deleted_true/test_new_config.json" |
| 95 | + |
| 96 | + UPGRADED_TEST_CONFIG_PATH = "unit_tests/test_migrations/account_id_to_array/test_upgraded_config.json" |
| 97 | + |
| 98 | + filter_properties = ["ad_statuses", "adset_statuses", "campaign_statuses"] |
| 99 | + |
| 100 | + def revert_migration(self, config_path: str) -> None: |
| 101 | + with open(config_path, "r") as test_config: |
| 102 | + config = json.load(test_config) |
| 103 | + for filter in self.filter_properties: |
| 104 | + config.pop(filter) |
| 105 | + with open(config_path, "w") as updated_config: |
| 106 | + config = json.dumps(config) |
| 107 | + updated_config.write(config) |
| 108 | + |
| 109 | + @pytest.mark.parametrize( |
| 110 | + "old_config_path, new_config_path, include_deleted", |
| 111 | + [(OLD_TEST1_CONFIG_PATH, NEW_TEST1_CONFIG_PATH, False), (OLD_TEST2_CONFIG_PATH, NEW_TEST2_CONFIG_PATH, True)], |
| 112 | + ) |
| 113 | + def test_migrate_config(self, old_config_path, new_config_path, include_deleted): |
| 114 | + migration_instance = MigrateIncludeDeletedToStatusFilters() |
| 115 | + original_config = load_config(old_config_path) |
| 116 | + # migrate the test_config |
| 117 | + migration_instance.migrate([CMD, "--config", old_config_path], SOURCE) |
| 118 | + # load the updated config |
| 119 | + test_migrated_config = load_config(old_config_path) |
| 120 | + # load expected updated config |
| 121 | + expected_new_config = load_config(new_config_path) |
| 122 | + # compare expected with migrated |
| 123 | + assert expected_new_config == test_migrated_config |
| 124 | + # check migrated property |
| 125 | + if include_deleted: |
| 126 | + assert all([filter in test_migrated_config for filter in self.filter_properties]) |
| 127 | + # check the old property is in place |
| 128 | + assert "include_deleted" in test_migrated_config |
| 129 | + assert test_migrated_config["include_deleted"] == include_deleted |
| 130 | + # check the migration should be skipped, once already done |
| 131 | + assert not migration_instance.should_migrate(test_migrated_config) |
| 132 | + if include_deleted: |
| 133 | + # test CONTROL MESSAGE was emitted |
| 134 | + control_msg = migration_instance.message_repository._message_queue[0] |
| 135 | + assert control_msg.type == Type.CONTROL |
| 136 | + assert control_msg.control.type == OrchestratorType.CONNECTOR_CONFIG |
| 137 | + # revert the test_config to the starting point |
| 138 | + self.revert_migration(old_config_path) |
| 139 | + |
| 140 | + @pytest.mark.parametrize("new_config_path", [NEW_TEST1_CONFIG_PATH, NEW_TEST2_CONFIG_PATH]) |
| 141 | + def test_should_not_migrate_new_config(self, new_config_path): |
| 142 | + new_config = load_config(new_config_path) |
| 143 | + migration_instance = MigrateIncludeDeletedToStatusFilters() |
| 144 | + assert not migration_instance.should_migrate(new_config) |
| 145 | + |
| 146 | + def test_should_not_migrate_upgraded_config(self): |
| 147 | + new_config = load_config(self.UPGRADED_TEST_CONFIG_PATH) |
| 148 | + migration_instance = MigrateIncludeDeletedToStatusFilters() |
| 149 | + assert not migration_instance.should_migrate(new_config) |
0 commit comments