#![cfg(feature = "postgres-live")]
use pylon_http::DataStore;
use pylon_kernel::{AppManifest, ManifestEntity, ManifestField};
use pylon_storage::pg_datastore::PostgresDataStore;
fn require_pg_url() -> Option<String> {
std::env::var("TEST_POSTGRES_URL").ok()
}
fn test_manifest() -> AppManifest {
AppManifest {
manifest_version: 1,
name: "pg_live_test".into(),
version: "0.1.0".into(),
entities: vec![ManifestEntity {
name: "PgTodo".into(),
fields: vec![
ManifestField {
name: "title".into(),
field_type: "string".into(),
optional: false,
unique: false,
crdt: None,
},
ManifestField {
name: "done".into(),
field_type: "bool".into(),
optional: false,
unique: false,
crdt: None,
},
],
indexes: vec![],
relations: vec![],
search: None,
crdt: true,
}],
routes: vec![],
queries: vec![],
actions: vec![],
policies: vec![],
}
}
#[test]
fn crud_roundtrip() {
let Some(url) = require_pg_url() else {
eprintln!("TEST_POSTGRES_URL not set — skipping pg_live test");
return;
};
let store = PostgresDataStore::connect(&url, test_manifest()).expect("connect");
let id = store
.insert(
"PgTodo",
&serde_json::json!({"title": "buy milk", "done": false}),
)
.expect("insert");
let row = store.get_by_id("PgTodo", &id).expect("get").expect("row");
assert_eq!(row["title"], "buy milk");
assert_eq!(row["done"], false);
let updated = store
.update(
"PgTodo",
&id,
&serde_json::json!({"title": "buy milk", "done": true}),
)
.expect("update");
assert!(updated);
let row2 = store.get_by_id("PgTodo", &id).expect("get").expect("row");
assert_eq!(row2["done"], true);
let rows = store.list("PgTodo").expect("list");
assert!(rows.iter().any(|r| r["id"] == serde_json::json!(id)));
let deleted = store.delete("PgTodo", &id).expect("delete");
assert!(deleted);
let gone = store.get_by_id("PgTodo", &id).expect("get after delete");
assert!(gone.is_none());
}
#[test]
fn unknown_entity_returns_error() {
let Some(url) = require_pg_url() else {
eprintln!("TEST_POSTGRES_URL not set — skipping pg_live test");
return;
};
let store = PostgresDataStore::connect(&url, test_manifest()).expect("connect");
let err = store
.insert("NotAnEntity", &serde_json::json!({}))
.expect_err("must reject unknown entity");
assert!(
err.code.contains("UNKNOWN") || err.code.contains("ENTITY") || !err.message.is_empty(),
"error should be descriptive, got code={} message={}",
err.code,
err.message
);
}