// 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(); }