1
+ from typing import Callable , Generator
2
+
1
3
from django .apps import apps as global_apps
4
+ from django .apps .registry import Apps
2
5
from django .db import connection
3
6
from django .db .migrations .executor import MigrationExecutor
4
7
from django .test import override_settings
@@ -13,93 +16,88 @@ class BaseMigrationTest:
13
16
migrate_to = None # The migration we want to test
14
17
setting_overrides = {}
15
18
16
- @pytest .fixture ( autouse = True )
17
- def setup_migration (self , db ):
19
+ @pytest .fixture
20
+ def setup_migration (self , db ) -> Generator :
18
21
"""
19
22
Setup the migration test by reversing to `migrate_from` state,
20
23
then applying the `migrate_to` state.
21
24
"""
22
- assert self .app is not None , "You must define the `app` attribute"
23
- assert self .migrate_from is not None , "You must define `migrate_from`"
24
- assert self .migrate_to is not None , "You must define `migrate_to`"
25
25
26
- # Step 1: Set up the MigrationExecutor
27
- executor = MigrationExecutor (connection )
26
+ def _migrate (callback : Callable ) -> None :
27
+ assert self .app is not None , "You must define the `app` attribute"
28
+ assert self .migrate_from is not None , "You must define `migrate_from`"
29
+ assert self .migrate_to is not None , "You must define `migrate_to`"
30
+
31
+ # Step 1: Set up the MigrationExecutor
32
+ executor = MigrationExecutor (connection )
28
33
29
- # Step 2: Reverse to the starting migration state
30
- migrate_from = [(self .app , self .migrate_from )]
31
- migrate_to = [(self .app , self .migrate_to )]
32
- old_migrate_state = executor .migrate (migrate_from )
33
- old_apps = old_migrate_state .apps
34
+ # Step 2: Reverse to the starting migration state
35
+ migrate_from = [(self .app , self .migrate_from )]
36
+ migrate_to = [(self .app , self .migrate_to )]
37
+ old_migrate_state = executor .migrate (migrate_from )
38
+ old_apps = old_migrate_state .apps
34
39
35
- # Step 3: Run the `setup_before_migration` hook with old state models
36
- self . setup_before_migration (old_apps )
40
+ # Step 3: Call `callback` old state models
41
+ callback (old_apps )
37
42
38
- # Step 4: Apply the migration we want to test with any settings overrides
39
- with override_settings (** self .setting_overrides ):
43
+ # Step 4: Apply the migration we want to test with any settings overrides
40
44
executor = MigrationExecutor (connection )
41
45
executor .loader .build_graph () # reload the graph in case of dependency changes
42
46
executor .migrate (migrate_to )
43
47
44
- # Set `self.apps` to the post-migration state
45
- self .apps = executor .loader .project_state (migrate_to ).apps
46
-
47
- def setup_before_migration (self , apps ):
48
- """
49
- Hook to set up the state before the migration. Subclasses can
50
- override this to create data or perform other setup actions.
51
- """
52
- pass
48
+ yield _migrate
53
49
54
50
55
51
class TestMigrateAPICredentialToService (BaseMigrationTest ):
56
52
app = "vng_api_common"
57
53
migrate_from = "0005_auto_20190614_1346"
58
54
migrate_to = "0006_delete_apicredential"
59
55
60
- def setup_before_migration (self , apps ):
61
- Service = apps .get_model ("zgw_consumers" , "Service" )
62
- APICredential = apps .get_model ("vng_api_common" , "APICredential" )
63
-
64
- APICredential .objects .create (
65
- api_root = "https://example.com/zaken/api/v1/" ,
66
- label = "Zaken API" ,
67
- client_id = "user" ,
68
- secret = "secret" ,
69
- user_id = "user" ,
70
- user_representation = "User" ,
71
- )
56
+ def test_migrate_api_credentials_to_services (self , setup_migration : Callable ):
57
+ def migration_callback (apps : Apps ) -> None :
58
+ Service = apps .get_model ("zgw_consumers" , "Service" )
59
+ APICredential = apps .get_model ("vng_api_common" , "APICredential" )
60
+
61
+ APICredential .objects .create (
62
+ api_root = "https://example.com/zaken/api/v1/" ,
63
+ label = "Zaken API" ,
64
+ client_id = "user" ,
65
+ secret = "secret" ,
66
+ user_id = "user" ,
67
+ user_representation = "User" ,
68
+ )
69
+
70
+ APICredential .objects .create (
71
+ api_root = "https://example.com/api/v1/" ,
72
+ label = "Selectielijst API" ,
73
+ client_id = "user2" ,
74
+ secret = "secret2" ,
75
+ user_id = "user2" ,
76
+ user_representation = "User2" ,
77
+ )
78
+
79
+ APICredential .objects .create (
80
+ api_root = "https://example.com/documenten/api/v1/" ,
81
+ label = "Documenten API" ,
82
+ client_id = "user3" ,
83
+ secret = "secret3" ,
84
+ user_id = "user3" ,
85
+ user_representation = "User3" ,
86
+ )
87
+ Service .objects .create (
88
+ api_root = "https://example.com/documenten/api/v1/" ,
89
+ label = "Documenten" ,
90
+ slug = "already-exists" ,
91
+ api_type = APITypes .drc ,
92
+ auth_type = AuthTypes .zgw ,
93
+ client_id = "user4" ,
94
+ secret = "secret4" ,
95
+ user_id = "user4" ,
96
+ user_representation = "User4" ,
97
+ )
98
+
99
+ setup_migration (migration_callback )
72
100
73
- APICredential .objects .create (
74
- api_root = "https://example.com/api/v1/" ,
75
- label = "Selectielijst API" ,
76
- client_id = "user2" ,
77
- secret = "secret2" ,
78
- user_id = "user2" ,
79
- user_representation = "User2" ,
80
- )
81
-
82
- APICredential .objects .create (
83
- api_root = "https://example.com/documenten/api/v1/" ,
84
- label = "Documenten API" ,
85
- client_id = "user3" ,
86
- secret = "secret3" ,
87
- user_id = "user3" ,
88
- user_representation = "User3" ,
89
- )
90
- Service .objects .create (
91
- api_root = "https://example.com/documenten/api/v1/" ,
92
- label = "Documenten" ,
93
- slug = "already-exists" ,
94
- api_type = APITypes .drc ,
95
- auth_type = AuthTypes .zgw ,
96
- client_id = "user4" ,
97
- secret = "secret4" ,
98
- user_id = "user4" ,
99
- user_representation = "User4" ,
100
- )
101
-
102
- def test_migrate_api_credentials_to_services (self ):
103
101
Service = global_apps .get_model ("zgw_consumers" , "Service" )
104
102
105
103
zaken_service = Service .objects .get (slug = "zaken-api" )
@@ -136,33 +134,93 @@ def test_migrate_api_credentials_to_services(self):
136
134
assert documenten_service .user_id == "user4"
137
135
assert documenten_service .user_representation == "User4"
138
136
137
+ def test_duplicate_service_slug (self , setup_migration ):
138
+ """
139
+ Test that the migration handles duplicate slugs correctly
140
+ """
141
+
142
+ def migration_callback (apps ):
143
+ Service = apps .get_model ("zgw_consumers" , "Service" )
144
+ APICredential = apps .get_model ("vng_api_common" , "APICredential" )
145
+
146
+ APICredential .objects .create (
147
+ api_root = "https://example.com/documenten/api/v1/" ,
148
+ label = "Documenten API" ,
149
+ client_id = "user3" ,
150
+ secret = "secret3" ,
151
+ user_id = "user3" ,
152
+ user_representation = "User3" ,
153
+ )
154
+
155
+ Service .objects .create (
156
+ api_root = "https://example.com/documenten/api/v2/" ,
157
+ label = "Documenten" ,
158
+ slug = "documenten-api" ,
159
+ api_type = APITypes .drc ,
160
+ auth_type = AuthTypes .zgw ,
161
+ client_id = "user4" ,
162
+ secret = "secret4" ,
163
+ user_id = "user4" ,
164
+ user_representation = "User4" ,
165
+ )
166
+
167
+ setup_migration (migration_callback )
168
+
169
+ Service = global_apps .get_model ("zgw_consumers" , "Service" )
170
+
171
+ service_v1 = Service .objects .get (slug = "documenten-api-2" )
172
+
173
+ assert service_v1 .api_root == "https://example.com/documenten/api/v1/"
174
+ assert service_v1 .label == "Documenten API"
175
+ assert service_v1 .api_type == APITypes .drc
176
+ assert service_v1 .auth_type == AuthTypes .zgw
177
+ assert service_v1 .client_id == "user3"
178
+ assert service_v1 .secret == "secret3"
179
+ assert service_v1 .user_id == "user3"
180
+ assert service_v1 .user_representation == "User3"
181
+
182
+ service_v2 = Service .objects .get (slug = "documenten-api" )
183
+
184
+ assert service_v2 .api_root == "https://example.com/documenten/api/v2/"
185
+ assert service_v2 .label == "Documenten"
186
+ assert service_v2 .api_type == APITypes .drc
187
+ assert service_v2 .auth_type == AuthTypes .zgw
188
+ assert service_v2 .client_id == "user4"
189
+ assert service_v2 .secret == "secret4"
190
+ assert service_v2 .user_id == "user4"
191
+ assert service_v2 .user_representation == "User4"
192
+
139
193
140
194
class TestMigrateAuthorizationsConfigAPIRootToService (BaseMigrationTest ):
141
195
app = "authorizations"
142
196
migrate_from = "0015_auto_20220318_1608"
143
197
migrate_to = "0016_remove_authorizationsconfig_api_root_and_more"
144
198
145
- def setup_before_migration (self , apps ):
146
- Service = apps .get_model ("zgw_consumers" , "Service" )
147
- AuthorizationsConfig = apps .get_model ("authorizations" , "AuthorizationsConfig" )
148
-
149
- config , _ = AuthorizationsConfig .objects .get_or_create ()
150
- config .api_root = "https://example.com/autorisaties/api/v1/"
151
- config .save ()
152
-
153
- self .service = Service .objects .create (
154
- api_root = "https://example.com/autorisaties/api/v1/" ,
155
- label = "Autorisaties" ,
156
- slug = "autorisaties" ,
157
- api_type = APITypes .ac ,
158
- auth_type = AuthTypes .zgw ,
159
- client_id = "user" ,
160
- secret = "secret" ,
161
- user_id = "user" ,
162
- user_representation = "User" ,
163
- )
199
+ def test_migrate_api_root_to_service (self , setup_migration : Callable ):
200
+ def migration_callback (apps : Apps ) -> None :
201
+ Service = apps .get_model ("zgw_consumers" , "Service" )
202
+ AuthorizationsConfig = apps .get_model (
203
+ "authorizations" , "AuthorizationsConfig"
204
+ )
205
+
206
+ config , _ = AuthorizationsConfig .objects .get_or_create ()
207
+ config .api_root = "https://example.com/autorisaties/api/v1/"
208
+ config .save ()
209
+
210
+ self .service = Service .objects .create (
211
+ api_root = "https://example.com/autorisaties/api/v1/" ,
212
+ label = "Autorisaties" ,
213
+ slug = "autorisaties" ,
214
+ api_type = APITypes .ac ,
215
+ auth_type = AuthTypes .zgw ,
216
+ client_id = "user" ,
217
+ secret = "secret" ,
218
+ user_id = "user" ,
219
+ user_representation = "User" ,
220
+ )
221
+
222
+ setup_migration (migration_callback )
164
223
165
- def test_migrate_api_root_to_service (self ):
166
224
AuthorizationsConfig = global_apps .get_model (
167
225
"authorizations" , "AuthorizationsConfig"
168
226
)
0 commit comments