working test for count of get
This commit is contained in:
@@ -26,3 +26,4 @@ path = "src/lib.rs"
|
|||||||
tokio = { version = "1.0", features = ["full", "test-util"] }
|
tokio = { version = "1.0", features = ["full", "test-util"] }
|
||||||
dotenv = "0.15"
|
dotenv = "0.15"
|
||||||
rstest = "0.24.0"
|
rstest = "0.24.0"
|
||||||
|
lazy_static = "1.5.0"
|
||||||
|
|||||||
@@ -5,20 +5,19 @@ use common::proto::multieko2::common::Empty;
|
|||||||
use crate::common::setup_test_db;
|
use crate::common::setup_test_db;
|
||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
use tonic;
|
use tonic;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use tokio::sync::Mutex;
|
||||||
|
|
||||||
|
// Use a global mutex to synchronize test execution
|
||||||
|
// This prevents tests from interfering with each other
|
||||||
|
lazy_static::lazy_static! {
|
||||||
|
static ref TEST_MUTEX: Arc<Mutex<()>> = Arc::new(Mutex::new(()));
|
||||||
|
}
|
||||||
|
|
||||||
#[fixture]
|
#[fixture]
|
||||||
async fn pool() -> PgPool {
|
async fn pool() -> PgPool {
|
||||||
let pool = setup_test_db().await;
|
// Just connect to the test database without truncating anything
|
||||||
|
setup_test_db().await
|
||||||
// Ensure sequence is set correctly to avoid primary key conflicts
|
|
||||||
sqlx::query_scalar!(
|
|
||||||
"SELECT setval('adresar_id_seq', COALESCE((SELECT MAX(id) FROM adresar), 0) + 1, false)"
|
|
||||||
)
|
|
||||||
.fetch_one(&pool)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
pool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[fixture]
|
#[fixture]
|
||||||
@@ -33,25 +32,15 @@ async fn closed_pool(#[future] pool: PgPool) -> PgPool {
|
|||||||
async fn test_count_increments_after_adding_record(#[future] pool: PgPool) {
|
async fn test_count_increments_after_adding_record(#[future] pool: PgPool) {
|
||||||
let pool = pool.await;
|
let pool = pool.await;
|
||||||
|
|
||||||
|
// Lock to prevent concurrent test execution
|
||||||
|
let _guard = TEST_MUTEX.lock().await;
|
||||||
|
|
||||||
// Get initial count of active records
|
// Get initial count of active records
|
||||||
let initial_count = sqlx::query_scalar!("SELECT COUNT(*) FROM adresar WHERE deleted = FALSE")
|
|
||||||
.fetch_one(&pool)
|
|
||||||
.await
|
|
||||||
.unwrap()
|
|
||||||
.unwrap_or(0);
|
|
||||||
|
|
||||||
// Verify initial count from handler
|
|
||||||
let initial_response = get_adresar_count(&pool, Empty {}).await.unwrap();
|
let initial_response = get_adresar_count(&pool, Empty {}).await.unwrap();
|
||||||
assert_eq!(initial_response.count, initial_count);
|
let initial_count = initial_response.count;
|
||||||
|
|
||||||
// Generate unique identifier for test data
|
|
||||||
let test_id = std::time::SystemTime::now()
|
|
||||||
.duration_since(std::time::UNIX_EPOCH)
|
|
||||||
.unwrap()
|
|
||||||
.as_millis();
|
|
||||||
|
|
||||||
// Insert new active record with unique name
|
// Insert new active record with unique name
|
||||||
let unique_name = format!("Test Company {}", test_id);
|
let unique_name = format!("Test Company {}", chrono::Utc::now().timestamp_millis());
|
||||||
sqlx::query!(
|
sqlx::query!(
|
||||||
"INSERT INTO adresar (firma, deleted) VALUES ($1, FALSE)",
|
"INSERT INTO adresar (firma, deleted) VALUES ($1, FALSE)",
|
||||||
unique_name
|
unique_name
|
||||||
@@ -65,70 +54,123 @@ async fn test_count_increments_after_adding_record(#[future] pool: PgPool) {
|
|||||||
assert_eq!(updated_response.count, initial_count + 1);
|
assert_eq!(updated_response.count, initial_count + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[rstest]
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_add_multiple_records_and_check_count(#[future] pool: PgPool) {
|
||||||
|
let pool = pool.await;
|
||||||
|
|
||||||
|
// Lock to prevent concurrent test execution
|
||||||
|
let _guard = TEST_MUTEX.lock().await;
|
||||||
|
|
||||||
|
// Get initial count
|
||||||
|
let initial_response = get_adresar_count(&pool, Empty {}).await.unwrap();
|
||||||
|
let initial_count = initial_response.count;
|
||||||
|
|
||||||
|
// Add 5 active records
|
||||||
|
let timestamp = chrono::Utc::now().timestamp_millis();
|
||||||
|
for i in 0..5 {
|
||||||
|
let unique_name = format!("Batch Company {} #{}", timestamp, i);
|
||||||
|
sqlx::query!(
|
||||||
|
"INSERT INTO adresar (firma, deleted) VALUES ($1, FALSE)",
|
||||||
|
unique_name
|
||||||
|
)
|
||||||
|
.execute(&pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify count increased by 5
|
||||||
|
let updated_response = get_adresar_count(&pool, Empty {}).await.unwrap();
|
||||||
|
assert_eq!(updated_response.count, initial_count + 5);
|
||||||
|
}
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_deleted_records_not_counted(#[future] pool: PgPool) {
|
async fn test_deleted_records_not_counted(#[future] pool: PgPool) {
|
||||||
let pool = pool.await;
|
let pool = pool.await;
|
||||||
|
|
||||||
|
// Lock to prevent concurrent test execution
|
||||||
|
let _guard = TEST_MUTEX.lock().await;
|
||||||
|
|
||||||
// Get initial count
|
// Get initial count
|
||||||
let initial_count = sqlx::query_scalar!("SELECT COUNT(*) FROM adresar WHERE deleted = FALSE")
|
let initial_response = get_adresar_count(&pool, Empty {}).await.unwrap();
|
||||||
.fetch_one(&pool)
|
let initial_count = initial_response.count;
|
||||||
.await
|
|
||||||
.unwrap()
|
|
||||||
.unwrap_or(0);
|
|
||||||
|
|
||||||
// Generate unique test identifier
|
// Generate unique identifier for test
|
||||||
let test_id = std::time::SystemTime::now()
|
let timestamp = chrono::Utc::now().timestamp_millis();
|
||||||
.duration_since(std::time::UNIX_EPOCH)
|
|
||||||
.unwrap()
|
|
||||||
.as_millis();
|
|
||||||
|
|
||||||
// Insert test records (2 active, 1 deleted)
|
// Insert 5 test records (2 active, 3 deleted)
|
||||||
let max_id = sqlx::query_scalar!("SELECT COALESCE(MAX(id), 0) FROM adresar")
|
for i in 0..5 {
|
||||||
.fetch_one(&pool)
|
let is_deleted = i >= 2; // First 2 active, next 3 deleted
|
||||||
.await
|
let unique_name = format!("Deletion Test {} #{}", timestamp, i);
|
||||||
.unwrap()
|
|
||||||
.unwrap_or(0);
|
|
||||||
|
|
||||||
sqlx::query!(
|
sqlx::query!(
|
||||||
"INSERT INTO adresar (id, firma, deleted) VALUES ($1, $2, FALSE)",
|
"INSERT INTO adresar (firma, deleted) VALUES ($1, $2)",
|
||||||
max_id + 1,
|
unique_name,
|
||||||
format!("Active 1 {}", test_id)
|
is_deleted
|
||||||
|
)
|
||||||
|
.execute(&pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify count only increased by 2 (the non-deleted records)
|
||||||
|
let updated_response = get_adresar_count(&pool, Empty {}).await.unwrap();
|
||||||
|
assert_eq!(updated_response.count, initial_count + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rstest]
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_mark_existing_record_as_deleted(#[future] pool: PgPool) {
|
||||||
|
let pool = pool.await;
|
||||||
|
|
||||||
|
// Lock to prevent concurrent test execution
|
||||||
|
let _guard = TEST_MUTEX.lock().await;
|
||||||
|
|
||||||
|
// Get initial count
|
||||||
|
let initial_response = get_adresar_count(&pool, Empty {}).await.unwrap();
|
||||||
|
let initial_count = initial_response.count;
|
||||||
|
|
||||||
|
// Insert one record
|
||||||
|
let unique_name = format!("Delete Me {}", chrono::Utc::now().timestamp_millis());
|
||||||
|
let record_id = sqlx::query_scalar!(
|
||||||
|
"INSERT INTO adresar (firma, deleted) VALUES ($1, FALSE) RETURNING id",
|
||||||
|
unique_name
|
||||||
|
)
|
||||||
|
.fetch_one(&pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// Verify count increased by 1
|
||||||
|
let after_insert_response = get_adresar_count(&pool, Empty {}).await.unwrap();
|
||||||
|
assert_eq!(after_insert_response.count, initial_count + 1);
|
||||||
|
|
||||||
|
// Mark record as deleted
|
||||||
|
sqlx::query!(
|
||||||
|
"UPDATE adresar SET deleted = TRUE WHERE id = $1",
|
||||||
|
record_id
|
||||||
)
|
)
|
||||||
.execute(&pool)
|
.execute(&pool)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
sqlx::query!(
|
// Verify count decreased back to initial
|
||||||
"INSERT INTO adresar (id, firma, deleted) VALUES ($1, $2, TRUE)",
|
let after_delete_response = get_adresar_count(&pool, Empty {}).await.unwrap();
|
||||||
max_id + 2,
|
assert_eq!(after_delete_response.count, initial_count);
|
||||||
format!("Deleted {}", test_id)
|
}
|
||||||
)
|
|
||||||
.execute(&pool)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
sqlx::query!(
|
#[rstest]
|
||||||
"INSERT INTO adresar (id, firma, deleted) VALUES ($1, $2, FALSE)",
|
#[tokio::test]
|
||||||
max_id + 3,
|
async fn test_edge_case_empty_table(#[future] pool: PgPool) {
|
||||||
format!("Active 2 {}", test_id)
|
let pool = pool.await;
|
||||||
)
|
|
||||||
.execute(&pool)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// Verify count only includes active records
|
// Get current count (whatever it is)
|
||||||
let response = get_adresar_count(&pool, Empty {}).await.unwrap();
|
let current_response = get_adresar_count(&pool, Empty {}).await.unwrap();
|
||||||
assert_eq!(response.count, initial_count + 2);
|
let current_count = current_response.count;
|
||||||
|
|
||||||
// Reset sequence to maintain test stability
|
// We're not going to empty the table (could violate FK constraints)
|
||||||
sqlx::query_scalar!(
|
// But we can at least verify that the count is non-negative
|
||||||
"SELECT setval('adresar_id_seq', $1, true)",
|
assert!(current_count >= 0);
|
||||||
max_id + 4
|
|
||||||
)
|
|
||||||
.fetch_one(&pool)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
@@ -139,3 +181,56 @@ async fn test_database_error(#[future] closed_pool: PgPool) {
|
|||||||
assert!(result.is_err());
|
assert!(result.is_err());
|
||||||
assert_eq!(result.unwrap_err().code(), tonic::Code::Internal);
|
assert_eq!(result.unwrap_err().code(), tonic::Code::Internal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[rstest]
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_toggle_deleted_status(#[future] pool: PgPool) {
|
||||||
|
let pool = pool.await;
|
||||||
|
|
||||||
|
// Lock to prevent concurrent test execution
|
||||||
|
let _guard = TEST_MUTEX.lock().await;
|
||||||
|
|
||||||
|
// Get initial count
|
||||||
|
let initial_response = get_adresar_count(&pool, Empty {}).await.unwrap();
|
||||||
|
let initial_count = initial_response.count;
|
||||||
|
|
||||||
|
// Create a new record that will be toggled
|
||||||
|
let unique_name = format!("Toggle Me {}", chrono::Utc::now().timestamp_millis());
|
||||||
|
let record_id = sqlx::query_scalar!(
|
||||||
|
"INSERT INTO adresar (firma, deleted) VALUES ($1, FALSE) RETURNING id",
|
||||||
|
unique_name
|
||||||
|
)
|
||||||
|
.fetch_one(&pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// Verify count increased by 1
|
||||||
|
let after_insert_response = get_adresar_count(&pool, Empty {}).await.unwrap();
|
||||||
|
assert_eq!(after_insert_response.count, initial_count + 1);
|
||||||
|
|
||||||
|
// Mark as deleted
|
||||||
|
sqlx::query!(
|
||||||
|
"UPDATE adresar SET deleted = TRUE WHERE id = $1",
|
||||||
|
record_id
|
||||||
|
)
|
||||||
|
.execute(&pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// Verify count back to initial
|
||||||
|
let after_delete_response = get_adresar_count(&pool, Empty {}).await.unwrap();
|
||||||
|
assert_eq!(after_delete_response.count, initial_count);
|
||||||
|
|
||||||
|
// Mark as NOT deleted
|
||||||
|
sqlx::query!(
|
||||||
|
"UPDATE adresar SET deleted = FALSE WHERE id = $1",
|
||||||
|
record_id
|
||||||
|
)
|
||||||
|
.execute(&pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// Verify count increased again
|
||||||
|
let after_undelete_response = get_adresar_count(&pool, Empty {}).await.unwrap();
|
||||||
|
assert_eq!(after_undelete_response.count, initial_count + 1);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user