5 more tests to go
This commit is contained in:
@@ -8,6 +8,6 @@ reset_db:
|
|||||||
|
|
||||||
run_tests:
|
run_tests:
|
||||||
@echo "Running tests..."
|
@echo "Running tests..."
|
||||||
@cargo test
|
@cargo test --test mod -- --test-threads=1
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ async fn execute_table_definition(
|
|||||||
return Err(Status::invalid_argument("Invalid column name"));
|
return Err(Status::invalid_argument("Invalid column name"));
|
||||||
}
|
}
|
||||||
if col_name.ends_with("_id") || col_name == "id" || col_name == "deleted" || col_name == "created_at" {
|
if col_name.ends_with("_id") || col_name == "id" || col_name == "deleted" || col_name == "created_at" {
|
||||||
return Err(Status::invalid_argument("Invalid column name"));
|
return Err(Status::invalid_argument("Column name cannot be 'id', 'deleted', 'created_at' or end with '_id'"));
|
||||||
}
|
}
|
||||||
let sql_type = map_field_type(&col_def.field_type)?;
|
let sql_type = map_field_type(&col_def.field_type)?;
|
||||||
columns.push(format!("\"{}\" {}", col_name, sql_type));
|
columns.push(format!("\"{}\" {}", col_name, sql_type));
|
||||||
|
|||||||
@@ -24,13 +24,17 @@ async fn get_root_connection() -> PgConnection {
|
|||||||
/// This is the key to test isolation.
|
/// This is the key to test isolation.
|
||||||
pub async fn setup_isolated_db() -> PgPool {
|
pub async fn setup_isolated_db() -> PgPool {
|
||||||
let mut root_conn = get_root_connection().await;
|
let mut root_conn = get_root_connection().await;
|
||||||
|
|
||||||
|
// Make schema names more unique - include timestamp + random
|
||||||
let schema_name = format!(
|
let schema_name = format!(
|
||||||
"test_{}",
|
"test_{}_{}",
|
||||||
|
std::time::SystemTime::now()
|
||||||
|
.duration_since(std::time::UNIX_EPOCH)
|
||||||
|
.unwrap()
|
||||||
|
.as_nanos(),
|
||||||
rand::thread_rng()
|
rand::thread_rng()
|
||||||
// --- CHANGE 2: Pass a reference to Alphanumeric directly ---
|
|
||||||
.sample_iter(&Alphanumeric)
|
.sample_iter(&Alphanumeric)
|
||||||
.take(12)
|
.take(8)
|
||||||
.map(char::from)
|
.map(char::from)
|
||||||
.collect::<String>()
|
.collect::<String>()
|
||||||
.to_lowercase()
|
.to_lowercase()
|
||||||
|
|||||||
@@ -157,8 +157,9 @@ async fn test_name_sanitization(#[future] pool: PgPool) {
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_create_minimal_table(#[future] pool: PgPool) {
|
async fn test_create_minimal_table(#[future] pool: PgPool) {
|
||||||
let pool = pool.await;
|
let pool = pool.await;
|
||||||
|
let profile_name = "test_minimal";
|
||||||
let req = PostTableDefinitionRequest {
|
let req = PostTableDefinitionRequest {
|
||||||
profile_name: "default".into(),
|
profile_name: profile_name.into(),
|
||||||
table_name: "minimal".into(),
|
table_name: "minimal".into(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
@@ -168,7 +169,7 @@ async fn test_create_minimal_table(#[future] pool: PgPool) {
|
|||||||
assert!(resp.sql.contains("created_at TIMESTAMPTZ"));
|
assert!(resp.sql.contains("created_at TIMESTAMPTZ"));
|
||||||
assert_table_structure_is_correct(
|
assert_table_structure_is_correct(
|
||||||
&pool,
|
&pool,
|
||||||
"default", // FIXED: Added schema parameter
|
profile_name,
|
||||||
"minimal",
|
"minimal",
|
||||||
&[
|
&[
|
||||||
("id", "bigint"),
|
("id", "bigint"),
|
||||||
|
|||||||
@@ -162,26 +162,24 @@ async fn test_fail_gracefully_if_schema_is_missing(#[future] pool: PgPool) {
|
|||||||
#[rstest]
|
#[rstest]
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_column_name_with_id_suffix_is_rejected(#[future] pool: PgPool) {
|
async fn test_column_name_with_id_suffix_is_rejected(#[future] pool: PgPool) {
|
||||||
// Test that column names ending with '_id' are properly rejected during input validation
|
|
||||||
let pool = pool.await;
|
let pool = pool.await;
|
||||||
|
|
||||||
// Test 1: Column ending with '_id' should be rejected
|
// Test 1: Column ending with '_id' should be rejected
|
||||||
let request = PostTableDefinitionRequest {
|
let request = PostTableDefinitionRequest {
|
||||||
profile_name: "default".into(),
|
profile_name: "default".into(),
|
||||||
table_name: "orders".into(), // Valid table name
|
table_name: "orders".into(),
|
||||||
columns: vec![ColumnDefinition {
|
columns: vec![ColumnDefinition {
|
||||||
name: "legacy_order_id".into(), // This should be rejected
|
name: "legacy_order_id".into(),
|
||||||
field_type: "integer".into(),
|
field_type: "integer".into(),
|
||||||
}],
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Act & Assert - should fail validation
|
|
||||||
let result = post_table_definition(&pool, request).await;
|
let result = post_table_definition(&pool, request).await;
|
||||||
assert!(result.is_err(), "Column names ending with '_id' should be rejected");
|
assert!(result.is_err(), "Column names ending with '_id' should be rejected");
|
||||||
if let Err(status) = result {
|
if let Err(status) = result {
|
||||||
assert_eq!(status.code(), tonic::Code::InvalidArgument);
|
assert_eq!(status.code(), tonic::Code::InvalidArgument);
|
||||||
assert!(status.message().contains("Invalid column name"));
|
// Update this line to match the actual error message:
|
||||||
|
assert!(status.message().contains("Column name cannot be") && status.message().contains("end with '_id'"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test 2: Column named exactly 'id' should be rejected
|
// Test 2: Column named exactly 'id' should be rejected
|
||||||
@@ -189,14 +187,17 @@ async fn test_column_name_with_id_suffix_is_rejected(#[future] pool: PgPool) {
|
|||||||
profile_name: "default".into(),
|
profile_name: "default".into(),
|
||||||
table_name: "orders".into(),
|
table_name: "orders".into(),
|
||||||
columns: vec![ColumnDefinition {
|
columns: vec![ColumnDefinition {
|
||||||
name: "id".into(), // This should be rejected
|
name: "id".into(),
|
||||||
field_type: "integer".into(),
|
field_type: "integer".into(),
|
||||||
}],
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let result2 = post_table_definition(&pool, request2).await;
|
let result2 = post_table_definition(&pool, request2).await;
|
||||||
assert!(result2.is_err(), "Column named 'id' should be rejected");
|
assert!(result2.is_err(), "Column named 'id' should be rejected");
|
||||||
|
if let Err(status) = result2 {
|
||||||
|
assert_eq!(status.code(), tonic::Code::InvalidArgument);
|
||||||
|
assert!(status.message().contains("Column name cannot be") && status.message().contains("'id'"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
|
|||||||
Reference in New Issue
Block a user