#[path = "../common/mod.rs"]
mod common;
use common::post_entity;
use common::user_entity;
use common::{DbOrSkip, require_db, reset_rows, setup_schema};
use arcature_data::{Page, QueryModel, find_by_pk, insert, of};
use sea_orm::{ActiveValue, ColumnTrait};
#[tokio::test]
async fn query_filter_order_paginate_and_eager_load() {
let DbOrSkip::Db(db) = require_db().await else {
return;
};
setup_schema(db.db()).await.expect("schema");
reset_rows(db.db()).await.expect("reset");
let now = chrono::Utc::now().fixed_offset();
let u1 = insert(
db.db(),
user_entity::ActiveModel {
id: ActiveValue::NotSet,
email: ActiveValue::Set("a@x.test".into()),
name: ActiveValue::Set("Alice".into()),
created_at: ActiveValue::Set(now),
},
)
.await
.expect("insert user 1");
let u2 = insert(
db.db(),
user_entity::ActiveModel {
id: ActiveValue::NotSet,
email: ActiveValue::Set("b@x.test".into()),
name: ActiveValue::Set("Bob".into()),
created_at: ActiveValue::Set(now),
},
)
.await
.expect("insert user 2");
for (user_id, title, active) in [
(u1.id, "A1".to_string(), true),
(u1.id, "A2".to_string(), true),
(u1.id, "A3-draft".to_string(), false),
(u2.id, "B1".to_string(), true),
(u2.id, "B2".to_string(), true),
] {
insert(
db.db(),
post_entity::ActiveModel {
id: ActiveValue::NotSet,
user_id: ActiveValue::Set(user_id),
title: ActiveValue::Set(title),
active: ActiveValue::Set(active),
body: ActiveValue::Set(None),
created_at: ActiveValue::Set(now),
},
)
.await
.expect("insert post");
}
let found = find_by_pk::<user_entity::Entity, _>(db.db(), u1.id)
.await
.expect("find_by_pk");
assert!(found.is_some(), "user 1 should be found by PK");
assert_eq!(found.unwrap().email, "a@x.test");
let missing = find_by_pk::<user_entity::Entity, _>(db.db(), 999_999)
.await
.expect("find_by_pk missing");
assert!(
missing.is_none(),
"missing PK returns Ok(None), not an error"
);
let active = post_entity::Entity::query(db.db())
.filter(post_entity::Column::Active.eq(true))
.order_by_desc(post_entity::Column::Title)
.all()
.await
.expect("query active");
assert_eq!(active.len(), 4, "four active posts");
assert_eq!(active[0].title, "B2");
let page: Page<post_entity::Model> = post_entity::Entity::query(db.db())
.filter(post_entity::Column::Active.eq(true))
.paginate(1)
.page(2)
.fetch()
.await
.expect("paginate");
assert_eq!(page.per_page, 1);
assert_eq!(page.page, 2);
assert_eq!(page.total, 4, "total across all pages");
assert_eq!(page.num_pages, 4);
assert_eq!(page.rows.len(), 1, "one row on page 2");
let err = post_entity::Entity::query(db.db())
.paginate(2)
.page(0)
.fetch()
.await
.expect_err("page 0 must error");
assert_eq!(err.id(), "arcature_data.pagination.page_must_be_positive");
let err = post_entity::Entity::query(db.db())
.paginate(0)
.fetch()
.await
.expect_err("per_page 0 must error");
assert_eq!(
err.id(),
"arcature_data.pagination.per_page_must_be_positive"
);
let with_users: Vec<(post_entity::Model, Option<user_entity::Model>)> =
post_entity::Entity::query(db.db())
.with(of::<user_entity::Entity>())
.await
.expect("eager load");
assert!(
with_users.iter().all(|(_, u)| u.is_some()),
"each post has a user"
);
assert_eq!(with_users.len(), 5);
db.stop().await;
}