robust testing of the table definitions
This commit is contained in:
@@ -340,3 +340,108 @@ async fn test_database_error_on_closed_pool(
|
||||
// Assert
|
||||
assert_eq!(result.unwrap_err().code(), Code::Internal);
|
||||
}
|
||||
|
||||
// Tests that minimal, uppercase and whitespace‐padded decimal specs
|
||||
// are accepted and correctly mapped to NUMERIC(p, s).
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_valid_decimal_variants(#[future] pool: PgPool) {
|
||||
let pool = pool.await;
|
||||
let cases = vec![
|
||||
("decimal(1,1)", "NUMERIC(1, 1)"),
|
||||
("decimal(1,0)", "NUMERIC(1, 0)"),
|
||||
("DECIMAL(5,2)", "NUMERIC(5, 2)"),
|
||||
("decimal( 5 , 2 )", "NUMERIC(5, 2)"),
|
||||
];
|
||||
for (i, (typ, expect)) in cases.into_iter().enumerate() {
|
||||
let request = PostTableDefinitionRequest {
|
||||
profile_name: "default".into(),
|
||||
table_name: format!("dec_valid_{}", i),
|
||||
columns: vec![ColumnDefinition {
|
||||
name: "amount".into(),
|
||||
field_type: typ.into(),
|
||||
}],
|
||||
..Default::default()
|
||||
};
|
||||
let resp = post_table_definition(&pool, request).await.unwrap();
|
||||
assert!(resp.success, "{}", typ);
|
||||
assert!(
|
||||
resp.sql.contains(expect),
|
||||
"expected `{}` to map to {}, got `{}`",
|
||||
typ,
|
||||
expect,
|
||||
resp.sql
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that malformed decimal inputs are rejected with InvalidArgument.
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_fail_on_malformed_decimal_inputs(#[future] pool: PgPool) {
|
||||
let pool = pool.await;
|
||||
let bad = vec!["decimal", "decimal()", "decimal(5,)", "decimal(,2)", "decimal(, )"];
|
||||
for (i, typ) in bad.into_iter().enumerate() {
|
||||
let request = PostTableDefinitionRequest {
|
||||
profile_name: "default".into(),
|
||||
table_name: format!("dec_bad_{}", i),
|
||||
columns: vec![ColumnDefinition {
|
||||
name: "amt".into(),
|
||||
field_type: typ.into(),
|
||||
}],
|
||||
..Default::default()
|
||||
};
|
||||
let err = post_table_definition(&pool, request).await.unwrap_err();
|
||||
assert_eq!(err.code(), Code::InvalidArgument, "{}", typ);
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that obviously invalid column identifiers are rejected
|
||||
// (start with digit/underscore, contain space or hyphen, or are empty).
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_fail_on_invalid_column_names(#[future] pool: PgPool) {
|
||||
let pool = pool.await;
|
||||
let bad_names = vec!["1col", "_col", "col name", "col-name", ""];
|
||||
for name in bad_names {
|
||||
let request = PostTableDefinitionRequest {
|
||||
profile_name: "default".into(),
|
||||
table_name: "tbl_invalid_cols".into(),
|
||||
columns: vec![ColumnDefinition {
|
||||
name: name.into(),
|
||||
field_type: "text".into(),
|
||||
}],
|
||||
..Default::default()
|
||||
};
|
||||
let err = post_table_definition(&pool, request).await.unwrap_err();
|
||||
assert_eq!(err.code(), Code::InvalidArgument, "{}", name);
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that a user‐supplied column ending in "_id" is rejected
|
||||
// to avoid collision with system‐generated FKs.
|
||||
#[rstest]
|
||||
#[tokio::test]
|
||||
async fn test_fail_on_column_name_suffix_id(#[future] pool: PgPool) {
|
||||
let pool = pool.await;
|
||||
let request = PostTableDefinitionRequest {
|
||||
profile_name: "default".into(),
|
||||
table_name: "tbl_suffix_id".into(),
|
||||
columns: vec![ColumnDefinition {
|
||||
name: "user_id".into(),
|
||||
field_type: "text".into(),
|
||||
}],
|
||||
..Default::default()
|
||||
};
|
||||
let err = post_table_definition(&pool, request).await.unwrap_err();
|
||||
assert_eq!(err.code(), Code::InvalidArgument);
|
||||
assert!(
|
||||
err.message().to_lowercase().contains("invalid column name"),
|
||||
"unexpected error message: {}",
|
||||
err.message()
|
||||
);
|
||||
}
|
||||
|
||||
include!("post_table_definition_test2.rs");
|
||||
include!("post_table_definition_test3.rs");
|
||||
include!("post_table_definition_test4.rs");
|
||||
|
||||
Reference in New Issue
Block a user