#![cfg(all(
feature = "query-adapters",
any(feature = "sqlite", feature = "postgres", feature = "mysql")
))]
mod common;
use aro_core::pagination::PageRequest;
use aro_core::repository::{Paginatable, Queryable, Repository};
use aro_fletch::EntityQuery;
use common::{User, setup};
use fletch_orm::{Filter, Op, Order};
#[tokio::test]
async fn find_by_name_filter() {
let (_pool, repo) = setup().await;
repo.create(User {
id: 1,
name: "Alice".into(),
})
.await
.unwrap();
repo.create(User {
id: 2,
name: "Bob".into(),
})
.await
.unwrap();
repo.create(User {
id: 3,
name: "Alicia".into(),
})
.await
.unwrap();
let query = EntityQuery::new()
.filter(Filter::new("name", Op::Like, "%Ali%"))
.order_by("id", Order::Asc);
let results = repo.find_by(query).await.unwrap();
assert_eq!(results.len(), 2);
assert_eq!(results[0].name, "Alice");
assert_eq!(results[1].name, "Alicia");
}
#[tokio::test]
async fn find_by_empty_query_returns_all() {
let (_pool, repo) = setup().await;
repo.create(User {
id: 1,
name: "Alice".into(),
})
.await
.unwrap();
repo.create(User {
id: 2,
name: "Bob".into(),
})
.await
.unwrap();
let results = repo.find_by(EntityQuery::new()).await.unwrap();
assert_eq!(results.len(), 2);
}
#[tokio::test]
async fn find_page_first_page() {
let (_pool, repo) = setup().await;
for (id, name) in [(1, "Alice"), (2, "Bob"), (3, "Charlie"), (4, "Diana")] {
repo.create(User {
id,
name: name.into(),
})
.await
.unwrap();
}
let page = repo
.find_page(PageRequest {
page: 1,
per_page: 2,
})
.await
.unwrap();
assert_eq!(page.total, 4);
assert_eq!(page.page, 1);
assert_eq!(page.per_page, 2);
assert_eq!(page.items.len(), 2);
assert_eq!(page.items[0].id, 1);
assert_eq!(page.items[1].id, 2);
assert!(page.has_next_page());
}
#[tokio::test]
async fn find_page_second_page() {
let (_pool, repo) = setup().await;
for (id, name) in [(1, "Alice"), (2, "Bob"), (3, "Charlie")] {
repo.create(User {
id,
name: name.into(),
})
.await
.unwrap();
}
let page = repo
.find_page(PageRequest {
page: 2,
per_page: 2,
})
.await
.unwrap();
assert_eq!(page.total, 3);
assert_eq!(page.items.len(), 1);
assert_eq!(page.items[0].id, 3);
assert!(!page.has_next_page());
}
#[tokio::test]
async fn find_page_empty_table() {
let (_pool, repo) = setup().await;
let page = repo
.find_page(PageRequest {
page: 1,
per_page: 10,
})
.await
.unwrap();
assert_eq!(page.total, 0);
assert!(page.items.is_empty());
assert!(!page.has_next_page());
}
#[tokio::test]
async fn find_page_by_applies_filter_to_total_and_items() {
let (_pool, repo) = setup().await;
for (id, name) in [(1, "Alice"), (2, "Bob"), (3, "Alicia"), (4, "Alix")] {
repo.create(User {
id,
name: name.into(),
})
.await
.unwrap();
}
let query = EntityQuery::new()
.filter(Filter::new("name", Op::Like, "%Ali%"))
.order_by("id", Order::Asc);
let page = repo
.find_page_by(
query,
PageRequest {
page: 1,
per_page: 2,
},
)
.await
.unwrap();
assert_eq!(page.total, 3);
assert_eq!(page.items.len(), 2);
assert_eq!(page.items[0].name, "Alice");
assert_eq!(page.items[1].name, "Alicia");
assert!(page.has_next_page());
}
#[tokio::test]
async fn find_page_by_second_page_respects_filter() {
let (_pool, repo) = setup().await;
for (id, name) in [(1, "Alice"), (2, "Bob"), (3, "Alicia"), (4, "Alix")] {
repo.create(User {
id,
name: name.into(),
})
.await
.unwrap();
}
let query = EntityQuery::new()
.filter(Filter::new("name", Op::Like, "%Ali%"))
.order_by("id", Order::Asc);
let page = repo
.find_page_by(
query,
PageRequest {
page: 2,
per_page: 2,
},
)
.await
.unwrap();
assert_eq!(page.total, 3);
assert_eq!(page.items.len(), 1);
assert_eq!(page.items[0].name, "Alix");
assert!(!page.has_next_page());
}
#[tokio::test]
async fn find_page_by_empty_query_matches_find_page_total() {
let (_pool, repo) = setup().await;
for (id, name) in [(1, "Alice"), (2, "Bob"), (3, "Charlie")] {
repo.create(User {
id,
name: name.into(),
})
.await
.unwrap();
}
let request = PageRequest {
page: 1,
per_page: 10,
};
let unfiltered = repo.find_page(request.clone()).await.unwrap();
let filtered = repo
.find_page_by(EntityQuery::new(), request)
.await
.unwrap();
assert_eq!(filtered.total, unfiltered.total);
assert_eq!(filtered.items.len(), unfiltered.items.len());
}
#[tokio::test]
async fn find_page_by_preserves_custom_order() {
let (_pool, repo) = setup().await;
for (id, name) in [(1, "Alice"), (2, "Bob"), (3, "Charlie")] {
repo.create(User {
id,
name: name.into(),
})
.await
.unwrap();
}
let query = EntityQuery::new().order_by("name", Order::Desc);
let page = repo
.find_page_by(
query,
PageRequest {
page: 1,
per_page: 10,
},
)
.await
.unwrap();
assert_eq!(page.items.len(), 3);
assert_eq!(page.items[0].name, "Charlie");
assert_eq!(page.items[1].name, "Bob");
assert_eq!(page.items[2].name, "Alice");
}