use chrono::{NaiveDateTime, Utc}; use googletest::prelude::*; use serde::{Deserialize, Serialize}; use uuid::Uuid; use common::*; use dojo_macros::Model; use dojo_orm::Database; mod common; macro_rules! create_users { ($db: ident, names = $($name:literal),+) => { $($db.insert(&User { id: Uuid::new_v4(), name: $name.to_string(), email: concat!($name, "@gmail.com").to_string(), created_at: Utc::now().naive_utc(), updated_at: Utc::now().naive_utc(), }).await?;)+ }; } macro_rules! create_paging_args { (first = $first: literal) => { (Some($first as i64), None) }; (first = $first: literal, after = $after: ident) => { (Some($first as i64), Some($after)) }; (last = $last: literal) => { (Some($last as i64), None) }; (last = $last: literal, before = $before: ident) => { (Some($last as i64), Some($before)) }; } #[tokio::test] async fn test_paging_forward() -> anyhow::Result<()> { let db: Database; setup!(db); #[derive(Serialize, Deserialize, Debug, Model)] #[dojo(name = "users", sort_keys = ["created_at", "id"])] struct User { id: Uuid, name: String, email: String, created_at: NaiveDateTime, updated_at: NaiveDateTime, } create_users!(db, names = "linh1", "linh2", "linh3"); let (first, after) = create_paging_args!(first = 1); let pagination = db.bind::().cursor(first, after, None, None).await?; assert_that!( pagination.items, contains_each![pat!(User { id: anything(), name: eq("linh1"), email: eq("linh1@gmail.com"), created_at: anything(), updated_at: anything(), })] ); assert_that!(pagination.has_next, eq(true)); assert_that!(pagination.has_previous, eq(false)); let cursor = pagination.end_cursor().unwrap(); let (first, after) = create_paging_args!(first = 1, after = cursor); let pagination = db.bind::().cursor(first, after, None, None).await?; assert_that!( pagination.items, contains_each![pat!(User { id: anything(), name: eq("linh2"), email: eq("linh2@gmail.com"), created_at: anything(), updated_at: anything(), })] ); assert_that!(pagination.has_next, eq(true)); assert_that!(pagination.has_previous, eq(false)); let cursor = pagination.end_cursor().unwrap(); let (first, after) = create_paging_args!(first = 1, after = cursor); let pagination = db.bind::().cursor(first, after, None, None).await?; assert_that!( pagination.items, contains_each![pat!(User { id: anything(), name: eq("linh3"), email: eq("linh3@gmail.com"), created_at: anything(), updated_at: anything(), })] ); assert_that!(pagination.has_next, eq(false)); assert_that!(pagination.has_previous, eq(false)); let cursor = pagination.end_cursor().unwrap(); let (first, after) = create_paging_args!(first = 1, after = cursor); let pagination = db.bind::().cursor(first, after, None, None).await?; assert_that!(pagination.items, empty()); assert_that!(pagination.has_next, eq(false)); assert_that!(pagination.has_previous, eq(false)); Ok(()) } #[tokio::test] async fn test_paging_backward() -> anyhow::Result<()> { let db: Database; setup!(db); #[derive(Serialize, Deserialize, Debug, Model)] #[dojo(name = "users", sort_keys = ["created_at", "id"])] struct User { id: Uuid, name: String, email: String, created_at: NaiveDateTime, updated_at: NaiveDateTime, } create_users!(db, names = "linh1", "linh2", "linh3"); let (last, before) = create_paging_args!(last = 1); let pagination = db.bind::().cursor(None, None, last, before).await?; assert_that!( pagination.items, contains_each![pat!(User { id: anything(), name: eq("linh3"), email: eq("linh3@gmail.com"), created_at: anything(), updated_at: anything(), })] ); assert_that!(pagination.has_next, eq(false)); assert_that!(pagination.has_previous, eq(true)); let cursor = pagination.end_cursor().unwrap(); let (last, before) = create_paging_args!(last = 1, before = cursor); let pagination = db.bind::().cursor(None, None, last, before).await?; assert_that!( pagination.items, contains_each![pat!(User { id: anything(), name: eq("linh2"), email: eq("linh2@gmail.com"), created_at: anything(), updated_at: anything(), })] ); assert_that!(pagination.has_next, eq(false)); assert_that!(pagination.has_previous, eq(true)); let cursor = pagination.end_cursor().unwrap(); let (last, before) = create_paging_args!(last = 1, before = cursor); let pagination = db.bind::().cursor(None, None, last, before).await?; assert_that!( pagination.items, contains_each![pat!(User { id: anything(), name: eq("linh1"), email: eq("linh1@gmail.com"), created_at: anything(), updated_at: anything(), })] ); assert_that!(pagination.has_next, eq(false)); assert_that!(pagination.has_previous, eq(false)); let cursor = pagination.end_cursor().unwrap(); let (last, before) = create_paging_args!(last = 1, before = cursor); let pagination = db.bind::().cursor(None, None, last, before).await?; assert_that!(pagination.items, empty()); assert_that!(pagination.has_next, eq(false)); assert_that!(pagination.has_previous, eq(false)); Ok(()) }