285 lines
7.7 KiB
Rust
285 lines
7.7 KiB
Rust
// tests/adresar/get_adresar_count_test.rs
|
|
use rstest::{fixture, rstest};
|
|
use server::adresar::handlers::get_adresar_count;
|
|
use common::proto::multieko2::common::Empty;
|
|
use crate::common::setup_test_db;
|
|
use sqlx::PgPool;
|
|
use tonic;
|
|
|
|
// For connection pooling
|
|
#[fixture]
|
|
async fn pool() -> PgPool {
|
|
setup_test_db().await
|
|
}
|
|
|
|
#[fixture]
|
|
async fn closed_pool(#[future] pool: PgPool) -> PgPool {
|
|
let pool = pool.await;
|
|
pool.close().await;
|
|
pool
|
|
}
|
|
|
|
// Create a self-contained test that runs in a transaction
|
|
// --------------------------------------------------------
|
|
// Instead of relying on table state and doing our own transaction management,
|
|
// we'll mock the database response to `get_adresar_count` and verify it behaves correctly
|
|
|
|
/// Test only that the handler returns the value from the database correctly
|
|
#[rstest]
|
|
#[tokio::test]
|
|
async fn test_handler_returns_count_from_database(#[future] pool: PgPool) {
|
|
let pool = pool.await;
|
|
|
|
// First, get whatever count the database currently has
|
|
let count_query = sqlx::query_scalar!(
|
|
"SELECT COUNT(*) FROM adresar WHERE deleted = FALSE"
|
|
)
|
|
.fetch_one(&pool)
|
|
.await
|
|
.unwrap()
|
|
.unwrap_or(0);
|
|
|
|
// Now call our handler and verify it returns the same count
|
|
let response = get_adresar_count(&pool, Empty {}).await.unwrap();
|
|
assert_eq!(response.count, count_query);
|
|
}
|
|
|
|
/// Test handler correctly excludes deleted records
|
|
#[rstest]
|
|
#[tokio::test]
|
|
async fn test_handler_excludes_deleted_records(#[future] pool: PgPool) {
|
|
let pool = pool.await;
|
|
|
|
// Use a transaction to isolate this test completely
|
|
let mut tx = pool.begin().await.unwrap();
|
|
|
|
// Count records where deleted = TRUE
|
|
let deleted_count = sqlx::query_scalar!(
|
|
"SELECT COUNT(*) FROM adresar WHERE deleted = TRUE"
|
|
)
|
|
.fetch_one(&mut *tx)
|
|
.await
|
|
.unwrap()
|
|
.unwrap_or(0);
|
|
|
|
// Count records where deleted = FALSE
|
|
let active_count = sqlx::query_scalar!(
|
|
"SELECT COUNT(*) FROM adresar WHERE deleted = FALSE"
|
|
)
|
|
.fetch_one(&mut *tx)
|
|
.await
|
|
.unwrap()
|
|
.unwrap_or(0);
|
|
|
|
// Count all records
|
|
let total_count = sqlx::query_scalar!(
|
|
"SELECT COUNT(*) FROM adresar"
|
|
)
|
|
.fetch_one(&mut *tx)
|
|
.await
|
|
.unwrap()
|
|
.unwrap_or(0);
|
|
|
|
// Verify our counts are consistent
|
|
assert_eq!(total_count, active_count + deleted_count);
|
|
|
|
// Verify our handler returns only the active count
|
|
let response = get_adresar_count(&pool, Empty {}).await.unwrap();
|
|
assert_eq!(response.count, active_count);
|
|
|
|
// Rollback transaction
|
|
tx.rollback().await.unwrap();
|
|
}
|
|
|
|
/// Test SQL query behavior with deleted flag
|
|
#[rstest]
|
|
#[tokio::test]
|
|
async fn test_deleted_flag_filters_records(#[future] pool: PgPool) {
|
|
let pool = pool.await;
|
|
|
|
// Use a transaction to isolate this test completely
|
|
let mut tx = pool.begin().await.unwrap();
|
|
|
|
// Insert test records inside this transaction
|
|
// They will be automatically rolled back at the end
|
|
|
|
sqlx::query!(
|
|
"INSERT INTO adresar (firma, deleted) VALUES ($1, FALSE)",
|
|
"Test Active Record"
|
|
)
|
|
.execute(&mut *tx)
|
|
.await
|
|
.unwrap();
|
|
|
|
sqlx::query!(
|
|
"INSERT INTO adresar (firma, deleted) VALUES ($1, TRUE)",
|
|
"Test Deleted Record"
|
|
)
|
|
.execute(&mut *tx)
|
|
.await
|
|
.unwrap();
|
|
|
|
// Count active records in the transaction
|
|
let active_count = sqlx::query_scalar!(
|
|
"SELECT COUNT(*) FROM adresar WHERE deleted = FALSE"
|
|
)
|
|
.fetch_one(&mut *tx)
|
|
.await
|
|
.unwrap()
|
|
.unwrap_or(0);
|
|
|
|
// Count deleted records in the transaction
|
|
let deleted_count = sqlx::query_scalar!(
|
|
"SELECT COUNT(*) FROM adresar WHERE deleted = TRUE"
|
|
)
|
|
.fetch_one(&mut *tx)
|
|
.await
|
|
.unwrap()
|
|
.unwrap_or(0);
|
|
|
|
// Verify at least one active and one deleted record
|
|
assert!(active_count > 0);
|
|
assert!(deleted_count > 0);
|
|
|
|
// Rollback transaction
|
|
tx.rollback().await.unwrap();
|
|
}
|
|
|
|
/// Test the handler returns an error with a closed pool
|
|
#[rstest]
|
|
#[tokio::test]
|
|
async fn test_database_error(#[future] closed_pool: PgPool) {
|
|
let closed_pool = closed_pool.await;
|
|
let result = get_adresar_count(&closed_pool, Empty {}).await;
|
|
assert!(result.is_err());
|
|
assert_eq!(result.unwrap_err().code(), tonic::Code::Internal);
|
|
}
|
|
|
|
/// Test the behavior of setting deleted to true and back
|
|
#[rstest]
|
|
#[tokio::test]
|
|
async fn test_update_of_deleted_flag(#[future] pool: PgPool) {
|
|
let pool = pool.await;
|
|
|
|
// Use a transaction for complete isolation
|
|
let mut tx = pool.begin().await.unwrap();
|
|
|
|
// Insert a test record
|
|
let id = sqlx::query_scalar!(
|
|
"INSERT INTO adresar (firma, deleted) VALUES ($1, FALSE) RETURNING id",
|
|
"Test Toggle Record"
|
|
)
|
|
.fetch_one(&mut *tx)
|
|
.await
|
|
.unwrap();
|
|
|
|
// Count active records with this new record
|
|
let active_count_before = sqlx::query_scalar!(
|
|
"SELECT COUNT(*) FROM adresar WHERE deleted = FALSE"
|
|
)
|
|
.fetch_one(&mut *tx)
|
|
.await
|
|
.unwrap()
|
|
.unwrap_or(0);
|
|
|
|
// Mark as deleted
|
|
sqlx::query!(
|
|
"UPDATE adresar SET deleted = TRUE WHERE id = $1",
|
|
id
|
|
)
|
|
.execute(&mut *tx)
|
|
.await
|
|
.unwrap();
|
|
|
|
// Count active records after marking as deleted
|
|
let active_count_after_delete = sqlx::query_scalar!(
|
|
"SELECT COUNT(*) FROM adresar WHERE deleted = FALSE"
|
|
)
|
|
.fetch_one(&mut *tx)
|
|
.await
|
|
.unwrap()
|
|
.unwrap_or(0);
|
|
|
|
// Verify count decreased by 1
|
|
assert_eq!(active_count_after_delete, active_count_before - 1);
|
|
|
|
// Mark as active again
|
|
sqlx::query!(
|
|
"UPDATE adresar SET deleted = FALSE WHERE id = $1",
|
|
id
|
|
)
|
|
.execute(&mut *tx)
|
|
.await
|
|
.unwrap();
|
|
|
|
// Count active records after marking as active
|
|
let active_count_after_restore = sqlx::query_scalar!(
|
|
"SELECT COUNT(*) FROM adresar WHERE deleted = FALSE"
|
|
)
|
|
.fetch_one(&mut *tx)
|
|
.await
|
|
.unwrap()
|
|
.unwrap_or(0);
|
|
|
|
// Verify count increased back to original
|
|
assert_eq!(active_count_after_restore, active_count_before);
|
|
|
|
// Rollback transaction
|
|
tx.rollback().await.unwrap();
|
|
}
|
|
|
|
/// Test edge cases of an empty table
|
|
#[rstest]
|
|
#[tokio::test]
|
|
async fn test_edge_case_empty_table(#[future] pool: PgPool) {
|
|
let pool = pool.await;
|
|
|
|
// Not literally testing an empty table since we can't truncate due to FK constraints
|
|
// But we can verify the count response is never negative
|
|
let response = get_adresar_count(&pool, Empty {}).await.unwrap();
|
|
assert!(response.count >= 0);
|
|
}
|
|
|
|
/// Test adding a record and verifying count increases
|
|
#[rstest]
|
|
#[tokio::test]
|
|
async fn test_count_increments_after_adding_record(#[future] pool: PgPool) {
|
|
let pool = pool.await;
|
|
|
|
// Use a transaction for complete isolation
|
|
let mut tx = pool.begin().await.unwrap();
|
|
|
|
// Get initial active count inside transaction
|
|
let initial_count = sqlx::query_scalar!(
|
|
"SELECT COUNT(*) FROM adresar WHERE deleted = FALSE"
|
|
)
|
|
.fetch_one(&mut *tx)
|
|
.await
|
|
.unwrap()
|
|
.unwrap_or(0);
|
|
|
|
// Add a record inside the transaction
|
|
sqlx::query!(
|
|
"INSERT INTO adresar (firma, deleted) VALUES ($1, FALSE)",
|
|
"Test Increment Record"
|
|
)
|
|
.execute(&mut *tx)
|
|
.await
|
|
.unwrap();
|
|
|
|
// Get new count inside transaction
|
|
let new_count = sqlx::query_scalar!(
|
|
"SELECT COUNT(*) FROM adresar WHERE deleted = FALSE"
|
|
)
|
|
.fetch_one(&mut *tx)
|
|
.await
|
|
.unwrap()
|
|
.unwrap_or(0);
|
|
|
|
// Verify count increased by exactly 1
|
|
assert_eq!(new_count, initial_count + 1);
|
|
|
|
// Rollback transaction
|
|
tx.rollback().await.unwrap();
|
|
}
|