#![allow(clippy::unwrap_used)]
use sqlx::PgPool;
use testcontainers::runners::AsyncRunner;
use testcontainers_modules::postgres::Postgres;
use super::storage_migration_sql;
async fn execute_ddl(pool: &PgPool, ddl: &str) {
for stmt in ddl.split(';') {
let trimmed = stmt.trim();
if !trimmed.is_empty() {
sqlx::query(trimmed).execute(pool).await.unwrap();
}
}
}
#[test]
fn test_migration_ddl_is_valid_sql() {
let ddl = storage_migration_sql();
assert!(
ddl.contains("_fraiseql_storage_objects"),
"DDL must create _fraiseql_storage_objects table"
);
assert!(ddl.contains("IF NOT EXISTS"), "DDL must use IF NOT EXISTS");
for col in [
"pk_storage_object",
"bucket",
"key",
"content_type",
"size_bytes",
"etag",
"owner_id",
"created_at",
"updated_at",
] {
assert!(ddl.contains(col), "DDL must contain column: {col}");
}
assert!(
ddl.contains("idx_storage_objects_bucket_key"),
"DDL must create bucket+key index"
);
assert!(ddl.contains("idx_storage_objects_owner"), "DDL must create owner index");
assert!(
ddl.contains("GENERATED ALWAYS AS IDENTITY"),
"pk must use GENERATED ALWAYS AS IDENTITY (Trinity pattern)"
);
}
#[tokio::test]
async fn test_migration_creates_table() {
let container = Postgres::default().start().await.unwrap();
let port = container.get_host_port_ipv4(5432).await.unwrap();
let url = format!("postgres://postgres:postgres@127.0.0.1:{port}/postgres");
let pool = PgPool::connect(&url).await.unwrap();
let ddl = storage_migration_sql();
execute_ddl(&pool, ddl).await;
let (exists,): (bool,) = sqlx::query_as(
"SELECT EXISTS (
SELECT 1 FROM pg_class WHERE relname = '_fraiseql_storage_objects'
)",
)
.fetch_one(&pool)
.await
.unwrap();
assert!(exists, "table _fraiseql_storage_objects must exist after migration");
}
#[tokio::test]
async fn test_migration_is_idempotent() {
let container = Postgres::default().start().await.unwrap();
let port = container.get_host_port_ipv4(5432).await.unwrap();
let url = format!("postgres://postgres:postgres@127.0.0.1:{port}/postgres");
let pool = PgPool::connect(&url).await.unwrap();
let ddl = storage_migration_sql();
execute_ddl(&pool, ddl).await;
execute_ddl(&pool, ddl).await;
}