@@ -18,13 +18,12 @@ def mock_chdir(monkeypatch, tmp_path):
1818def migration_folder (tmp_path ):
1919 migration_folder_path = tmp_path / MIGRATION_FOLDER
2020 migration_folder_path .mkdir (exist_ok = True )
21- (migration_folder_path / "__init__.py" ).touch ()
2221 return migration_folder_path
2322
2423
2524@pytest .fixture
2625def data_migration_file (migration_folder ):
27- migration_id = "fake_file_name "
26+ migration_id = "fake_data_file_name "
2827 migration_file = migration_folder / f"20250406020202_{ migration_id } .py"
2928 migration_file .write_text (
3029 encoding = "utf-8" ,
@@ -40,9 +39,17 @@ def data_migration_file_error(migration_folder):
4039 file_data = MIGRATION_SCAFFOLDING_TEMPLATE .substitute (command_name = "DataBaseCommand" ).replace (
4140 "pass" , "raise Exception('Fake Error')"
4241 )
42+ migration_file .write_text (encoding = "utf-8" , data = file_data )
43+ return {"migration_id" : migration_id , "full_filename" : migration_file }
44+
45+
46+ @pytest .fixture
47+ def schema_migration_file (migration_folder ):
48+ migration_id = "fake_schema_file_name"
49+ migration_file = migration_folder / f"20260101010101_{ migration_id } .py"
4350 migration_file .write_text (
4451 encoding = "utf-8" ,
45- data = file_data ,
52+ data = MIGRATION_SCAFFOLDING_TEMPLATE . substitute ( command_name = "SchemaBaseCommand" ) ,
4653 )
4754 return {"migration_id" : migration_id , "full_filename" : migration_file }
4855
@@ -84,20 +91,57 @@ def test_migrate_command_multiple_options_error(runner):
8491
8592
8693@freeze_time ("2025-04-06 13:00:00" )
87- def test_migrate_data_migration (data_migration_file , migration_state_file , runner ):
94+ def test_migrate_data_migration (
95+ data_migration_file , schema_migration_file , migration_state_file , runner , log
96+ ):
8897 result = runner .invoke (app , ["migrate" , "--data" ])
8998
9099 assert result .exit_code == 0 , result .output
91100 migration_state_data = json .loads (migration_state_file .read_text (encoding = "utf-8" ))
92- assert migration_state_data ["fake_file_name" ] == {
93- "migration_id" : "fake_file_name" ,
94- "order_id" : 20250406020202 ,
95- "type" : "data" ,
96- "started_at" : "2025-04-06T13:00:00+00:00" ,
97- "applied_at" : "2025-04-06T13:00:00+00:00" ,
101+ assert migration_state_data == {
102+ "fake_data_file_name" : {
103+ "migration_id" : "fake_data_file_name" ,
104+ "order_id" : 20250406020202 ,
105+ "type" : "data" ,
106+ "started_at" : "2025-04-06T13:00:00+00:00" ,
107+ "applied_at" : "2025-04-06T13:00:00+00:00" ,
108+ }
109+ }
110+ assert "Running data migrations..." in result .output
111+ assert "Running migration: fake_data_file_name" in log .text
112+ assert "Migrations completed successfully." in result .output
113+
114+
115+ @freeze_time ("2025-04-06 13:00:00" )
116+ def test_migrate_skip_migration_already_applied (
117+ data_migration_file , migration_state_file , runner , log
118+ ):
119+ applied_state_data = {
120+ "fake_data_file_name" : {
121+ "migration_id" : "fake_data_file_name" ,
122+ "order_id" : 20250406020202 ,
123+ "type" : "data" ,
124+ "started_at" : "2025-04-06T13:00:00+00:00" ,
125+ "applied_at" : "2025-04-06T13:00:00+00:00" ,
126+ }
127+ }
128+ migration_state_file .write_text (data = json .dumps (applied_state_data ))
129+
130+ result = runner .invoke (app , ["migrate" , "--data" ])
131+
132+ assert result .exit_code == 0 , result .output
133+ migration_state_data = json .loads (migration_state_file .read_text (encoding = "utf-8" ))
134+ assert migration_state_data == {
135+ "fake_data_file_name" : {
136+ "migration_id" : "fake_data_file_name" ,
137+ "order_id" : 20250406020202 ,
138+ "type" : "data" ,
139+ "started_at" : "2025-04-06T13:00:00+00:00" ,
140+ "applied_at" : "2025-04-06T13:00:00+00:00" ,
141+ }
98142 }
99143 assert "Running data migrations..." in result .output
100- assert "Running migration: fake_file_name " in result . output
144+ assert "Skipping applied migration: fake_data_file_name " in log . text
101145 assert "Migrations completed successfully." in result .output
102146
103147
@@ -119,7 +163,7 @@ def test_migrate_data_duplicate_migration(runner, migration_folder):
119163
120164
121165@freeze_time ("2025-04-06 13:00:00" )
122- def test_migrate_data_run_script_fail (data_migration_file_error , migration_state_file , runner ):
166+ def test_migrate_data_run_script_fail (data_migration_file_error , migration_state_file , runner , log ):
123167 result = runner .invoke (app , ["migrate" , "--data" ])
124168
125169 assert result .exit_code == 1 , result .output
@@ -132,7 +176,7 @@ def test_migrate_data_run_script_fail(data_migration_file_error, migration_state
132176 "applied_at" : None ,
133177 }
134178 assert "Running data migrations..." in result .output
135- assert "Running migration: fake_error_file_name" in result . output
179+ assert "Running migration: fake_error_file_name" in log . text
136180 assert "Migration fake_error_file_name failed: Fake Error" in result .output
137181
138182
0 commit comments