placing them properly
This commit is contained in:
318
server/tests/tables_data/get/get_table_data_by_position_test.rs
Normal file
318
server/tests/tables_data/get/get_table_data_by_position_test.rs
Normal file
@@ -0,0 +1,318 @@
|
||||
// tests/tables_data/handlers/get_table_data_by_position_test.rs
|
||||
use rstest::{fixture, rstest};
|
||||
use tonic;
|
||||
use sqlx::PgPool;
|
||||
use common::proto::multieko2::tables_data::GetTableDataByPositionRequest;
|
||||
use common::proto::multieko2::table_definition::{PostTableDefinitionRequest, ColumnDefinition};
|
||||
use server::table_definition::handlers::post_table_definition;
|
||||
use server::tables_data::handlers::get_table_data_by_position;
|
||||
use crate::common::setup_test_db;
|
||||
use chrono::Utc;
|
||||
use serde_json::json;
|
||||
|
||||
#[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
|
||||
}
|
||||
|
||||
async fn setup_test_environment(pool: &PgPool) -> (String, String, i64) {
|
||||
// Create unique profile and table names
|
||||
let profile_name = format!("test_profile_{}", Utc::now().timestamp_nanos_opt().unwrap_or(0));
|
||||
let table_name = format!("test_table_{}", Utc::now().timestamp_nanos_opt().unwrap_or(0));
|
||||
|
||||
// Use the table definition handler to create the table properly
|
||||
let request = PostTableDefinitionRequest {
|
||||
profile_name: profile_name.clone(),
|
||||
table_name: table_name.clone(),
|
||||
columns: vec![
|
||||
ColumnDefinition {
|
||||
name: "firma".to_string(),
|
||||
field_type: "text".to_string(),
|
||||
}
|
||||
],
|
||||
indexes: vec![],
|
||||
links: vec![],
|
||||
};
|
||||
|
||||
post_table_definition(pool, request).await.unwrap();
|
||||
|
||||
// Get the schema_id for cleanup
|
||||
let schema_id = sqlx::query_scalar!(
|
||||
"SELECT id FROM schemas WHERE name = $1",
|
||||
profile_name
|
||||
)
|
||||
.fetch_one(pool)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
(profile_name, table_name, schema_id)
|
||||
}
|
||||
|
||||
async fn cleanup_test_environment(pool: &PgPool, schema_id: i64, profile_name: &str) {
|
||||
let mut tx = pool.begin().await.unwrap();
|
||||
|
||||
// Cleanup order matters!
|
||||
sqlx::query(&format!(r#"DROP SCHEMA IF EXISTS "{}" CASCADE"#, profile_name))
|
||||
.execute(&mut *tx)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
sqlx::query!("DELETE FROM table_definitions WHERE schema_id = $1", schema_id)
|
||||
.execute(&mut *tx)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
sqlx::query!("DELETE FROM schemas WHERE id = $1", schema_id)
|
||||
.execute(&mut *tx)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
tx.commit().await.unwrap();
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_retrieves_correct_record_by_position(
|
||||
#[future] pool: PgPool,
|
||||
) {
|
||||
let pool = pool.await;
|
||||
let (profile_name, table_name, schema_id) = setup_test_environment(&pool).await;
|
||||
|
||||
// Insert test data
|
||||
let mut tx = pool.begin().await.unwrap();
|
||||
let id1: i64 = sqlx::query_scalar(&format!(
|
||||
r#"INSERT INTO "{}"."{}" (firma) VALUES ('Test 1') RETURNING id"#,
|
||||
profile_name,
|
||||
table_name
|
||||
))
|
||||
.fetch_one(&mut *tx)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let id2: i64 = sqlx::query_scalar(&format!(
|
||||
r#"INSERT INTO "{}"."{}" (firma) VALUES ('Test 2') RETURNING id"#,
|
||||
profile_name,
|
||||
table_name
|
||||
))
|
||||
.fetch_one(&mut *tx)
|
||||
.await
|
||||
.unwrap();
|
||||
tx.commit().await.unwrap();
|
||||
|
||||
// Test position 1
|
||||
let request = GetTableDataByPositionRequest {
|
||||
profile_name: profile_name.clone(),
|
||||
table_name: table_name.clone(),
|
||||
position: 1,
|
||||
};
|
||||
let response = get_table_data_by_position(&pool, request).await.unwrap();
|
||||
assert_eq!(response.data["id"], id1.to_string());
|
||||
|
||||
// Test position 2
|
||||
let request = GetTableDataByPositionRequest {
|
||||
profile_name: profile_name.clone(),
|
||||
table_name: table_name.clone(),
|
||||
position: 2,
|
||||
};
|
||||
let response = get_table_data_by_position(&pool, request).await.unwrap();
|
||||
assert_eq!(response.data["id"], id2.to_string());
|
||||
|
||||
cleanup_test_environment(&pool, schema_id, &profile_name).await;
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_excludes_deleted_records(
|
||||
#[future] pool: PgPool,
|
||||
) {
|
||||
let pool = pool.await;
|
||||
let (profile_name, table_name, schema_id) = setup_test_environment(&pool).await;
|
||||
|
||||
// Insert test data
|
||||
let mut tx = pool.begin().await.unwrap();
|
||||
let id1: i64 = sqlx::query_scalar(&format!(
|
||||
r#"INSERT INTO "{}"."{}" (firma) VALUES ('Test 1') RETURNING id"#,
|
||||
profile_name,
|
||||
table_name
|
||||
))
|
||||
.fetch_one(&mut *tx)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Insert and delete a record
|
||||
let deleted_id: i64 = sqlx::query_scalar(&format!(
|
||||
r#"INSERT INTO "{}"."{}" (firma) VALUES ('Deleted') RETURNING id"#,
|
||||
profile_name,
|
||||
table_name
|
||||
))
|
||||
.fetch_one(&mut *tx)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let id2: i64 = sqlx::query_scalar(&format!(
|
||||
r#"INSERT INTO "{}"."{}" (firma) VALUES ('Test 2') RETURNING id"#,
|
||||
profile_name,
|
||||
table_name
|
||||
))
|
||||
.fetch_one(&mut *tx)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
sqlx::query(&format!(
|
||||
r#"UPDATE "{}"."{}" SET deleted = true WHERE id = $1"#,
|
||||
profile_name,
|
||||
table_name
|
||||
))
|
||||
.bind(deleted_id)
|
||||
.execute(&mut *tx)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
tx.commit().await.unwrap();
|
||||
|
||||
// Test positions
|
||||
let request = GetTableDataByPositionRequest {
|
||||
profile_name: profile_name.clone(),
|
||||
table_name: table_name.clone(),
|
||||
position: 1,
|
||||
};
|
||||
let response = get_table_data_by_position(&pool, request).await.unwrap();
|
||||
assert_eq!(response.data["id"], id1.to_string());
|
||||
|
||||
let request = GetTableDataByPositionRequest {
|
||||
profile_name: profile_name.clone(),
|
||||
table_name: table_name.clone(),
|
||||
position: 2,
|
||||
};
|
||||
let response = get_table_data_by_position(&pool, request).await.unwrap();
|
||||
assert_eq!(response.data["id"], id2.to_string());
|
||||
|
||||
cleanup_test_environment(&pool, schema_id, &profile_name).await;
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_invalid_position(
|
||||
#[future] pool: PgPool,
|
||||
) {
|
||||
let pool = pool.await;
|
||||
let (profile_name, table_name, schema_id) = setup_test_environment(&pool).await;
|
||||
|
||||
// Test position 0
|
||||
let request = GetTableDataByPositionRequest {
|
||||
profile_name: profile_name.clone(),
|
||||
table_name: table_name.clone(),
|
||||
position: 0,
|
||||
};
|
||||
let result = get_table_data_by_position(&pool, request).await;
|
||||
assert!(result.is_err());
|
||||
assert_eq!(result.unwrap_err().code(), tonic::Code::InvalidArgument);
|
||||
|
||||
// Test negative position
|
||||
let request = GetTableDataByPositionRequest {
|
||||
profile_name: profile_name.clone(),
|
||||
table_name: table_name.clone(),
|
||||
position: -1,
|
||||
};
|
||||
let result = get_table_data_by_position(&pool, request).await;
|
||||
assert!(result.is_err());
|
||||
assert_eq!(result.unwrap_err().code(), tonic::Code::InvalidArgument);
|
||||
|
||||
cleanup_test_environment(&pool, schema_id, &profile_name).await;
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_position_out_of_bounds(
|
||||
#[future] pool: PgPool,
|
||||
) {
|
||||
let pool = pool.await;
|
||||
let (profile_name, table_name, schema_id) = setup_test_environment(&pool).await;
|
||||
|
||||
// Insert one record
|
||||
let mut tx = pool.begin().await.unwrap();
|
||||
sqlx::query(&format!(
|
||||
r#"INSERT INTO "{}"."{}" (firma) VALUES ('Test 1')"#,
|
||||
profile_name,
|
||||
table_name
|
||||
))
|
||||
.execute(&mut *tx)
|
||||
.await
|
||||
.unwrap();
|
||||
tx.commit().await.unwrap();
|
||||
|
||||
// Test position beyond count
|
||||
let request = GetTableDataByPositionRequest {
|
||||
profile_name: profile_name.clone(),
|
||||
table_name: table_name.clone(),
|
||||
position: 2,
|
||||
};
|
||||
let result = get_table_data_by_position(&pool, request).await;
|
||||
assert!(result.is_err());
|
||||
assert_eq!(result.unwrap_err().code(), tonic::Code::NotFound);
|
||||
|
||||
cleanup_test_environment(&pool, schema_id, &profile_name).await;
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_table_not_in_profile(
|
||||
#[future] pool: PgPool,
|
||||
) {
|
||||
let pool = pool.await;
|
||||
let (profile_name, _, schema_id) = setup_test_environment(&pool).await;
|
||||
|
||||
// Test with non-existent table
|
||||
let request = GetTableDataByPositionRequest {
|
||||
profile_name,
|
||||
table_name: "non_existent_table".to_string(),
|
||||
position: 1,
|
||||
};
|
||||
let result = get_table_data_by_position(&pool, request).await;
|
||||
assert!(result.is_err());
|
||||
assert_eq!(result.unwrap_err().code(), tonic::Code::NotFound);
|
||||
|
||||
cleanup_test_environment(&pool, schema_id, "dummy_table").await;
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_profile_not_found(
|
||||
#[future] pool: PgPool,
|
||||
) {
|
||||
let pool = pool.await;
|
||||
|
||||
let request = GetTableDataByPositionRequest {
|
||||
profile_name: "nonexistent_profile".to_string(),
|
||||
table_name: "adresar".to_string(),
|
||||
position: 1,
|
||||
};
|
||||
let result = get_table_data_by_position(&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 = GetTableDataByPositionRequest {
|
||||
profile_name: "test".to_string(),
|
||||
table_name: "test".to_string(),
|
||||
position: 1,
|
||||
};
|
||||
let result = get_table_data_by_position(&closed_pool, request).await;
|
||||
|
||||
assert!(result.is_err());
|
||||
assert_eq!(result.unwrap_err().code(), tonic::Code::Internal);
|
||||
}
|
||||
@@ -2,3 +2,4 @@
|
||||
|
||||
pub mod get_table_data_count_test;
|
||||
pub mod get_table_data_test;
|
||||
pub mod get_table_data_by_position_test;
|
||||
|
||||
Reference in New Issue
Block a user