From cdf49612c40f36877c3c92e32445d30cc8da7e22 Mon Sep 17 00:00:00 2001 From: filipriec Date: Tue, 4 Mar 2025 19:16:54 +0100 Subject: [PATCH] delete test implemented --- .../handlers/delete_table_data_test.rs | 222 ++++++++++++++++++ server/tests/tables_data/handlers/mod.rs | 1 + 2 files changed, 223 insertions(+) create mode 100644 server/tests/tables_data/handlers/delete_table_data_test.rs diff --git a/server/tests/tables_data/handlers/delete_table_data_test.rs b/server/tests/tables_data/handlers/delete_table_data_test.rs new file mode 100644 index 0000000..fd06f54 --- /dev/null +++ b/server/tests/tables_data/handlers/delete_table_data_test.rs @@ -0,0 +1,222 @@ +// tests/tables_data/delete_table_data_test.rs +use rstest::{fixture, rstest}; +use server::tables_data::handlers::delete_table_data; +use common::proto::multieko2::tables_data::DeleteTableDataRequest; +use crate::common::setup_test_db; +use sqlx::{PgPool, Row}; +use tonic; +use std::sync::Arc; +use tokio::sync::Mutex; +use chrono::Utc; + +lazy_static::lazy_static! { + static ref TEST_MUTEX: Arc> = 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 +} + +#[fixture] +async fn existing_profile(#[future] pool: PgPool) -> (PgPool, String, i64) { + let pool = pool.await; + let profile_name = format!("TestProfile_{}", Utc::now().timestamp_nanos_opt().unwrap_or_default()); + let profile = sqlx::query!( + "INSERT INTO profiles (name) VALUES ($1) RETURNING id", + profile_name + ) + .fetch_one(&pool) + .await + .unwrap(); + (pool, profile_name, profile.id) +} + +#[fixture] +async fn existing_table( + #[future] existing_profile: (PgPool, String, i64), +) -> (PgPool, String, i64, String) { + let (pool, profile_name, profile_id) = existing_profile.await; + let table_name = format!("test_table_{}", Utc::now().timestamp_nanos_opt().unwrap_or_default()); + + sqlx::query!( + "INSERT INTO table_definitions (profile_id, table_name) VALUES ($1, $2)", + profile_id, + table_name + ) + .execute(&pool) + .await + .unwrap(); + + let create_table = format!( + r#" + CREATE TABLE "{}" ( + id SERIAL PRIMARY KEY, + deleted BOOLEAN NOT NULL DEFAULT false + ) + "#, + table_name + ); + + sqlx::query(&create_table) + .execute(&pool) + .await + .unwrap(); + + (pool, profile_name, profile_id, table_name) +} + +#[fixture] +async fn existing_record( + #[future] existing_table: (PgPool, String, i64, String), +) -> (PgPool, String, String, i64) { + let (pool, profile_name, _profile_id, table_name) = existing_table.await; + let query = format!( + "INSERT INTO \"{}\" (deleted) VALUES (false) RETURNING id", + table_name + ); + + let row = sqlx::query(&query) + .fetch_one(&pool) + .await + .unwrap(); + + let id: i64 = row.get("id"); + (pool, profile_name, table_name, id) +} + +#[fixture] +async fn existing_deleted_record( + #[future] existing_table: (PgPool, String, i64, String), +) -> (PgPool, String, String, i64) { + let (pool, profile_name, _profile_id, table_name) = existing_table.await; + let query = format!( + "INSERT INTO \"{}\" (deleted) VALUES (true) RETURNING id", + table_name + ); + + let row = sqlx::query(&query) + .fetch_one(&pool) + .await + .unwrap(); + + let id: i64 = row.get("id"); + (pool, profile_name, table_name, id) +} + +#[rstest] +#[tokio::test] +async fn test_delete_table_data_success( + #[future] existing_record: (PgPool, String, String, i64), +) { + let _guard = TEST_MUTEX.lock().await; + let (pool, profile_name, table_name, record_id) = existing_record.await; + let request = DeleteTableDataRequest { + profile_name: profile_name.clone(), + table_name: table_name.clone(), + record_id, + }; + let response = delete_table_data(&pool, request).await.unwrap(); + assert!(response.success); + + let query = format!( + "SELECT deleted FROM \"{}\" WHERE id = $1", + table_name + ); + let row = sqlx::query(&query) + .bind(record_id) + .fetch_one(&pool) + .await + .unwrap(); + + assert!(row.get::("deleted")); +} + +#[rstest] +#[tokio::test] +async fn test_delete_table_data_profile_not_found( + #[future] pool: PgPool, +) { + let _guard = TEST_MUTEX.lock().await; + let pool = pool.await; + let request = DeleteTableDataRequest { + profile_name: "NonExistentProfile".to_string(), + table_name: "test_table".to_string(), + record_id: 1, + }; + let result = delete_table_data(&pool, request).await; + assert!(result.is_err()); + assert_eq!(result.unwrap_err().code(), tonic::Code::NotFound); +} + +#[rstest] +#[tokio::test] +async fn test_delete_table_data_table_not_found( + #[future] existing_profile: (PgPool, String, i64), +) { + let _guard = TEST_MUTEX.lock().await; + let (pool, profile_name, _) = existing_profile.await; + let request = DeleteTableDataRequest { + profile_name, + table_name: "non_existent_table".to_string(), + record_id: 1, + }; + let result = delete_table_data(&pool, request).await; + assert!(result.is_err()); + assert_eq!(result.unwrap_err().code(), tonic::Code::NotFound); +} + +#[rstest] +#[tokio::test] +async fn test_delete_table_data_record_not_found( + #[future] existing_table: (PgPool, String, i64, String), +) { + let _guard = TEST_MUTEX.lock().await; + let (pool, profile_name, _, table_name) = existing_table.await; + let request = DeleteTableDataRequest { + profile_name, + table_name, + record_id: 9999, + }; + let response = delete_table_data(&pool, request).await.unwrap(); + assert!(!response.success); +} + +#[rstest] +#[tokio::test] +async fn test_delete_table_data_already_deleted( + #[future] existing_deleted_record: (PgPool, String, String, i64), +) { + let _guard = TEST_MUTEX.lock().await; + let (pool, profile_name, table_name, record_id) = existing_deleted_record.await; + let request = DeleteTableDataRequest { + profile_name, + table_name, + record_id, + }; + let response = delete_table_data(&pool, request).await.unwrap(); + assert!(!response.success); +} + +#[rstest] +#[tokio::test] +async fn test_delete_table_data_database_error( + #[future] closed_pool: PgPool, +) { + let closed_pool = closed_pool.await; + let request = DeleteTableDataRequest { + profile_name: "test".to_string(), + table_name: "test".to_string(), + record_id: 1, + }; + let result = delete_table_data(&closed_pool, request).await; + assert!(result.is_err()); + assert_eq!(result.unwrap_err().code(), tonic::Code::Internal); +} diff --git a/server/tests/tables_data/handlers/mod.rs b/server/tests/tables_data/handlers/mod.rs index d9f93f4..36c17f4 100644 --- a/server/tests/tables_data/handlers/mod.rs +++ b/server/tests/tables_data/handlers/mod.rs @@ -1,4 +1,5 @@ // tests/tables_data/mod.rs pub mod post_table_data_test; pub mod put_table_data_test; +pub mod delete_table_data_test;