cratestack-sqlx 0.3.7

Rust-native schema-first framework for typed HTTP APIs, generated clients, and backend services.
Documentation
#![cfg(test)]

use crate::{
    FieldRef, FilterExpr, OrderClause, PolicyExpr, ReadPolicy, ReadPredicate, SortDirection,
    render::{render_filter_expr_sql, render_order_clause_sql, render_read_policy_sql},
};
use cratestack_core::{CoolContext, Value};

#[test]
fn relation_filters_render_explicit_quantifiers() {
    let some = FilterExpr::relation_some(
        "users",
        "id",
        "sessions",
        "user_id",
        FieldRef::<(), String>::new("label")
            .contains("Revoked")
            .into(),
    );
    let every = FilterExpr::relation_every(
        "users",
        "id",
        "sessions",
        "user_id",
        FieldRef::<(), String>::new("label")
            .contains("Session")
            .into(),
    );
    let none = FilterExpr::relation_none(
        "users",
        "id",
        "sessions",
        "user_id",
        FieldRef::<(), Option<String>>::new("revoked_at")
            .is_not_null()
            .into(),
    );
    let mut bind_index = 1usize;
    let mut some_sql = String::new();
    render_filter_expr_sql(&some, &mut some_sql, &mut bind_index);
    let mut every_sql = String::new();
    render_filter_expr_sql(&every, &mut every_sql, &mut bind_index);
    let mut none_sql = String::new();
    render_filter_expr_sql(&none, &mut none_sql, &mut bind_index);

    assert_eq!(
        some_sql,
        "EXISTS (SELECT 1 FROM sessions WHERE sessions.user_id = users.id AND label LIKE $1)"
    );
    assert_eq!(
        every_sql,
        "NOT EXISTS (SELECT 1 FROM sessions WHERE sessions.user_id = users.id AND NOT (label LIKE $2))"
    );
    assert_eq!(
        none_sql,
        "NOT EXISTS (SELECT 1 FROM sessions WHERE sessions.user_id = users.id AND revoked_at IS NOT NULL)"
    );
}

#[test]
fn relation_scalar_order_preview_uses_correlated_subquery() {
    let clause = OrderClause::relation_scalar(
        "posts",
        "author_id",
        "users",
        "id",
        "users.email",
        SortDirection::Asc,
    );
    let mut sql = String::new();
    render_order_clause_sql(&clause, &mut sql);

    assert_eq!(
        sql,
        "(SELECT users.email FROM users WHERE users.id = posts.author_id LIMIT 1) ASC NULLS LAST"
    );
}

#[test]
fn relation_policy_preview_uses_exists_subquery() {
    let policy = [ReadPolicy {
        expr: PolicyExpr::Predicate(ReadPredicate::Relation {
            quantifier: crate::RelationQuantifier::ToOne,
            parent_table: "posts",
            parent_column: "author_id",
            related_table: "users",
            related_column: "id",
            expr: &PolicyExpr::Predicate(ReadPredicate::FieldEqAuth {
                column: "email",
                auth_field: "email",
            }),
        }),
    }];
    let ctx = CoolContext::authenticated([(
        "email".to_owned(),
        Value::String("owner@example.com".to_owned()),
    )]);

    let mut bind_index = 1usize;
    let sql = render_read_policy_sql(&policy, &[], &ctx, &mut bind_index)
        .expect("policy preview should render");

    assert_eq!(
        sql,
        "EXISTS (SELECT 1 FROM users WHERE users.id = posts.author_id AND email = $1)"
    );
}