1
- use crate :: support:: database:: {
2
- create_test_source_database, run_etl_migrations_on_source_database,
3
- } ;
4
- use crate :: {
5
- support:: mocks:: create_default_image,
6
- support:: mocks:: destinations:: create_destination,
7
- support:: mocks:: sources:: create_source,
8
- support:: mocks:: tenants:: { create_tenant, create_tenant_with_id_and_name} ,
9
- support:: test_app:: { TestApp , spawn_test_app} ,
10
- } ;
11
1
use etl_api:: routes:: pipelines:: {
12
2
CreatePipelineRequest , CreatePipelineResponse , GetPipelineReplicationStatusResponse ,
13
- ReadPipelineResponse , ReadPipelinesResponse , RollbackTableStateRequest ,
14
- RollbackTableStateResponse , RollbackType , SimpleTableReplicationState ,
15
- UpdatePipelineConfigRequest , UpdatePipelineConfigResponse , UpdatePipelineImageRequest ,
16
- UpdatePipelineRequest ,
3
+ GetPipelineVersionResponse , ReadPipelineResponse , ReadPipelinesResponse ,
4
+ RollbackTableStateRequest , RollbackTableStateResponse , RollbackType ,
5
+ SimpleTableReplicationState , UpdatePipelineConfigRequest , UpdatePipelineConfigResponse ,
6
+ UpdatePipelineImageRequest , UpdatePipelineRequest ,
17
7
} ;
18
8
use etl_config:: shared:: { BatchConfig , PgConnectionConfig } ;
19
9
use etl_postgres:: sqlx:: test_utils:: drop_pg_database;
@@ -22,11 +12,22 @@ use reqwest::StatusCode;
22
12
use sqlx:: PgPool ;
23
13
use sqlx:: postgres:: types:: Oid ;
24
14
15
+ use crate :: support:: database:: {
16
+ create_test_source_database, run_etl_migrations_on_source_database,
17
+ } ;
18
+ use crate :: support:: mocks:: create_image_with_name;
25
19
use crate :: support:: mocks:: pipelines:: {
26
20
ConfigUpdateType , create_pipeline_with_config, new_pipeline_config,
27
21
partially_updated_optional_pipeline_config, updated_optional_pipeline_config,
28
22
updated_pipeline_config,
29
23
} ;
24
+ use crate :: {
25
+ support:: mocks:: create_default_image,
26
+ support:: mocks:: destinations:: create_destination,
27
+ support:: mocks:: sources:: create_source,
28
+ support:: mocks:: tenants:: { create_tenant, create_tenant_with_id_and_name} ,
29
+ support:: test_app:: { TestApp , spawn_test_app} ,
30
+ } ;
30
31
31
32
mod support;
32
33
@@ -1280,3 +1281,90 @@ async fn deleting_pipeline_removes_table_schemas_from_source_database() {
1280
1281
1281
1282
drop_pg_database ( & source_db_config) . await ;
1282
1283
}
1284
+
1285
+ #[ tokio:: test( flavor = "multi_thread" ) ]
1286
+ async fn pipeline_version_returns_current_version_and_no_new_version_when_default_matches ( ) {
1287
+ init_test_tracing ( ) ;
1288
+ // Arrange
1289
+ let app = spawn_test_app ( ) . await ;
1290
+ let tenant_id = create_tenant ( & app) . await ;
1291
+ let source_id = create_source ( & app, & tenant_id) . await ;
1292
+ let destination_id = create_destination ( & app, & tenant_id) . await ;
1293
+
1294
+ // Create a default image without a tag -> should parse to "latest".
1295
+ create_image_with_name ( & app, "some/image" . to_string ( ) , true ) . await ;
1296
+
1297
+ let pipeline_id = {
1298
+ let req = CreatePipelineRequest {
1299
+ source_id,
1300
+ destination_id,
1301
+ config : new_pipeline_config ( ) ,
1302
+ } ;
1303
+ let resp = app. create_pipeline ( & tenant_id, & req) . await ;
1304
+ let resp: CreatePipelineResponse =
1305
+ resp. json ( ) . await . expect ( "failed to deserialize response" ) ;
1306
+ resp. id
1307
+ } ;
1308
+
1309
+ // Act
1310
+ let response = app. get_pipeline_version ( & tenant_id, pipeline_id) . await ;
1311
+
1312
+ // Assert
1313
+ assert ! ( response. status( ) . is_success( ) ) ;
1314
+ let version: GetPipelineVersionResponse = response
1315
+ . json ( )
1316
+ . await
1317
+ . expect ( "failed to deserialize response" ) ;
1318
+ assert_eq ! ( version. version. name, "latest" ) ;
1319
+ assert ! ( version. new_version. is_none( ) ) ;
1320
+ }
1321
+
1322
+ #[ tokio:: test( flavor = "multi_thread" ) ]
1323
+ async fn pipeline_version_includes_new_default_version_when_available ( ) {
1324
+ init_test_tracing ( ) ;
1325
+ // Arrange
1326
+ let app = spawn_test_app ( ) . await ;
1327
+ let tenant_id = create_tenant ( & app) . await ;
1328
+ let source_id = create_source ( & app, & tenant_id) . await ;
1329
+ let destination_id = create_destination ( & app, & tenant_id) . await ;
1330
+
1331
+ // Initial default image for pipeline creation
1332
+ let old_default_image_id =
1333
+ create_image_with_name ( & app, "supabase/replicator:1.2.3" . to_string ( ) , true ) . await ;
1334
+
1335
+ let pipeline_id = {
1336
+ let req = CreatePipelineRequest {
1337
+ source_id,
1338
+ destination_id,
1339
+ config : new_pipeline_config ( ) ,
1340
+ } ;
1341
+ let resp = app. create_pipeline ( & tenant_id, & req) . await ;
1342
+ let resp: CreatePipelineResponse =
1343
+ resp. json ( ) . await . expect ( "failed to deserialize response" ) ;
1344
+ resp. id
1345
+ } ;
1346
+
1347
+ // Create a new default image (should flip default)
1348
+ let default_image_id =
1349
+ create_image_with_name ( & app, "supabase/replicator:1.3.0" . to_string ( ) , true ) . await ;
1350
+
1351
+ // Act
1352
+ let response = app. get_pipeline_version ( & tenant_id, pipeline_id) . await ;
1353
+
1354
+ // Assert
1355
+ assert ! ( response. status( ) . is_success( ) ) ;
1356
+ let version: GetPipelineVersionResponse = response
1357
+ . json ( )
1358
+ . await
1359
+ . expect ( "failed to deserialize response" ) ;
1360
+
1361
+ let current_version = version. version ;
1362
+ assert_eq ! ( current_version. id, old_default_image_id) ;
1363
+ assert_eq ! ( current_version. name, "1.2.3" ) ;
1364
+
1365
+ let new_version = version
1366
+ . new_version
1367
+ . expect ( "expected new_version to be present" ) ;
1368
+ assert_eq ! ( new_version. id, default_image_id) ;
1369
+ assert_eq ! ( new_version. name, "1.3.0" ) ;
1370
+ }
0 commit comments