#![allow(dead_code)]
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use tokio::sync::OnceCell;
use umbral::orm::{DynQuerySet, InsertedPk};
use umbral_core::db;
#[derive(Debug, Clone, sqlx::FromRow, Serialize, Deserialize, umbral::orm::Model)]
#[umbral(table = "ifp_tag")]
pub struct Tag {
#[umbral(primary_key, string, max_length = 50)]
pub slug: String,
#[umbral(string)]
pub label: String,
}
#[derive(Debug, Clone, sqlx::FromRow, Serialize, Deserialize, umbral::orm::Model)]
#[umbral(table = "ifp_note")]
pub struct Note {
pub id: i64,
#[umbral(string)]
pub body: String,
}
static BOOT: OnceCell<()> = OnceCell::const_new();
async fn boot() {
BOOT.get_or_init(|| async {
let settings = umbral::Settings::from_env().expect("figment defaults");
let pool = db::connect_sqlite("sqlite::memory:")
.await
.expect("in-memory sqlite");
umbral::App::builder()
.settings(settings)
.database("default", pool.clone())
.model::<Tag>()
.model::<Note>()
.build()
.expect("App::build");
umbral_core::migrate::create_tables_for_tests()
.await
.expect("create the test schema");
})
.await;
}
fn tag_meta() -> umbral::migrate::ModelMeta {
umbral::migrate::registered_models()
.into_iter()
.find(|m| m.table == "ifp_tag")
.expect("Tag registered")
}
fn note_meta() -> umbral::migrate::ModelMeta {
umbral::migrate::registered_models()
.into_iter()
.find(|m| m.table == "ifp_note")
.expect("Note registered")
}
fn form(pairs: &[(&str, &str)]) -> HashMap<String, String> {
pairs
.iter()
.map(|(k, v)| (k.to_string(), v.to_string()))
.collect()
}
#[tokio::test]
async fn string_pk_insert_returns_the_real_key_not_zero() {
boot().await;
let pk = DynQuerySet::for_meta(&tag_meta())
.insert_form(&form(&[("slug", "rust"), ("label", "Rust")]), &[])
.await
.expect("insert tag");
assert_eq!(
pk,
InsertedPk::Text("rust".to_string()),
"a String-PK insert must return its actual key in true shape, not a lying 0"
);
assert_eq!(pk.to_string(), "rust");
assert_eq!(pk.as_i64(), None, "a String PK is not an integer");
}
#[tokio::test]
async fn integer_pk_insert_still_returns_the_rowid() {
boot().await;
let pk = DynQuerySet::for_meta(¬e_meta())
.insert_form(&form(&[("body", "hello")]), &[])
.await
.expect("insert note");
let id = pk.as_i64().expect("integer PK comes back as Int");
assert!(id > 0, "auto-increment id should be a real rowid");
assert_eq!(pk.to_string(), id.to_string());
}
#[tokio::test]
async fn empty_insert_reports_none() {
boot().await;
let pk = DynQuerySet::for_meta(¬e_meta())
.insert_form(&form(&[("body", "x")]), &["body".to_string()])
.await
.expect("insert note");
assert!(
pk.is_none(),
"an insert with no columns must report None: {pk:?}"
);
}