#![cfg(feature = "test-postgres")]
#![allow(clippy::unwrap_used, clippy::print_stderr)]
use std::io::Write;
use fraiseql_core::schema::{CompiledSchema, QueryDefinition};
use tempfile::NamedTempFile;
use tokio_postgres::NoTls;
const SETUP: &str = "\
DROP SCHEMA IF EXISTS fql_487_cli CASCADE;
CREATE SCHEMA fql_487_cli;
CREATE VIEW fql_487_cli.v_orders AS SELECT '{}'::jsonb AS data;
CREATE FUNCTION fql_487_cli.fn_create_order(p_input jsonb)
RETURNS jsonb LANGUAGE sql AS $$ SELECT p_input $$;
";
const TEARDOWN: &str = "DROP SCHEMA IF EXISTS fql_487_cli CASCADE;";
async fn run_sql(url: &str, sql: &str) {
let (client, connection) = tokio_postgres::connect(url, NoTls).await.unwrap();
tokio::spawn(async move {
let _ = connection.await;
});
client.batch_execute(sql).await.unwrap();
}
fn write_compiled(schema: &CompiledSchema) -> NamedTempFile {
let mut f = NamedTempFile::new().unwrap();
f.write_all(serde_json::to_string(schema).unwrap().as_bytes()).unwrap();
f.flush().unwrap();
f
}
fn query(name: &str, sql_source: &str) -> QueryDefinition {
QueryDefinition::new(name, "T").with_sql_source(sql_source).returning_list()
}
#[tokio::test]
async fn validate_against_db_exits_nonzero_on_unbacked_source() {
let Some(url) = fraiseql_test_support::try_database_url() else {
eprintln!("skipping #487 CLI-gate test: no DATABASE_URL");
return;
};
run_sql(&url, SETUP).await;
let schema = CompiledSchema {
queries: vec![query("orders", "fql_487_cli.v_missing")],
..Default::default()
};
let file = write_compiled(&schema);
let result = fraiseql_cli::commands::validate::run_against_db(
file.path().to_str().unwrap(),
&url,
false,
)
.await;
assert!(result.is_err(), "an unbacked sql_source must fail validate --against-db");
run_sql(&url, TEARDOWN).await;
}
#[tokio::test]
async fn validate_against_db_succeeds_when_fully_backed() {
let Some(url) = fraiseql_test_support::try_database_url() else {
eprintln!("skipping #487 CLI-gate test: no DATABASE_URL");
return;
};
run_sql(&url, SETUP).await;
let schema = CompiledSchema {
queries: vec![query("orders", "fql_487_cli.v_orders")],
..Default::default()
};
let file = write_compiled(&schema);
let result = fraiseql_cli::commands::validate::run_against_db(
file.path().to_str().unwrap(),
&url,
false,
)
.await;
assert!(result.is_ok(), "a fully-backed schema must pass: {result:?}");
run_sql(&url, TEARDOWN).await;
}