mod common;
use common::*;
use pgmold::apply::{apply_migration, ApplyOptions};
#[tokio::test]
async fn apply_succeeds_with_valid_schema() {
let (_container, url) = setup_postgres().await;
let connection = PgConnection::new(&url).await.unwrap();
let schema_file = write_sql_temp_file(
r#"
CREATE TABLE users (
id BIGINT NOT NULL PRIMARY KEY,
email TEXT NOT NULL
);
"#,
);
let schema_source = schema_file.path().to_str().unwrap().to_string();
let result = apply_migration(
&[schema_source],
&connection,
ApplyOptions {
dry_run: false,
allow_destructive: false,
},
)
.await
.unwrap();
assert!(result.applied);
assert!(!result.operations.is_empty());
let schema = introspect_schema(&connection, &["public".to_string()], false)
.await
.unwrap();
assert!(schema.tables.contains_key("public.users"));
}
#[tokio::test]
async fn apply_returns_error_on_invalid_sql() {
let (_container, url) = setup_postgres().await;
let connection = PgConnection::new(&url).await.unwrap();
sqlx::query("CREATE TABLE users (id INT PRIMARY KEY)")
.execute(connection.pool())
.await
.unwrap();
sqlx::query("INSERT INTO users (id) VALUES (1)")
.execute(connection.pool())
.await
.unwrap();
let schema_file = write_sql_temp_file(
r#"
CREATE TABLE users (
id INT NOT NULL PRIMARY KEY,
name TEXT NOT NULL
);
"#,
);
let schema_source = schema_file.path().to_str().unwrap().to_string();
let result = apply_migration(
&[schema_source],
&connection,
ApplyOptions {
dry_run: false,
allow_destructive: false,
},
)
.await;
assert!(result.is_err(), "Expected Err but got Ok");
}
#[tokio::test]
async fn apply_rolls_back_on_failure() {
let (_container, url) = setup_postgres().await;
let connection = PgConnection::new(&url).await.unwrap();
let setup_file = write_sql_temp_file(
r#"
CREATE TABLE table_a (
id INT NOT NULL PRIMARY KEY,
value TEXT
);
"#,
);
let setup_source = setup_file.path().to_str().unwrap().to_string();
apply_migration(
&[setup_source],
&connection,
ApplyOptions {
dry_run: false,
allow_destructive: false,
},
)
.await
.unwrap();
sqlx::query("INSERT INTO table_a (id, value) VALUES (1, 'row1')")
.execute(connection.pool())
.await
.unwrap();
let target_file = write_sql_temp_file(
r#"
CREATE TABLE table_a (
id INT NOT NULL PRIMARY KEY,
value TEXT,
required_field TEXT NOT NULL
);
CREATE TABLE table_b (
id INT NOT NULL PRIMARY KEY
);
"#,
);
let target_source = target_file.path().to_str().unwrap().to_string();
let apply_result = apply_migration(
&[target_source],
&connection,
ApplyOptions {
dry_run: false,
allow_destructive: false,
},
)
.await;
assert!(apply_result.is_err(), "Expected Err but got Ok");
let schema = introspect_schema(&connection, &["public".to_string()], false)
.await
.unwrap();
assert!(
!schema.tables.contains_key("public.table_b"),
"table_b should not exist after rollback"
);
}