get test not working now
This commit is contained in:
414
server/tests/tables_data/handlers/get_table_data_test.rs
Normal file
414
server/tests/tables_data/handlers/get_table_data_test.rs
Normal file
@@ -0,0 +1,414 @@
|
|||||||
|
// tests/tables_data/handlers/get_table_data_test.rs
|
||||||
|
use rstest::{fixture, rstest};
|
||||||
|
use server::tables_data::handlers::get_table_data;
|
||||||
|
use common::proto::multieko2::tables_data::{GetTableDataRequest, GetTableDataResponse};
|
||||||
|
use crate::common::setup_test_db;
|
||||||
|
use sqlx::{PgPool, Row};
|
||||||
|
use tonic;
|
||||||
|
use chrono::Utc;
|
||||||
|
use serde_json::json;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use tokio::sync::Mutex;
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
#[fixture]
|
||||||
|
async fn existing_profile(#[future] pool: PgPool) -> (PgPool, String, i64) {
|
||||||
|
let _guard = TEST_MUTEX.lock().await;
|
||||||
|
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, String) {
|
||||||
|
let _guard = TEST_MUTEX.lock().await;
|
||||||
|
let (pool, profile_name, profile_id) = existing_profile.await;
|
||||||
|
let table_name = format!("test_table_{}", Utc::now().timestamp_nanos_opt().unwrap_or_default());
|
||||||
|
|
||||||
|
// Define columns for the table
|
||||||
|
let columns = json!([
|
||||||
|
"\"name\" VARCHAR(255)",
|
||||||
|
"\"age\" INTEGER",
|
||||||
|
"\"email\" VARCHAR(100)",
|
||||||
|
"\"is_active\" BOOLEAN"
|
||||||
|
]);
|
||||||
|
|
||||||
|
sqlx::query!(
|
||||||
|
"INSERT INTO table_definitions (profile_id, table_name, columns) VALUES ($1, $2, $3)",
|
||||||
|
profile_id,
|
||||||
|
table_name,
|
||||||
|
columns
|
||||||
|
)
|
||||||
|
.execute(&pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// Create actual table
|
||||||
|
let create_table = format!(
|
||||||
|
r#"
|
||||||
|
CREATE TABLE "{}" (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
deleted BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
firma TEXT NOT NULL,
|
||||||
|
name VARCHAR(255),
|
||||||
|
age INTEGER,
|
||||||
|
email VARCHAR(100),
|
||||||
|
is_active BOOLEAN
|
||||||
|
)
|
||||||
|
"#,
|
||||||
|
table_name
|
||||||
|
);
|
||||||
|
|
||||||
|
sqlx::query(&create_table)
|
||||||
|
.execute(&pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
(pool, profile_name, table_name)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[fixture]
|
||||||
|
async fn existing_record(
|
||||||
|
#[future] existing_table: (PgPool, String, String),
|
||||||
|
) -> (PgPool, String, String, i64) {
|
||||||
|
let _guard = TEST_MUTEX.lock().await;
|
||||||
|
let (pool, profile_name, table_name) = existing_table.await;
|
||||||
|
|
||||||
|
let query = format!(
|
||||||
|
r#"INSERT INTO "{}" (firma, name, age, email, is_active)
|
||||||
|
VALUES ($1, $2, $3, $4, $5)
|
||||||
|
RETURNING id"#,
|
||||||
|
table_name
|
||||||
|
);
|
||||||
|
|
||||||
|
let record = sqlx::query(&query)
|
||||||
|
.bind("Test Company")
|
||||||
|
.bind("John Doe")
|
||||||
|
.bind(30)
|
||||||
|
.bind("john@example.com")
|
||||||
|
.bind(true)
|
||||||
|
.fetch_one(&pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let id: i64 = record.get("id");
|
||||||
|
(pool, profile_name, table_name, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[fixture]
|
||||||
|
async fn existing_deleted_record(
|
||||||
|
#[future] existing_table: (PgPool, String, String),
|
||||||
|
) -> (PgPool, String, String, i64) {
|
||||||
|
let _guard = TEST_MUTEX.lock().await;
|
||||||
|
let (pool, profile_name, table_name) = existing_table.await;
|
||||||
|
|
||||||
|
let query = format!(
|
||||||
|
r#"INSERT INTO "{}" (firma, deleted)
|
||||||
|
VALUES ($1, true)
|
||||||
|
RETURNING id"#,
|
||||||
|
table_name
|
||||||
|
);
|
||||||
|
|
||||||
|
let record = sqlx::query(&query)
|
||||||
|
.bind("Deleted Company")
|
||||||
|
.fetch_one(&pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let id: i64 = record.get("id");
|
||||||
|
(pool, profile_name, table_name, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[fixture]
|
||||||
|
async fn existing_record_with_nulls(
|
||||||
|
#[future] existing_table: (PgPool, String, String),
|
||||||
|
) -> (PgPool, String, String, i64) {
|
||||||
|
let _guard = TEST_MUTEX.lock().await;
|
||||||
|
let (pool, profile_name, table_name) = existing_table.await;
|
||||||
|
|
||||||
|
let query = format!(
|
||||||
|
r#"INSERT INTO "{}" (firma)
|
||||||
|
VALUES ($1)
|
||||||
|
RETURNING id"#,
|
||||||
|
table_name
|
||||||
|
);
|
||||||
|
|
||||||
|
let record = sqlx::query(&query)
|
||||||
|
.bind("Null Fields Company")
|
||||||
|
.fetch_one(&pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let id: i64 = record.get("id");
|
||||||
|
(pool, profile_name, table_name, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn cleanup_test_data(pool: &PgPool, table_name: &str) {
|
||||||
|
sqlx::query(&format!(r#"DROP TABLE IF EXISTS "{}" CASCADE"#, table_name))
|
||||||
|
.execute(pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
sqlx::query!("DELETE FROM table_definitions WHERE table_name = $1", table_name)
|
||||||
|
.execute(pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rstest]
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_get_table_data_success(
|
||||||
|
#[future] existing_record: (PgPool, String, String, i64),
|
||||||
|
) {
|
||||||
|
let (pool, profile_name, table_name, id) = existing_record.await;
|
||||||
|
let request = GetTableDataRequest {
|
||||||
|
profile_name: profile_name.clone(),
|
||||||
|
table_name: table_name.clone(),
|
||||||
|
id,
|
||||||
|
};
|
||||||
|
|
||||||
|
let response = get_table_data(&pool, request).await.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(response.data["id"], id.to_string());
|
||||||
|
assert_eq!(response.data["firma"], "Test Company");
|
||||||
|
assert_eq!(response.data["name"], "John Doe");
|
||||||
|
assert_eq!(response.data["age"], "30");
|
||||||
|
assert_eq!(response.data["email"], "john@example.com");
|
||||||
|
assert_eq!(response.data["is_active"], "true");
|
||||||
|
assert_eq!(response.data["deleted"], "false");
|
||||||
|
|
||||||
|
cleanup_test_data(&pool, &table_name).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rstest]
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_get_optional_fields_null(
|
||||||
|
#[future] existing_record_with_nulls: (PgPool, String, String, i64),
|
||||||
|
) {
|
||||||
|
let (pool, profile_name, table_name, id) = existing_record_with_nulls.await;
|
||||||
|
let request = GetTableDataRequest {
|
||||||
|
profile_name: profile_name.clone(),
|
||||||
|
table_name: table_name.clone(),
|
||||||
|
id,
|
||||||
|
};
|
||||||
|
|
||||||
|
let response = get_table_data(&pool, request).await.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(response.data["name"], "");
|
||||||
|
assert_eq!(response.data["age"], "");
|
||||||
|
assert_eq!(response.data["email"], "");
|
||||||
|
assert_eq!(response.data["is_active"], "");
|
||||||
|
assert_eq!(response.data["deleted"], "false");
|
||||||
|
|
||||||
|
cleanup_test_data(&pool, &table_name).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rstest]
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_get_nonexistent_id(
|
||||||
|
#[future] existing_table: (PgPool, String, String),
|
||||||
|
) {
|
||||||
|
let (pool, profile_name, table_name) = existing_table.await;
|
||||||
|
let request = GetTableDataRequest {
|
||||||
|
profile_name: profile_name.clone(),
|
||||||
|
table_name: table_name.clone(),
|
||||||
|
id: 9999,
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = get_table_data(&pool, request).await;
|
||||||
|
assert!(result.is_err());
|
||||||
|
assert_eq!(result.unwrap_err().code(), tonic::Code::NotFound);
|
||||||
|
|
||||||
|
cleanup_test_data(&pool, &table_name).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rstest]
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_get_deleted_record(
|
||||||
|
#[future] existing_deleted_record: (PgPool, String, String, i64),
|
||||||
|
) {
|
||||||
|
let (pool, profile_name, table_name, id) = existing_deleted_record.await;
|
||||||
|
let request = GetTableDataRequest {
|
||||||
|
profile_name: profile_name.clone(),
|
||||||
|
table_name: table_name.clone(),
|
||||||
|
id,
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = get_table_data(&pool, request).await;
|
||||||
|
assert!(result.is_err());
|
||||||
|
assert_eq!(result.unwrap_err().code(), tonic::Code::NotFound);
|
||||||
|
|
||||||
|
cleanup_test_data(&pool, &table_name).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rstest]
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_get_database_error(
|
||||||
|
#[future] closed_pool: PgPool,
|
||||||
|
) {
|
||||||
|
let closed_pool = closed_pool.await;
|
||||||
|
let request = GetTableDataRequest {
|
||||||
|
profile_name: "test".into(),
|
||||||
|
table_name: "test".into(),
|
||||||
|
id: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = get_table_data(&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] existing_table: (PgPool, String, String),
|
||||||
|
) {
|
||||||
|
let (pool, profile_name, table_name) = existing_table.await;
|
||||||
|
|
||||||
|
let query = format!(
|
||||||
|
r#"INSERT INTO "{}" (firma, name, email)
|
||||||
|
VALUES ($1, $2, $3)
|
||||||
|
RETURNING id"#,
|
||||||
|
table_name
|
||||||
|
);
|
||||||
|
|
||||||
|
let record = sqlx::query(&query)
|
||||||
|
.bind("Test Company")
|
||||||
|
.bind("Náměstí ČR")
|
||||||
|
.bind("čšěř@example.com")
|
||||||
|
.fetch_one(&pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let id: i64 = record.get("id");
|
||||||
|
|
||||||
|
let request = GetTableDataRequest {
|
||||||
|
profile_name: profile_name.clone(),
|
||||||
|
table_name: table_name.clone(),
|
||||||
|
id,
|
||||||
|
};
|
||||||
|
|
||||||
|
let response = get_table_data(&pool, request).await.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(response.data["name"], "Náměstí ČR");
|
||||||
|
assert_eq!(response.data["email"], "čšěř@example.com");
|
||||||
|
|
||||||
|
cleanup_test_data(&pool, &table_name).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rstest]
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_get_max_length_fields(
|
||||||
|
#[future] existing_table: (PgPool, String, String),
|
||||||
|
) {
|
||||||
|
let (pool, profile_name, table_name) = existing_table.await;
|
||||||
|
|
||||||
|
let long_name = "a".repeat(255);
|
||||||
|
let query = format!(
|
||||||
|
r#"INSERT INTO "{}" (firma, name)
|
||||||
|
VALUES ($1, $2)
|
||||||
|
RETURNING id"#,
|
||||||
|
table_name
|
||||||
|
);
|
||||||
|
|
||||||
|
let record = sqlx::query(&query)
|
||||||
|
.bind("Test Company")
|
||||||
|
.bind(&long_name)
|
||||||
|
.fetch_one(&pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let id: i64 = record.get("id");
|
||||||
|
|
||||||
|
let request = GetTableDataRequest {
|
||||||
|
profile_name: profile_name.clone(),
|
||||||
|
table_name: table_name.clone(),
|
||||||
|
id,
|
||||||
|
};
|
||||||
|
|
||||||
|
let response = get_table_data(&pool, request).await.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(response.data["name"], long_name);
|
||||||
|
assert_eq!(response.data["name"].len(), 255);
|
||||||
|
|
||||||
|
cleanup_test_data(&pool, &table_name).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rstest]
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_get_invalid_profile(
|
||||||
|
#[future] pool: PgPool,
|
||||||
|
) {
|
||||||
|
let pool = pool.await;
|
||||||
|
let request = GetTableDataRequest {
|
||||||
|
profile_name: "non_existent_profile".into(),
|
||||||
|
table_name: "test_table".into(),
|
||||||
|
id: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = get_table_data(&pool, request).await;
|
||||||
|
assert!(result.is_err());
|
||||||
|
assert_eq!(result.unwrap_err().code(), tonic::Code::NotFound);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rstest]
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_get_invalid_table(
|
||||||
|
#[future] existing_profile: (PgPool, String, i64),
|
||||||
|
) {
|
||||||
|
let (pool, profile_name, _) = existing_profile.await;
|
||||||
|
let request = GetTableDataRequest {
|
||||||
|
profile_name,
|
||||||
|
table_name: "non_existent_table".into(),
|
||||||
|
id: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = get_table_data(&pool, request).await;
|
||||||
|
assert!(result.is_err());
|
||||||
|
assert_eq!(result.unwrap_err().code(), tonic::Code::NotFound);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rstest]
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_get_invalid_column(
|
||||||
|
#[future] existing_record: (PgPool, String, String, i64),
|
||||||
|
) {
|
||||||
|
let (pool, profile_name, table_name, id) = existing_record.await;
|
||||||
|
|
||||||
|
// Try to request a column that doesn't exist in the table definition
|
||||||
|
let mut request = GetTableDataRequest {
|
||||||
|
profile_name: profile_name.clone(),
|
||||||
|
table_name: table_name.clone(),
|
||||||
|
id,
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = get_table_data(&pool, request).await;
|
||||||
|
assert!(result.is_ok()); // Should still succeed as we're not filtering columns
|
||||||
|
|
||||||
|
cleanup_test_data(&pool, &table_name).await;
|
||||||
|
}
|
||||||
@@ -2,4 +2,5 @@
|
|||||||
pub mod post_table_data_test;
|
pub mod post_table_data_test;
|
||||||
pub mod put_table_data_test;
|
pub mod put_table_data_test;
|
||||||
pub mod delete_table_data_test;
|
pub mod delete_table_data_test;
|
||||||
|
pub mod get_table_data_test;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user