working without any problems
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
// tests/adresar/get_adresar_by_position_test.rs
|
// tests/adresar/get_adresar_by_position_test.rs
|
||||||
use rstest::{fixture, rstest};
|
use rstest::{fixture, rstest};
|
||||||
use server::adresar::handlers::get_adresar_by_position;
|
use server::adresar::handlers::{get_adresar_by_position, get_adresar_count};
|
||||||
use common::proto::multieko2::common::PositionRequest;
|
use common::proto::multieko2::common::{PositionRequest, Empty};
|
||||||
use crate::common::setup_test_db;
|
use crate::common::setup_test_db;
|
||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
use tonic;
|
use tonic;
|
||||||
@@ -58,14 +58,14 @@ async fn find_position_of_record(pool: &PgPool, id: i64) -> Option<i64> {
|
|||||||
.fetch_all(pool)
|
.fetch_all(pool)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// Find the position of our record (1-based)
|
// Find the position of our record (1-based)
|
||||||
for (index, record_id) in records.iter().enumerate() {
|
for (index, record_id) in records.iter().enumerate() {
|
||||||
if *record_id == id {
|
if *record_id == id {
|
||||||
return Some((index + 1) as i64);
|
return Some((index + 1) as i64);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,11 +74,11 @@ async fn find_position_of_record(pool: &PgPool, id: i64) -> Option<i64> {
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_position_zero(#[future] pool: PgPool) {
|
async fn test_position_zero(#[future] pool: PgPool) {
|
||||||
let pool = pool.await;
|
let pool = pool.await;
|
||||||
|
|
||||||
// Request position 0 (invalid)
|
// Request position 0 (invalid)
|
||||||
let request = PositionRequest { position: 0 };
|
let request = PositionRequest { position: 0 };
|
||||||
let result = get_adresar_by_position(&pool, request).await;
|
let result = get_adresar_by_position(&pool, request).await;
|
||||||
|
|
||||||
// Verify it returns an error
|
// Verify it returns an error
|
||||||
assert!(result.is_err());
|
assert!(result.is_err());
|
||||||
assert_eq!(result.unwrap_err().code(), tonic::Code::InvalidArgument);
|
assert_eq!(result.unwrap_err().code(), tonic::Code::InvalidArgument);
|
||||||
@@ -88,11 +88,11 @@ async fn test_position_zero(#[future] pool: PgPool) {
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_position_negative(#[future] pool: PgPool) {
|
async fn test_position_negative(#[future] pool: PgPool) {
|
||||||
let pool = pool.await;
|
let pool = pool.await;
|
||||||
|
|
||||||
// Request negative position (invalid)
|
// Request negative position (invalid)
|
||||||
let request = PositionRequest { position: -1 };
|
let request = PositionRequest { position: -1 };
|
||||||
let result = get_adresar_by_position(&pool, request).await;
|
let result = get_adresar_by_position(&pool, request).await;
|
||||||
|
|
||||||
// Verify it returns an error
|
// Verify it returns an error
|
||||||
assert!(result.is_err());
|
assert!(result.is_err());
|
||||||
assert_eq!(result.unwrap_err().code(), tonic::Code::InvalidArgument);
|
assert_eq!(result.unwrap_err().code(), tonic::Code::InvalidArgument);
|
||||||
@@ -102,36 +102,36 @@ async fn test_position_negative(#[future] pool: PgPool) {
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_basic_position_retrieval(#[future] pool: PgPool) {
|
async fn test_basic_position_retrieval(#[future] pool: PgPool) {
|
||||||
let pool = pool.await;
|
let pool = pool.await;
|
||||||
|
|
||||||
// Take a lock to prevent concurrent test execution
|
// Take a lock to prevent concurrent test execution
|
||||||
let _guard = TEST_MUTEX.lock().await;
|
let _guard = TEST_MUTEX.lock().await;
|
||||||
|
|
||||||
// Use a unique prefix for test data to prevent conflicts
|
// Use a unique prefix for test data to prevent conflicts
|
||||||
let prefix = "PosBasicTest";
|
let prefix = "PosBasicTest";
|
||||||
|
|
||||||
// Clean up any existing test data
|
// Clean up any existing test data
|
||||||
cleanup_test_records(&pool, prefix).await;
|
cleanup_test_records(&pool, prefix).await;
|
||||||
|
|
||||||
// Create test records
|
// Create test records
|
||||||
let id1 = create_test_record(&pool, &format!("{}_1", prefix), false).await;
|
let id1 = create_test_record(&pool, &format!("{}_1", prefix), false).await;
|
||||||
let id2 = create_test_record(&pool, &format!("{}_2", prefix), false).await;
|
let id2 = create_test_record(&pool, &format!("{}_2", prefix), false).await;
|
||||||
let id3 = create_test_record(&pool, &format!("{}_3", prefix), false).await;
|
let id3 = create_test_record(&pool, &format!("{}_3", prefix), false).await;
|
||||||
|
|
||||||
// Find the positions of these records in the database
|
// Find the positions of these records in the database
|
||||||
let pos1 = find_position_of_record(&pool, id1).await.unwrap();
|
let pos1 = find_position_of_record(&pool, id1).await.unwrap();
|
||||||
let pos2 = find_position_of_record(&pool, id2).await.unwrap();
|
let pos2 = find_position_of_record(&pool, id2).await.unwrap();
|
||||||
let pos3 = find_position_of_record(&pool, id3).await.unwrap();
|
let pos3 = find_position_of_record(&pool, id3).await.unwrap();
|
||||||
|
|
||||||
// Test retrieving each position
|
// Test retrieving each position
|
||||||
let response1 = get_adresar_by_position(&pool, PositionRequest { position: pos1 }).await.unwrap();
|
let response1 = get_adresar_by_position(&pool, PositionRequest { position: pos1 }).await.unwrap();
|
||||||
assert_eq!(response1.id, id1);
|
assert_eq!(response1.id, id1);
|
||||||
|
|
||||||
let response2 = get_adresar_by_position(&pool, PositionRequest { position: pos2 }).await.unwrap();
|
let response2 = get_adresar_by_position(&pool, PositionRequest { position: pos2 }).await.unwrap();
|
||||||
assert_eq!(response2.id, id2);
|
assert_eq!(response2.id, id2);
|
||||||
|
|
||||||
let response3 = get_adresar_by_position(&pool, PositionRequest { position: pos3 }).await.unwrap();
|
let response3 = get_adresar_by_position(&pool, PositionRequest { position: pos3 }).await.unwrap();
|
||||||
assert_eq!(response3.id, id3);
|
assert_eq!(response3.id, id3);
|
||||||
|
|
||||||
// Clean up test data
|
// Clean up test data
|
||||||
cleanup_test_records(&pool, prefix).await;
|
cleanup_test_records(&pool, prefix).await;
|
||||||
}
|
}
|
||||||
@@ -140,35 +140,35 @@ async fn test_basic_position_retrieval(#[future] pool: PgPool) {
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_deleted_records_excluded(#[future] pool: PgPool) {
|
async fn test_deleted_records_excluded(#[future] pool: PgPool) {
|
||||||
let pool = pool.await;
|
let pool = pool.await;
|
||||||
|
|
||||||
// Take a lock to prevent concurrent test execution
|
// Take a lock to prevent concurrent test execution
|
||||||
let _guard = TEST_MUTEX.lock().await;
|
let _guard = TEST_MUTEX.lock().await;
|
||||||
|
|
||||||
// Use a unique prefix for test data
|
// Use a unique prefix for test data
|
||||||
let prefix = "PosDeletedTest";
|
let prefix = "PosDeletedTest";
|
||||||
|
|
||||||
// Clean up any existing test data
|
// Clean up any existing test data
|
||||||
cleanup_test_records(&pool, prefix).await;
|
cleanup_test_records(&pool, prefix).await;
|
||||||
|
|
||||||
// Create a mix of active and deleted records
|
// Create a mix of active and deleted records
|
||||||
let id1 = create_test_record(&pool, &format!("{}_1", prefix), false).await;
|
let id1 = create_test_record(&pool, &format!("{}_1", prefix), false).await;
|
||||||
let _id_deleted = create_test_record(&pool, &format!("{}_del", prefix), true).await;
|
let _id_deleted = create_test_record(&pool, &format!("{}_del", prefix), true).await;
|
||||||
let id2 = create_test_record(&pool, &format!("{}_2", prefix), false).await;
|
let id2 = create_test_record(&pool, &format!("{}_2", prefix), false).await;
|
||||||
|
|
||||||
// Find positions
|
// Find positions
|
||||||
let pos1 = find_position_of_record(&pool, id1).await.unwrap();
|
let pos1 = find_position_of_record(&pool, id1).await.unwrap();
|
||||||
let pos2 = find_position_of_record(&pool, id2).await.unwrap();
|
let pos2 = find_position_of_record(&pool, id2).await.unwrap();
|
||||||
|
|
||||||
// Verify positions are consecutive, which means the deleted record is excluded
|
// Verify positions are consecutive, which means the deleted record is excluded
|
||||||
assert_eq!(pos2, pos1 + 1);
|
assert_eq!(pos2, pos1 + 1);
|
||||||
|
|
||||||
// Retrieve by position and verify
|
// Retrieve by position and verify
|
||||||
let response1 = get_adresar_by_position(&pool, PositionRequest { position: pos1 }).await.unwrap();
|
let response1 = get_adresar_by_position(&pool, PositionRequest { position: pos1 }).await.unwrap();
|
||||||
assert_eq!(response1.id, id1);
|
assert_eq!(response1.id, id1);
|
||||||
|
|
||||||
let response2 = get_adresar_by_position(&pool, PositionRequest { position: pos2 }).await.unwrap();
|
let response2 = get_adresar_by_position(&pool, PositionRequest { position: pos2 }).await.unwrap();
|
||||||
assert_eq!(response2.id, id2);
|
assert_eq!(response2.id, id2);
|
||||||
|
|
||||||
// Clean up test data
|
// Clean up test data
|
||||||
cleanup_test_records(&pool, prefix).await;
|
cleanup_test_records(&pool, prefix).await;
|
||||||
}
|
}
|
||||||
@@ -177,44 +177,44 @@ async fn test_deleted_records_excluded(#[future] pool: PgPool) {
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_position_changes_after_deletion(#[future] pool: PgPool) {
|
async fn test_position_changes_after_deletion(#[future] pool: PgPool) {
|
||||||
let pool = pool.await;
|
let pool = pool.await;
|
||||||
|
|
||||||
// Take a lock to prevent concurrent test execution
|
// Take a lock to prevent concurrent test execution
|
||||||
let _guard = TEST_MUTEX.lock().await;
|
let _guard = TEST_MUTEX.lock().await;
|
||||||
|
|
||||||
// Use a unique prefix for test data
|
// Use a unique prefix for test data
|
||||||
let prefix = "PosChangeTest";
|
let prefix = "PosChangeTest";
|
||||||
|
|
||||||
// Clean up any existing test data
|
// Clean up any existing test data
|
||||||
cleanup_test_records(&pool, prefix).await;
|
cleanup_test_records(&pool, prefix).await;
|
||||||
|
|
||||||
// Create records
|
// Create records
|
||||||
let id1 = create_test_record(&pool, &format!("{}_1", prefix), false).await;
|
let id1 = create_test_record(&pool, &format!("{}_1", prefix), false).await;
|
||||||
let id2 = create_test_record(&pool, &format!("{}_2", prefix), false).await;
|
let id2 = create_test_record(&pool, &format!("{}_2", prefix), false).await;
|
||||||
let id3 = create_test_record(&pool, &format!("{}_3", prefix), false).await;
|
let id3 = create_test_record(&pool, &format!("{}_3", prefix), false).await;
|
||||||
|
|
||||||
// Find initial positions
|
// Find initial positions
|
||||||
let pos1 = find_position_of_record(&pool, id1).await.unwrap();
|
let _pos1 = find_position_of_record(&pool, id1).await.unwrap();
|
||||||
let pos2 = find_position_of_record(&pool, id2).await.unwrap();
|
let pos2 = find_position_of_record(&pool, id2).await.unwrap();
|
||||||
let pos3 = find_position_of_record(&pool, id3).await.unwrap();
|
let pos3 = find_position_of_record(&pool, id3).await.unwrap();
|
||||||
|
|
||||||
// Mark the first record as deleted
|
// Mark the first record as deleted
|
||||||
sqlx::query!("UPDATE adresar SET deleted = TRUE WHERE id = $1", id1)
|
sqlx::query!("UPDATE adresar SET deleted = TRUE WHERE id = $1", id1)
|
||||||
.execute(&pool)
|
.execute(&pool)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// Find new positions
|
// Find new positions
|
||||||
let pos2_after = find_position_of_record(&pool, id2).await.unwrap();
|
let pos2_after = find_position_of_record(&pool, id2).await.unwrap();
|
||||||
let pos3_after = find_position_of_record(&pool, id3).await.unwrap();
|
let pos3_after = find_position_of_record(&pool, id3).await.unwrap();
|
||||||
|
|
||||||
// Verify positions shifted
|
// Verify positions shifted
|
||||||
assert!(pos2_after < pos2);
|
assert!(pos2_after < pos2);
|
||||||
assert!(pos3_after < pos3);
|
assert!(pos3_after < pos3);
|
||||||
|
|
||||||
// Verify by retrieving records at new positions
|
// Verify by retrieving records at new positions
|
||||||
let response_at_first = get_adresar_by_position(&pool, PositionRequest { position: pos2_after }).await.unwrap();
|
let response_at_first = get_adresar_by_position(&pool, PositionRequest { position: pos2_after }).await.unwrap();
|
||||||
assert_eq!(response_at_first.id, id2);
|
assert_eq!(response_at_first.id, id2);
|
||||||
|
|
||||||
// Clean up test data
|
// Clean up test data
|
||||||
cleanup_test_records(&pool, prefix).await;
|
cleanup_test_records(&pool, prefix).await;
|
||||||
}
|
}
|
||||||
@@ -223,10 +223,10 @@ async fn test_position_changes_after_deletion(#[future] pool: PgPool) {
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_position_out_of_bounds(#[future] pool: PgPool) {
|
async fn test_position_out_of_bounds(#[future] pool: PgPool) {
|
||||||
let pool = pool.await;
|
let pool = pool.await;
|
||||||
|
|
||||||
// Take a lock to prevent concurrent test execution
|
// Take a lock to prevent concurrent test execution
|
||||||
let _guard = TEST_MUTEX.lock().await;
|
let _guard = TEST_MUTEX.lock().await;
|
||||||
|
|
||||||
// Get the total count of non-deleted records
|
// Get the total count of non-deleted records
|
||||||
let count = sqlx::query_scalar!(
|
let count = sqlx::query_scalar!(
|
||||||
"SELECT COUNT(*) FROM adresar WHERE deleted = FALSE"
|
"SELECT COUNT(*) FROM adresar WHERE deleted = FALSE"
|
||||||
@@ -235,11 +235,11 @@ async fn test_position_out_of_bounds(#[future] pool: PgPool) {
|
|||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.unwrap_or(0);
|
.unwrap_or(0);
|
||||||
|
|
||||||
// Request a position beyond the count
|
// Request a position beyond the count
|
||||||
let request = PositionRequest { position: count + 1 };
|
let request = PositionRequest { position: count + 1 };
|
||||||
let result = get_adresar_by_position(&pool, request).await;
|
let result = get_adresar_by_position(&pool, request).await;
|
||||||
|
|
||||||
// Verify it returns an error
|
// Verify it returns an error
|
||||||
assert!(result.is_err());
|
assert!(result.is_err());
|
||||||
assert_eq!(result.unwrap_err().code(), tonic::Code::NotFound);
|
assert_eq!(result.unwrap_err().code(), tonic::Code::NotFound);
|
||||||
@@ -249,11 +249,11 @@ async fn test_position_out_of_bounds(#[future] pool: PgPool) {
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_database_error(#[future] closed_pool: PgPool) {
|
async fn test_database_error(#[future] closed_pool: PgPool) {
|
||||||
let closed_pool = closed_pool.await;
|
let closed_pool = closed_pool.await;
|
||||||
|
|
||||||
// Attempt to query with a closed pool
|
// Attempt to query with a closed pool
|
||||||
let request = PositionRequest { position: 1 };
|
let request = PositionRequest { position: 1 };
|
||||||
let result = get_adresar_by_position(&closed_pool, request).await;
|
let result = get_adresar_by_position(&closed_pool, request).await;
|
||||||
|
|
||||||
// Verify it returns an internal error
|
// Verify it returns an internal error
|
||||||
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);
|
||||||
@@ -263,41 +263,106 @@ async fn test_database_error(#[future] closed_pool: PgPool) {
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_position_after_adding_record(#[future] pool: PgPool) {
|
async fn test_position_after_adding_record(#[future] pool: PgPool) {
|
||||||
let pool = pool.await;
|
let pool = pool.await;
|
||||||
|
|
||||||
// Take a lock to prevent concurrent test execution
|
// Take a lock to prevent concurrent test execution
|
||||||
let _guard = TEST_MUTEX.lock().await;
|
let _guard = TEST_MUTEX.lock().await;
|
||||||
|
|
||||||
// Use a unique prefix for test data
|
// Use a unique prefix for test data
|
||||||
let prefix = "PosAddTest";
|
let prefix = "PosAddTest";
|
||||||
|
|
||||||
// Clean up any existing test data
|
// Clean up any existing test data
|
||||||
cleanup_test_records(&pool, prefix).await;
|
cleanup_test_records(&pool, prefix).await;
|
||||||
|
|
||||||
// Create records
|
// Create records
|
||||||
let id1 = create_test_record(&pool, &format!("{}_1", prefix), false).await;
|
let id1 = create_test_record(&pool, &format!("{}_1", prefix), false).await;
|
||||||
let id2 = create_test_record(&pool, &format!("{}_2", prefix), false).await;
|
let id2 = create_test_record(&pool, &format!("{}_2", prefix), false).await;
|
||||||
|
|
||||||
// Find positions
|
// Find positions
|
||||||
let pos1 = find_position_of_record(&pool, id1).await.unwrap();
|
let pos1 = find_position_of_record(&pool, id1).await.unwrap();
|
||||||
let pos2 = find_position_of_record(&pool, id2).await.unwrap();
|
let pos2 = find_position_of_record(&pool, id2).await.unwrap();
|
||||||
|
|
||||||
// Add a new record
|
// Add a new record
|
||||||
let id3 = create_test_record(&pool, &format!("{}_3", prefix), false).await;
|
let id3 = create_test_record(&pool, &format!("{}_3", prefix), false).await;
|
||||||
|
|
||||||
// Find its position
|
// Find its position
|
||||||
let pos3 = find_position_of_record(&pool, id3).await.unwrap();
|
let pos3 = find_position_of_record(&pool, id3).await.unwrap();
|
||||||
|
|
||||||
// Verify retrieval by position
|
// Verify retrieval by position
|
||||||
let response3 = get_adresar_by_position(&pool, PositionRequest { position: pos3 }).await.unwrap();
|
let response3 = get_adresar_by_position(&pool, PositionRequest { position: pos3 }).await.unwrap();
|
||||||
assert_eq!(response3.id, id3);
|
assert_eq!(response3.id, id3);
|
||||||
|
|
||||||
// Verify original positions still work
|
// Verify original positions still work
|
||||||
let response1 = get_adresar_by_position(&pool, PositionRequest { position: pos1 }).await.unwrap();
|
let response1 = get_adresar_by_position(&pool, PositionRequest { position: pos1 }).await.unwrap();
|
||||||
assert_eq!(response1.id, id1);
|
assert_eq!(response1.id, id1);
|
||||||
|
|
||||||
let response2 = get_adresar_by_position(&pool, PositionRequest { position: pos2 }).await.unwrap();
|
let response2 = get_adresar_by_position(&pool, PositionRequest { position: pos2 }).await.unwrap();
|
||||||
assert_eq!(response2.id, id2);
|
assert_eq!(response2.id, id2);
|
||||||
|
|
||||||
|
// Clean up test data
|
||||||
|
cleanup_test_records(&pool, prefix).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test handler correctly excludes deleted records
|
||||||
|
#[rstest]
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_handler_excludes_deleted_records(#[future] pool: PgPool) {
|
||||||
|
let pool = pool.await;
|
||||||
|
|
||||||
|
// Take a lock to prevent concurrent test execution
|
||||||
|
let _guard = TEST_MUTEX.lock().await;
|
||||||
|
|
||||||
|
// Use a unique prefix for test data
|
||||||
|
let prefix = "CountTest";
|
||||||
|
|
||||||
|
// Clean up any existing test data
|
||||||
|
cleanup_test_records(&pool, prefix).await;
|
||||||
|
|
||||||
|
// Create active records
|
||||||
|
for i in 1..=3 {
|
||||||
|
create_test_record(&pool, &format!("{}_Active_{}", prefix, i), false).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create deleted records
|
||||||
|
for i in 1..=2 {
|
||||||
|
create_test_record(&pool, &format!("{}_Deleted_{}", prefix, i), true).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count our test records by deleted status
|
||||||
|
let active_test_count = sqlx::query_scalar!(
|
||||||
|
"SELECT COUNT(*) FROM adresar WHERE firma LIKE $1 AND deleted = FALSE",
|
||||||
|
format!("{}%", prefix)
|
||||||
|
)
|
||||||
|
.fetch_one(&pool)
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.unwrap_or(0);
|
||||||
|
|
||||||
|
let deleted_test_count = sqlx::query_scalar!(
|
||||||
|
"SELECT COUNT(*) FROM adresar WHERE firma LIKE $1 AND deleted = TRUE",
|
||||||
|
format!("{}%", prefix)
|
||||||
|
)
|
||||||
|
.fetch_one(&pool)
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.unwrap_or(0);
|
||||||
|
|
||||||
|
// Verify our test data was inserted correctly
|
||||||
|
assert_eq!(active_test_count, 3);
|
||||||
|
assert_eq!(deleted_test_count, 2);
|
||||||
|
|
||||||
|
// Get the total count of active records (including existing ones)
|
||||||
|
let total_active_count = 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, total_active_count);
|
||||||
|
|
||||||
// Clean up test data
|
// Clean up test data
|
||||||
cleanup_test_records(&pool, prefix).await;
|
cleanup_test_records(&pool, prefix).await;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user