use db::Db;
use sqlx::PgPool;

#[sqlx::test]
async fn migrate_is_idempotent_and_creates_audit_log(pool: PgPool) {
    let db = Db::from_pool(pool);

    // sqlx::test already applied migrations to this temp DB; re-running must be a
    // no-op success (idempotent).
    db.migrate()
        .await
        .expect("re-running migrate is idempotent");

    let regclass: Option<String> =
        sqlx::query_scalar("SELECT to_regclass('public.audit_log')::text")
            .fetch_one(db.pool())
            .await
            .unwrap();
    assert_eq!(regclass.as_deref(), Some("audit_log"));
}

#[sqlx::test]
async fn migrate_creates_object_table(pool: PgPool) {
    let db = Db::from_pool(pool);

    let regclass: Option<String> = sqlx::query_scalar("SELECT to_regclass('public.object')::text")
        .fetch_one(db.pool())
        .await
        .unwrap();

    assert_eq!(regclass.as_deref(), Some("object"));
}

#[sqlx::test]
async fn migrate_creates_vocabulary_and_authority_tables(pool: PgPool) {
    let db = Db::from_pool(pool);
    for table in [
        "vocabulary",
        "term",
        "term_label",
        "authority",
        "authority_label",
    ] {
        let regclass: Option<String> =
            sqlx::query_scalar(&format!("SELECT to_regclass('public.{table}')::text"))
                .fetch_one(db.pool())
                .await
                .unwrap();
        assert_eq!(
            regclass.as_deref(),
            Some(table),
            "table {table} should exist"
        );
    }
}

#[sqlx::test]
async fn migrate_creates_field_definition_tables(pool: PgPool) {
    let db = Db::from_pool(pool);

    for table in ["field_definition", "field_definition_label"] {
        let regclass: Option<String> =
            sqlx::query_scalar(&format!("SELECT to_regclass('public.{table}')::text"))
                .fetch_one(db.pool())
                .await
                .unwrap();
        assert_eq!(
            regclass.as_deref(),
            Some(table),
            "table {table} should exist"
        );
    }
}

#[sqlx::test]
async fn migrate_adds_object_fields_column(pool: PgPool) {
    let db = Db::from_pool(pool);
    let exists: Option<bool> = sqlx::query_scalar(
        "SELECT true FROM information_schema.columns \
         WHERE table_name = 'object' AND column_name = 'fields'",
    )
    .fetch_optional(db.pool())
    .await
    .unwrap();
    assert_eq!(exists, Some(true));
}
