removed unused tests
This commit is contained in:
@@ -1,161 +0,0 @@
|
||||
// tests/adresar/delete_adresar_test.rs
|
||||
use rstest::{fixture, rstest};
|
||||
use server::adresar::handlers::delete_adresar;
|
||||
use common::proto::multieko2::adresar::DeleteAdresarRequest;
|
||||
use crate::common::setup_test_db;
|
||||
use sqlx::PgPool;
|
||||
use tonic;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
// Reuse the mutex from get_adresar_by_position_test or create a new one
|
||||
lazy_static::lazy_static! {
|
||||
static ref TEST_MUTEX: Arc<Mutex<()>> = Arc::new(Mutex::new(()));
|
||||
}
|
||||
|
||||
// Fixtures
|
||||
#[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
|
||||
}
|
||||
|
||||
#[fixture]
|
||||
async fn existing_record(#[future] pool: PgPool) -> (PgPool, i64, String) {
|
||||
let pool = pool.await;
|
||||
// Use a unique prefix for test data
|
||||
let prefix = format!("DeleteTest_{}", chrono::Utc::now().timestamp_nanos_opt().unwrap_or_default());
|
||||
|
||||
let record = sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO adresar (firma, deleted)
|
||||
VALUES ($1, false)
|
||||
RETURNING id
|
||||
"#,
|
||||
format!("{}_Company", prefix)
|
||||
)
|
||||
.fetch_one(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
(pool, record.id, prefix)
|
||||
}
|
||||
|
||||
#[fixture]
|
||||
async fn existing_deleted_record(#[future] pool: PgPool) -> (PgPool, i64, String) {
|
||||
let pool = pool.await;
|
||||
// Use a unique prefix for test data
|
||||
let prefix = format!("DeletedTest_{}", chrono::Utc::now().timestamp_nanos_opt().unwrap_or_default());
|
||||
|
||||
let record = sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO adresar (firma, deleted)
|
||||
VALUES ($1, true)
|
||||
RETURNING id
|
||||
"#,
|
||||
format!("{}_Deleted", prefix)
|
||||
)
|
||||
.fetch_one(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
(pool, record.id, prefix)
|
||||
}
|
||||
|
||||
// Helper to check if the record is deleted
|
||||
async fn assert_record_deleted(pool: &PgPool, id: i64) {
|
||||
let db_record = sqlx::query!("SELECT deleted FROM adresar WHERE id = $1", id)
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert!(db_record.deleted);
|
||||
}
|
||||
|
||||
// Helper to clean up test records
|
||||
async fn cleanup_test_records(pool: &PgPool, prefix: &str) {
|
||||
if !prefix.is_empty() {
|
||||
sqlx::query!(
|
||||
"DELETE FROM adresar WHERE firma LIKE $1",
|
||||
format!("{}%", prefix)
|
||||
)
|
||||
.execute(pool)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
// Tests
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_delete_adresar_success(
|
||||
#[future] existing_record: (PgPool, i64, String),
|
||||
) {
|
||||
// Take a lock to prevent concurrent test execution
|
||||
let _guard = TEST_MUTEX.lock().await;
|
||||
|
||||
let (pool, id, prefix) = existing_record.await;
|
||||
let request = DeleteAdresarRequest { id };
|
||||
let response = delete_adresar(&pool, request).await.unwrap();
|
||||
|
||||
assert!(response.success);
|
||||
assert_record_deleted(&pool, id).await;
|
||||
|
||||
// Clean up
|
||||
cleanup_test_records(&pool, &prefix).await;
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_delete_adresar_nonexistent_id(
|
||||
#[future] pool: PgPool,
|
||||
) {
|
||||
// Take a lock to prevent concurrent test execution
|
||||
let _guard = TEST_MUTEX.lock().await;
|
||||
|
||||
let pool = pool.await;
|
||||
let request = DeleteAdresarRequest { id: 9999 };
|
||||
let response = delete_adresar(&pool, request).await.unwrap();
|
||||
|
||||
// Deleting a non-existent record should return success: false
|
||||
assert!(!response.success);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_delete_adresar_already_deleted(
|
||||
#[future] existing_deleted_record: (PgPool, i64, String),
|
||||
) {
|
||||
// Take a lock to prevent concurrent test execution
|
||||
let _guard = TEST_MUTEX.lock().await;
|
||||
|
||||
let (pool, id, prefix) = existing_deleted_record.await;
|
||||
let request = DeleteAdresarRequest { id };
|
||||
let response = delete_adresar(&pool, request).await.unwrap();
|
||||
|
||||
// Deleting an already deleted record should return success: false
|
||||
assert!(!response.success);
|
||||
|
||||
// Clean up
|
||||
cleanup_test_records(&pool, &prefix).await;
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_delete_adresar_database_error(
|
||||
#[future] closed_pool: PgPool,
|
||||
) {
|
||||
// No need for mutex here as we're not modifying the database
|
||||
let closed_pool = closed_pool.await;
|
||||
let request = DeleteAdresarRequest { id: 1 };
|
||||
let result = delete_adresar(&closed_pool, request).await;
|
||||
|
||||
assert!(result.is_err());
|
||||
assert_eq!(result.unwrap_err().code(), tonic::Code::Internal);
|
||||
}
|
||||
@@ -1,368 +0,0 @@
|
||||
// tests/adresar/get_adresar_by_position_test.rs
|
||||
use rstest::{fixture, rstest};
|
||||
use server::adresar::handlers::{get_adresar_by_position, get_adresar_count};
|
||||
use common::proto::multieko2::common::{PositionRequest, Empty};
|
||||
use crate::common::setup_test_db;
|
||||
use sqlx::PgPool;
|
||||
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]
|
||||
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 test record with specific data and delete status
|
||||
async fn create_test_record(pool: &PgPool, firma: &str, deleted: bool) -> i64 {
|
||||
sqlx::query_scalar!(
|
||||
"INSERT INTO adresar (firma, deleted) VALUES ($1, $2) RETURNING id",
|
||||
firma,
|
||||
deleted
|
||||
)
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
// Clean up test records after tests
|
||||
async fn cleanup_test_records(pool: &PgPool, prefix: &str) {
|
||||
sqlx::query!(
|
||||
"DELETE FROM adresar WHERE firma LIKE $1",
|
||||
format!("{}%", prefix)
|
||||
)
|
||||
.execute(pool)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
// Find the position of a record in the database
|
||||
async fn find_position_of_record(pool: &PgPool, id: i64) -> Option<i64> {
|
||||
// Get all non-deleted records ordered by ID
|
||||
let records = sqlx::query_scalar!(
|
||||
"SELECT id FROM adresar WHERE deleted = FALSE ORDER BY id ASC"
|
||||
)
|
||||
.fetch_all(pool)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Find the position of our record (1-based)
|
||||
for (index, record_id) in records.iter().enumerate() {
|
||||
if *record_id == id {
|
||||
return Some((index + 1) as i64);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
// Test position validation
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_position_zero(#[future] pool: PgPool) {
|
||||
let pool = pool.await;
|
||||
|
||||
// Request position 0 (invalid)
|
||||
let request = PositionRequest { position: 0 };
|
||||
let result = get_adresar_by_position(&pool, request).await;
|
||||
|
||||
// Verify it returns an error
|
||||
assert!(result.is_err());
|
||||
assert_eq!(result.unwrap_err().code(), tonic::Code::InvalidArgument);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_position_negative(#[future] pool: PgPool) {
|
||||
let pool = pool.await;
|
||||
|
||||
// Request negative position (invalid)
|
||||
let request = PositionRequest { position: -1 };
|
||||
let result = get_adresar_by_position(&pool, request).await;
|
||||
|
||||
// Verify it returns an error
|
||||
assert!(result.is_err());
|
||||
assert_eq!(result.unwrap_err().code(), tonic::Code::InvalidArgument);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_basic_position_retrieval(#[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 to prevent conflicts
|
||||
let prefix = "PosBasicTest";
|
||||
|
||||
// Clean up any existing test data
|
||||
cleanup_test_records(&pool, prefix).await;
|
||||
|
||||
// Create test records
|
||||
let id1 = create_test_record(&pool, &format!("{}_1", 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;
|
||||
|
||||
// Find the positions of these records in the database
|
||||
let pos1 = find_position_of_record(&pool, id1).await.unwrap();
|
||||
let pos2 = find_position_of_record(&pool, id2).await.unwrap();
|
||||
let pos3 = find_position_of_record(&pool, id3).await.unwrap();
|
||||
|
||||
// Test retrieving each position
|
||||
let response1 = get_adresar_by_position(&pool, PositionRequest { position: pos1 }).await.unwrap();
|
||||
assert_eq!(response1.id, id1);
|
||||
|
||||
let response2 = get_adresar_by_position(&pool, PositionRequest { position: pos2 }).await.unwrap();
|
||||
assert_eq!(response2.id, id2);
|
||||
|
||||
let response3 = get_adresar_by_position(&pool, PositionRequest { position: pos3 }).await.unwrap();
|
||||
assert_eq!(response3.id, id3);
|
||||
|
||||
// Clean up test data
|
||||
cleanup_test_records(&pool, prefix).await;
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_deleted_records_excluded(#[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 = "PosDeletedTest";
|
||||
|
||||
// Clean up any existing test data
|
||||
cleanup_test_records(&pool, prefix).await;
|
||||
|
||||
// Create a mix of active and deleted records
|
||||
let id1 = create_test_record(&pool, &format!("{}_1", prefix), false).await;
|
||||
let _id_deleted = create_test_record(&pool, &format!("{}_del", prefix), true).await;
|
||||
let id2 = create_test_record(&pool, &format!("{}_2", prefix), false).await;
|
||||
|
||||
// Find positions
|
||||
let pos1 = find_position_of_record(&pool, id1).await.unwrap();
|
||||
let pos2 = find_position_of_record(&pool, id2).await.unwrap();
|
||||
|
||||
// Verify positions are consecutive, which means the deleted record is excluded
|
||||
assert_eq!(pos2, pos1 + 1);
|
||||
|
||||
// Retrieve by position and verify
|
||||
let response1 = get_adresar_by_position(&pool, PositionRequest { position: pos1 }).await.unwrap();
|
||||
assert_eq!(response1.id, id1);
|
||||
|
||||
let response2 = get_adresar_by_position(&pool, PositionRequest { position: pos2 }).await.unwrap();
|
||||
assert_eq!(response2.id, id2);
|
||||
|
||||
// Clean up test data
|
||||
cleanup_test_records(&pool, prefix).await;
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_position_changes_after_deletion(#[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 = "PosChangeTest";
|
||||
|
||||
// Clean up any existing test data
|
||||
cleanup_test_records(&pool, prefix).await;
|
||||
|
||||
// Create records
|
||||
let id1 = create_test_record(&pool, &format!("{}_1", 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;
|
||||
|
||||
// Find initial positions
|
||||
let _pos1 = find_position_of_record(&pool, id1).await.unwrap();
|
||||
let pos2 = find_position_of_record(&pool, id2).await.unwrap();
|
||||
let pos3 = find_position_of_record(&pool, id3).await.unwrap();
|
||||
|
||||
// Mark the first record as deleted
|
||||
sqlx::query!("UPDATE adresar SET deleted = TRUE WHERE id = $1", id1)
|
||||
.execute(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Find new positions
|
||||
let pos2_after = find_position_of_record(&pool, id2).await.unwrap();
|
||||
let pos3_after = find_position_of_record(&pool, id3).await.unwrap();
|
||||
|
||||
// Verify positions shifted
|
||||
assert!(pos2_after < pos2);
|
||||
assert!(pos3_after < pos3);
|
||||
|
||||
// Verify by retrieving records at new positions
|
||||
let response_at_first = get_adresar_by_position(&pool, PositionRequest { position: pos2_after }).await.unwrap();
|
||||
assert_eq!(response_at_first.id, id2);
|
||||
|
||||
// Clean up test data
|
||||
cleanup_test_records(&pool, prefix).await;
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_position_out_of_bounds(#[future] pool: PgPool) {
|
||||
let pool = pool.await;
|
||||
|
||||
// Take a lock to prevent concurrent test execution
|
||||
let _guard = TEST_MUTEX.lock().await;
|
||||
|
||||
// Get the total count of non-deleted records
|
||||
let count = sqlx::query_scalar!(
|
||||
"SELECT COUNT(*) FROM adresar WHERE deleted = FALSE"
|
||||
)
|
||||
.fetch_one(&pool)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap_or(0);
|
||||
|
||||
// Request a position beyond the count
|
||||
let request = PositionRequest { position: count + 1 };
|
||||
let result = get_adresar_by_position(&pool, request).await;
|
||||
|
||||
// Verify it returns an error
|
||||
assert!(result.is_err());
|
||||
assert_eq!(result.unwrap_err().code(), tonic::Code::NotFound);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_database_error(#[future] closed_pool: PgPool) {
|
||||
let closed_pool = closed_pool.await;
|
||||
|
||||
// Attempt to query with a closed pool
|
||||
let request = PositionRequest { position: 1 };
|
||||
let result = get_adresar_by_position(&closed_pool, request).await;
|
||||
|
||||
// Verify it returns an internal error
|
||||
assert!(result.is_err());
|
||||
assert_eq!(result.unwrap_err().code(), tonic::Code::Internal);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_position_after_adding_record(#[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 = "PosAddTest";
|
||||
|
||||
// Clean up any existing test data
|
||||
cleanup_test_records(&pool, prefix).await;
|
||||
|
||||
// Create records
|
||||
let id1 = create_test_record(&pool, &format!("{}_1", prefix), false).await;
|
||||
let id2 = create_test_record(&pool, &format!("{}_2", prefix), false).await;
|
||||
|
||||
// Find positions
|
||||
let pos1 = find_position_of_record(&pool, id1).await.unwrap();
|
||||
let pos2 = find_position_of_record(&pool, id2).await.unwrap();
|
||||
|
||||
// Add a new record
|
||||
let id3 = create_test_record(&pool, &format!("{}_3", prefix), false).await;
|
||||
|
||||
// Find its position
|
||||
let pos3 = find_position_of_record(&pool, id3).await.unwrap();
|
||||
|
||||
// Verify retrieval by position
|
||||
let response3 = get_adresar_by_position(&pool, PositionRequest { position: pos3 }).await.unwrap();
|
||||
assert_eq!(response3.id, id3);
|
||||
|
||||
// Verify original positions still work
|
||||
let response1 = get_adresar_by_position(&pool, PositionRequest { position: pos1 }).await.unwrap();
|
||||
assert_eq!(response1.id, id1);
|
||||
|
||||
let response2 = get_adresar_by_position(&pool, PositionRequest { position: pos2 }).await.unwrap();
|
||||
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
|
||||
cleanup_test_records(&pool, prefix).await;
|
||||
}
|
||||
@@ -1,284 +0,0 @@
|
||||
// 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();
|
||||
}
|
||||
@@ -1,238 +0,0 @@
|
||||
// tests/adresar/get_adresar_test.rs
|
||||
use rstest::{fixture, rstest};
|
||||
use server::adresar::handlers::get_adresar;
|
||||
use common::proto::multieko2::adresar::{GetAdresarRequest, AdresarResponse};
|
||||
use crate::common::setup_test_db;
|
||||
use sqlx::PgPool;
|
||||
use tonic;
|
||||
|
||||
#[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
|
||||
}
|
||||
|
||||
#[fixture]
|
||||
async fn existing_record(#[future] pool: PgPool) -> (PgPool, i64) {
|
||||
let pool = pool.await;
|
||||
let record = sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO adresar (
|
||||
firma, kz, drc, ulica, psc, mesto, stat, banka, ucet,
|
||||
skladm, ico, kontakt, telefon, skladu, fax, deleted
|
||||
)
|
||||
VALUES (
|
||||
'Test Company', 'KZ', 'DRC', 'Street', '12345', 'City',
|
||||
'Country', 'Bank', 'Account', 'SkladM', 'ICO', 'Contact',
|
||||
'+421123456789', 'SkladU', 'Fax', false
|
||||
)
|
||||
RETURNING id
|
||||
"#
|
||||
)
|
||||
.fetch_one(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
(pool, record.id)
|
||||
}
|
||||
|
||||
#[fixture]
|
||||
async fn existing_deleted_record(#[future] pool: PgPool) -> (PgPool, i64) {
|
||||
let pool = pool.await;
|
||||
let record = sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO adresar (firma, deleted)
|
||||
VALUES ('Deleted Company', true)
|
||||
RETURNING id
|
||||
"#
|
||||
)
|
||||
.fetch_one(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
(pool, record.id)
|
||||
}
|
||||
|
||||
#[fixture]
|
||||
async fn existing_record_with_nulls(#[future] pool: PgPool) -> (PgPool, i64) {
|
||||
let pool = pool.await;
|
||||
let record = sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO adresar (firma)
|
||||
VALUES ('Null Fields Company')
|
||||
RETURNING id
|
||||
"#
|
||||
)
|
||||
.fetch_one(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
(pool, record.id)
|
||||
}
|
||||
|
||||
async fn assert_response_matches(pool: &PgPool, id: i64, response: &AdresarResponse) {
|
||||
let db_record = sqlx::query!("SELECT * FROM adresar WHERE id = $1", id)
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(db_record.firma, response.firma);
|
||||
assert_eq!(db_record.kz.unwrap_or_default(), response.kz);
|
||||
assert_eq!(db_record.drc.unwrap_or_default(), response.drc);
|
||||
assert_eq!(db_record.ulica.unwrap_or_default(), response.ulica);
|
||||
assert_eq!(db_record.psc.unwrap_or_default(), response.psc);
|
||||
assert_eq!(db_record.mesto.unwrap_or_default(), response.mesto);
|
||||
assert_eq!(db_record.stat.unwrap_or_default(), response.stat);
|
||||
assert_eq!(db_record.banka.unwrap_or_default(), response.banka);
|
||||
assert_eq!(db_record.ucet.unwrap_or_default(), response.ucet);
|
||||
assert_eq!(db_record.skladm.unwrap_or_default(), response.skladm);
|
||||
assert_eq!(db_record.ico.unwrap_or_default(), response.ico);
|
||||
assert_eq!(db_record.kontakt.unwrap_or_default(), response.kontakt);
|
||||
assert_eq!(db_record.telefon.unwrap_or_default(), response.telefon);
|
||||
assert_eq!(db_record.skladu.unwrap_or_default(), response.skladu);
|
||||
assert_eq!(db_record.fax.unwrap_or_default(), response.fax);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_get_adresar_success(
|
||||
#[future] existing_record: (PgPool, i64),
|
||||
) {
|
||||
let (pool, id) = existing_record.await;
|
||||
let request = GetAdresarRequest { id };
|
||||
let response = get_adresar(&pool, request).await.unwrap();
|
||||
|
||||
assert_eq!(response.id, id);
|
||||
assert_response_matches(&pool, id, &response).await;
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_get_optional_fields_null(
|
||||
#[future] existing_record_with_nulls: (PgPool, i64),
|
||||
) {
|
||||
let (pool, id) = existing_record_with_nulls.await;
|
||||
let request = GetAdresarRequest { id };
|
||||
let response = get_adresar(&pool, request).await.unwrap();
|
||||
|
||||
assert_eq!(response.kz, "");
|
||||
assert_eq!(response.drc, "");
|
||||
assert_eq!(response.ulica, "");
|
||||
assert_eq!(response.psc, "");
|
||||
assert_eq!(response.mesto, "");
|
||||
assert_eq!(response.stat, "");
|
||||
assert_eq!(response.banka, "");
|
||||
assert_eq!(response.ucet, "");
|
||||
assert_eq!(response.skladm, "");
|
||||
assert_eq!(response.ico, "");
|
||||
assert_eq!(response.kontakt, "");
|
||||
assert_eq!(response.telefon, "");
|
||||
assert_eq!(response.skladu, "");
|
||||
assert_eq!(response.fax, "");
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_get_nonexistent_id(
|
||||
#[future] pool: PgPool,
|
||||
) {
|
||||
let pool = pool.await;
|
||||
let request = GetAdresarRequest { id: 9999 };
|
||||
let result = get_adresar(&pool, request).await;
|
||||
|
||||
assert!(result.is_err());
|
||||
assert_eq!(result.unwrap_err().code(), tonic::Code::NotFound);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_get_deleted_record(
|
||||
#[future] existing_deleted_record: (PgPool, i64),
|
||||
) {
|
||||
let (pool, id) = existing_deleted_record.await;
|
||||
let request = GetAdresarRequest { id };
|
||||
let result = get_adresar(&pool, request).await;
|
||||
|
||||
assert!(result.is_err());
|
||||
assert_eq!(result.unwrap_err().code(), tonic::Code::NotFound);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_database_error(
|
||||
#[future] closed_pool: PgPool,
|
||||
) {
|
||||
let closed_pool = closed_pool.await;
|
||||
let request = GetAdresarRequest { id: 1 };
|
||||
let result = get_adresar(&closed_pool, request).await;
|
||||
|
||||
assert!(result.is_err());
|
||||
assert_eq!(result.unwrap_err().code(), tonic::Code::Internal);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_get_special_characters(
|
||||
#[future] pool: PgPool,
|
||||
) {
|
||||
let pool = pool.await;
|
||||
let firma = "Náměstí ČR";
|
||||
let telefon = "+420 123-456.789";
|
||||
let ulica = "Křižíkova 123";
|
||||
|
||||
let record = sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO adresar (firma, telefon, ulica)
|
||||
VALUES ($1, $2, $3)
|
||||
RETURNING id
|
||||
"#,
|
||||
firma,
|
||||
telefon,
|
||||
ulica
|
||||
)
|
||||
.fetch_one(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let request = GetAdresarRequest { id: record.id };
|
||||
let response = get_adresar(&pool, request).await.unwrap();
|
||||
|
||||
assert_eq!(response.firma, firma);
|
||||
assert_eq!(response.telefon, telefon);
|
||||
assert_eq!(response.ulica, ulica);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_get_max_length_fields(
|
||||
#[future] pool: PgPool,
|
||||
) {
|
||||
let pool = pool.await;
|
||||
let firma = "a".repeat(255);
|
||||
let telefon = "1".repeat(20);
|
||||
|
||||
let record = sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO adresar (firma, telefon)
|
||||
VALUES ($1, $2)
|
||||
RETURNING id
|
||||
"#,
|
||||
firma,
|
||||
telefon
|
||||
)
|
||||
.fetch_one(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let request = GetAdresarRequest { id: record.id };
|
||||
let response = get_adresar(&pool, request).await.unwrap();
|
||||
|
||||
assert_eq!(response.firma.len(), 255);
|
||||
assert_eq!(response.telefon.len(), 20);
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
// server/tests/adresar/mod.rs
|
||||
|
||||
pub mod post_adresar_test;
|
||||
pub mod put_adresar_test;
|
||||
pub mod get_adresar_test;
|
||||
pub mod get_adresar_count_test;
|
||||
pub mod get_adresar_by_position_test;
|
||||
pub mod delete_adresar_test;
|
||||
@@ -1,222 +0,0 @@
|
||||
// tests/adresar/post_adresar_test.rs
|
||||
use rstest::{fixture, rstest};
|
||||
use server::adresar::handlers::post_adresar;
|
||||
use common::proto::multieko2::adresar::PostAdresarRequest;
|
||||
use crate::common::setup_test_db;
|
||||
use sqlx::PgPool;
|
||||
use tonic;
|
||||
|
||||
// Fixtures
|
||||
#[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
|
||||
}
|
||||
|
||||
#[fixture]
|
||||
fn valid_request() -> PostAdresarRequest {
|
||||
PostAdresarRequest {
|
||||
firma: "Test Company".into(),
|
||||
kz: "KZ123".into(),
|
||||
drc: "DRC456".into(),
|
||||
ulica: "Test Street".into(),
|
||||
psc: "12345".into(),
|
||||
mesto: "Test City".into(),
|
||||
stat: "Test Country".into(),
|
||||
banka: "Test Bank".into(),
|
||||
ucet: "123456789".into(),
|
||||
skladm: "Warehouse M".into(),
|
||||
ico: "12345678".into(),
|
||||
kontakt: "John Doe".into(),
|
||||
telefon: "+421123456789".into(),
|
||||
skladu: "Warehouse U".into(),
|
||||
fax: "+421123456700".into(),
|
||||
}
|
||||
}
|
||||
|
||||
#[fixture]
|
||||
fn minimal_request() -> PostAdresarRequest {
|
||||
PostAdresarRequest {
|
||||
firma: "Required Only".into(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to check database state
|
||||
async fn assert_response_matches(pool: &PgPool, response: &common::proto::multieko2::adresar::AdresarResponse) {
|
||||
let db_record = sqlx::query!("SELECT * FROM adresar WHERE id = $1", response.id)
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(db_record.firma, response.firma);
|
||||
assert_eq!(db_record.telefon.as_deref(), Some(response.telefon.as_str()));
|
||||
// Add assertions for other fields...
|
||||
assert!(!db_record.deleted);
|
||||
assert!(db_record.created_at.is_some());
|
||||
}
|
||||
|
||||
// Tests
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_create_adresar_success(#[future] pool: PgPool, valid_request: PostAdresarRequest) {
|
||||
let pool = pool.await;
|
||||
let response = post_adresar(&pool, valid_request).await.unwrap();
|
||||
|
||||
assert!(response.id > 0);
|
||||
assert_eq!(response.firma, "Test Company");
|
||||
assert_response_matches(&pool, &response).await;
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_create_adresar_whitespace_trimming(
|
||||
#[future] pool: PgPool,
|
||||
valid_request: PostAdresarRequest,
|
||||
) {
|
||||
let pool = pool.await;
|
||||
let mut request = valid_request;
|
||||
request.firma = " Test Company ".into();
|
||||
request.telefon = " +421123456789 ".into();
|
||||
request.ulica = " Test Street ".into();
|
||||
|
||||
let response = post_adresar(&pool, request).await.unwrap();
|
||||
assert_eq!(response.firma, "Test Company");
|
||||
assert_eq!(response.telefon, "+421123456789");
|
||||
assert_eq!(response.ulica, "Test Street");
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_create_adresar_empty_optional_fields(
|
||||
#[future] pool: PgPool,
|
||||
valid_request: PostAdresarRequest,
|
||||
) {
|
||||
let pool = pool.await;
|
||||
let mut request = valid_request;
|
||||
request.telefon = " ".into();
|
||||
|
||||
let response = post_adresar(&pool, request).await.unwrap();
|
||||
let db_telefon = sqlx::query_scalar!("SELECT telefon FROM adresar WHERE id = $1", response.id)
|
||||
.fetch_one(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert!(db_telefon.is_none());
|
||||
assert_eq!(response.telefon, "");
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_create_adresar_invalid_firma(
|
||||
#[future] pool: PgPool,
|
||||
valid_request: PostAdresarRequest,
|
||||
) {
|
||||
let pool = pool.await;
|
||||
let mut request = valid_request;
|
||||
request.firma = " ".into();
|
||||
let result = post_adresar(&pool, request).await;
|
||||
|
||||
assert!(result.is_err());
|
||||
assert_eq!(result.unwrap_err().code(), tonic::Code::InvalidArgument);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_create_adresar_minimal_valid_request(
|
||||
#[future] pool: PgPool,
|
||||
minimal_request: PostAdresarRequest,
|
||||
) {
|
||||
let pool = pool.await;
|
||||
let response = post_adresar(&pool, minimal_request).await.unwrap();
|
||||
|
||||
assert!(response.id > 0);
|
||||
assert_eq!(response.firma, "Required Only");
|
||||
assert!(response.kz.is_empty());
|
||||
assert!(response.drc.is_empty());
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_create_adresar_empty_firma(
|
||||
#[future] pool: PgPool,
|
||||
minimal_request: PostAdresarRequest,
|
||||
) {
|
||||
let pool = pool.await;
|
||||
let mut request = minimal_request;
|
||||
request.firma = "".into();
|
||||
let result = post_adresar(&pool, request).await;
|
||||
|
||||
assert!(result.is_err());
|
||||
assert_eq!(result.unwrap_err().code(), tonic::Code::InvalidArgument);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_create_adresar_database_error(
|
||||
#[future] closed_pool: PgPool,
|
||||
minimal_request: PostAdresarRequest,
|
||||
) {
|
||||
let closed_pool = closed_pool.await;
|
||||
let result = post_adresar(&closed_pool, minimal_request).await;
|
||||
|
||||
assert!(result.is_err());
|
||||
assert_eq!(result.unwrap_err().code(), tonic::Code::Internal);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_create_adresar_field_length_limits(
|
||||
#[future] pool: PgPool,
|
||||
valid_request: PostAdresarRequest,
|
||||
) {
|
||||
let pool = pool.await;
|
||||
let mut request = valid_request;
|
||||
request.firma = "a".repeat(255);
|
||||
request.telefon = "1".repeat(20);
|
||||
|
||||
let response = post_adresar(&pool, request).await.unwrap();
|
||||
assert_eq!(response.firma.len(), 255);
|
||||
assert_eq!(response.telefon.len(), 20);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_create_adresar_special_characters(
|
||||
#[future] pool: PgPool,
|
||||
valid_request: PostAdresarRequest,
|
||||
) {
|
||||
let pool = pool.await;
|
||||
let mut request = valid_request;
|
||||
request.telefon = "+420 123-456.789".into();
|
||||
request.ulica = "Náměstí 28. října".into();
|
||||
|
||||
let response = post_adresar(&pool, request.clone()).await.unwrap();
|
||||
assert_eq!(response.telefon, request.telefon);
|
||||
assert_eq!(response.ulica, request.ulica);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_create_adresar_optional_fields_null_vs_empty(
|
||||
#[future] pool: PgPool,
|
||||
valid_request: PostAdresarRequest,
|
||||
) {
|
||||
let pool = pool.await;
|
||||
let mut request = valid_request;
|
||||
request.telefon = String::new();
|
||||
let response = post_adresar(&pool, request).await.unwrap();
|
||||
|
||||
let db_telefon = sqlx::query_scalar!("SELECT telefon FROM adresar WHERE id = $1", response.id)
|
||||
.fetch_one(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert!(db_telefon.is_none());
|
||||
}
|
||||
@@ -1,266 +0,0 @@
|
||||
// tests/adresar/put_adresar_test.rs
|
||||
use rstest::{fixture, rstest};
|
||||
use server::adresar::handlers::put_adresar;
|
||||
use common::proto::multieko2::adresar::PutAdresarRequest;
|
||||
use crate::common::setup_test_db;
|
||||
use sqlx::PgPool;
|
||||
use tonic;
|
||||
|
||||
// Fixtures
|
||||
#[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
|
||||
}
|
||||
|
||||
#[fixture]
|
||||
async fn existing_record(#[future] pool: PgPool) -> (PgPool, i64) {
|
||||
let pool = pool.await;
|
||||
|
||||
// Create a test record in the database
|
||||
let record = sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO adresar (
|
||||
firma, kz, drc, ulica, psc, mesto, stat, banka, ucet,
|
||||
skladm, ico, kontakt, telefon, skladu, fax, deleted
|
||||
)
|
||||
VALUES (
|
||||
'Original Company', 'Original KZ', 'Original DRC', 'Original Street',
|
||||
'12345', 'Original City', 'Original Country', 'Original Bank',
|
||||
'Original Account', 'Original SkladM', 'Original ICO',
|
||||
'Original Contact', '+421123456789', 'Original SkladU', 'Original Fax',
|
||||
false
|
||||
)
|
||||
RETURNING id
|
||||
"#
|
||||
)
|
||||
.fetch_one(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
(pool, record.id)
|
||||
}
|
||||
|
||||
#[fixture]
|
||||
fn valid_request_template() -> PutAdresarRequest {
|
||||
PutAdresarRequest {
|
||||
id: 0, // This will be replaced in each test
|
||||
firma: "Updated Company".into(),
|
||||
kz: "Updated KZ".into(),
|
||||
drc: "Updated DRC".into(),
|
||||
ulica: "Updated Street".into(),
|
||||
psc: "67890".into(),
|
||||
mesto: "Updated City".into(),
|
||||
stat: "Updated Country".into(),
|
||||
banka: "Updated Bank".into(),
|
||||
ucet: "987654321".into(),
|
||||
skladm: "Updated SkladM".into(),
|
||||
ico: "87654321".into(),
|
||||
kontakt: "Jane Doe".into(),
|
||||
telefon: "+421987654321".into(),
|
||||
skladu: "Updated SkladU".into(),
|
||||
fax: "+421987654300".into(),
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to check database state
|
||||
async fn assert_response_matches(pool: &PgPool, id: i64, response: &common::proto::multieko2::adresar::AdresarResponse) {
|
||||
let db_record = sqlx::query!("SELECT * FROM adresar WHERE id = $1", id)
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(db_record.firma, response.firma);
|
||||
assert_eq!(db_record.kz.unwrap_or_default(), response.kz);
|
||||
assert_eq!(db_record.drc.unwrap_or_default(), response.drc);
|
||||
assert_eq!(db_record.ulica.unwrap_or_default(), response.ulica);
|
||||
assert_eq!(db_record.psc.unwrap_or_default(), response.psc);
|
||||
assert_eq!(db_record.mesto.unwrap_or_default(), response.mesto);
|
||||
assert_eq!(db_record.stat.unwrap_or_default(), response.stat);
|
||||
assert_eq!(db_record.banka.unwrap_or_default(), response.banka);
|
||||
assert_eq!(db_record.ucet.unwrap_or_default(), response.ucet);
|
||||
assert_eq!(db_record.skladm.unwrap_or_default(), response.skladm);
|
||||
assert_eq!(db_record.ico.unwrap_or_default(), response.ico);
|
||||
assert_eq!(db_record.kontakt.unwrap_or_default(), response.kontakt);
|
||||
assert_eq!(db_record.telefon.unwrap_or_default(), response.telefon);
|
||||
assert_eq!(db_record.skladu.unwrap_or_default(), response.skladu);
|
||||
assert_eq!(db_record.fax.unwrap_or_default(), response.fax);
|
||||
assert!(!db_record.deleted, "Record should not be deleted");
|
||||
}
|
||||
|
||||
// Tests
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_update_adresar_success(#[future] existing_record: (PgPool, i64), valid_request_template: PutAdresarRequest) {
|
||||
let (pool, id) = existing_record.await;
|
||||
|
||||
let mut request = valid_request_template;
|
||||
request.id = id;
|
||||
|
||||
let response = put_adresar(&pool, request).await.unwrap();
|
||||
|
||||
assert_eq!(response.id, id);
|
||||
assert_response_matches(&pool, id, &response).await;
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_update_whitespace_fields(#[future] existing_record: (PgPool, i64), valid_request_template: PutAdresarRequest) {
|
||||
let (pool, id) = existing_record.await;
|
||||
|
||||
let mut request = valid_request_template;
|
||||
request.id = id;
|
||||
request.firma = " Updated Company ".into();
|
||||
request.telefon = " +421987654321 ".into();
|
||||
|
||||
let response = put_adresar(&pool, request).await.unwrap();
|
||||
|
||||
// Verify trimmed values in response
|
||||
assert_eq!(response.firma, "Updated Company");
|
||||
assert_eq!(response.telefon, "+421987654321");
|
||||
|
||||
// Verify raw values in database
|
||||
let db_record = sqlx::query!("SELECT firma, telefon FROM adresar WHERE id = $1", id)
|
||||
.fetch_one(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(db_record.firma, "Updated Company"); // Trimmed
|
||||
assert_eq!(db_record.telefon.unwrap(), "+421987654321"); // Trimmed
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_update_empty_required_field(#[future] existing_record: (PgPool, i64), valid_request_template: PutAdresarRequest) {
|
||||
let (pool, id) = existing_record.await;
|
||||
|
||||
let mut request = valid_request_template;
|
||||
request.id = id;
|
||||
request.firma = "".into();
|
||||
|
||||
let result = put_adresar(&pool, request).await;
|
||||
assert!(result.is_err());
|
||||
assert_eq!(result.unwrap_err().code(), tonic::Code::InvalidArgument);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_update_nonexistent_id(#[future] pool: PgPool) {
|
||||
let pool = pool.await;
|
||||
|
||||
let request = PutAdresarRequest {
|
||||
id: 9999, // Non-existent ID
|
||||
firma: "Updated Company".into(),
|
||||
kz: "Updated KZ".into(),
|
||||
drc: "Updated DRC".into(),
|
||||
ulica: "Updated Street".into(),
|
||||
psc: "67890".into(),
|
||||
mesto: "Updated City".into(),
|
||||
stat: "Updated Country".into(),
|
||||
banka: "Updated Bank".into(),
|
||||
ucet: "987654321".into(),
|
||||
skladm: "Updated SkladM".into(),
|
||||
ico: "87654321".into(),
|
||||
kontakt: "Jane Doe".into(),
|
||||
telefon: "+421987654321".into(),
|
||||
skladu: "Updated SkladU".into(),
|
||||
fax: "+421987654300".into(),
|
||||
};
|
||||
|
||||
let result = put_adresar(&pool, request).await;
|
||||
assert!(result.is_err());
|
||||
assert_eq!(result.unwrap_err().code(), tonic::Code::Internal);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_update_deleted_record(#[future] existing_record: (PgPool, i64), valid_request_template: PutAdresarRequest) {
|
||||
let (pool, id) = existing_record.await;
|
||||
|
||||
// Mark the record as deleted
|
||||
sqlx::query!("UPDATE adresar SET deleted = true WHERE id = $1", id)
|
||||
.execute(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let mut request = valid_request_template;
|
||||
request.id = id;
|
||||
|
||||
let result = put_adresar(&pool, request).await;
|
||||
assert!(result.is_err());
|
||||
assert_eq!(result.unwrap_err().code(), tonic::Code::Internal);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_clear_optional_fields(#[future] existing_record: (PgPool, i64), valid_request_template: PutAdresarRequest) {
|
||||
let (pool, id) = existing_record.await;
|
||||
|
||||
let mut request = valid_request_template;
|
||||
request.id = id;
|
||||
request.telefon = String::new();
|
||||
request.ulica = String::new();
|
||||
|
||||
let response = put_adresar(&pool, request).await.unwrap();
|
||||
|
||||
// Check response contains empty strings
|
||||
assert!(response.telefon.is_empty());
|
||||
assert!(response.ulica.is_empty());
|
||||
|
||||
// Check database contains NULL
|
||||
let db_record = sqlx::query!("SELECT telefon, ulica FROM adresar WHERE id = $1", id)
|
||||
.fetch_one(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert!(db_record.telefon.is_none());
|
||||
assert!(db_record.ulica.is_none());
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_max_length_fields(#[future] existing_record: (PgPool, i64), valid_request_template: PutAdresarRequest) {
|
||||
let (pool, id) = existing_record.await;
|
||||
|
||||
let mut request = valid_request_template;
|
||||
request.id = id;
|
||||
request.firma = "a".repeat(255);
|
||||
request.telefon = "1".repeat(20);
|
||||
|
||||
let _response = put_adresar(&pool, request).await.unwrap();
|
||||
|
||||
let db_record = sqlx::query!("SELECT firma, telefon FROM adresar WHERE id = $1", id)
|
||||
.fetch_one(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(db_record.firma.len(), 255);
|
||||
assert_eq!(db_record.telefon.unwrap().len(), 20);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_special_characters(#[future] existing_record: (PgPool, i64), valid_request_template: PutAdresarRequest) {
|
||||
let (pool, id) = existing_record.await;
|
||||
|
||||
let mut request = valid_request_template;
|
||||
request.id = id;
|
||||
request.ulica = "Náměstí 28. října".into();
|
||||
request.telefon = "+420 123-456.789".into();
|
||||
|
||||
let _response = put_adresar(&pool, request).await.unwrap();
|
||||
|
||||
let db_record = sqlx::query!("SELECT ulica, telefon FROM adresar WHERE id = $1", id)
|
||||
.fetch_one(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(db_record.ulica.unwrap(), "Náměstí 28. října");
|
||||
assert_eq!(db_record.telefon.unwrap(), "+420 123-456.789");
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
// tests/mod.rs
|
||||
// pub mod adresar;
|
||||
pub mod tables_data;
|
||||
pub mod common;
|
||||
// pub mod table_definition;
|
||||
|
||||
Reference in New Issue
Block a user