@@ -0,0 +1,552 @@
// tests/tables_data/put/put_table_data_steel_decimal_test.rs
use sqlx ::PgPool ;
use common ::proto ::multieko2 ::{
table_definition ::{ PostTableDefinitionRequest , ColumnDefinition } ,
table_script ::PostTableScriptRequest ,
tables_data ::{ PostTableDataRequest , PutTableDataRequest } ,
} ;
use prost_types ::value ::Kind ;
use prost_types ::Value as ProtoValue ;
use std ::collections ::HashMap ;
use tokio ::sync ::mpsc ;
use server ::indexer ::IndexCommand ;
use server ::table_definition ::handlers ::post_table_definition ::post_table_definition ;
use server ::table_script ::handlers ::post_table_script ::post_table_script ;
use server ::tables_data ::handlers ::post_table_data ::post_table_data ;
use server ::tables_data ::handlers ::put_table_data ::put_table_data ;
async fn setup_test_schema ( pool : & PgPool , profile_name : & str , table_name : & str ) -> i64 {
// Create table definition
let request = PostTableDefinitionRequest {
profile_name : profile_name . to_string ( ) ,
table_name : table_name . to_string ( ) ,
columns : vec ! [
ColumnDefinition {
name : " price " . to_string ( ) ,
field_type : " decimal(10, 2) " . to_string ( ) ,
} ,
ColumnDefinition {
name : " quantity " . to_string ( ) ,
field_type : " integer " . to_string ( ) ,
} ,
ColumnDefinition {
name : " total " . to_string ( ) ,
field_type : " decimal(10, 2) " . to_string ( ) ,
} ,
ColumnDefinition {
name : " percentage " . to_string ( ) ,
field_type : " decimal(28, 24) " . to_string ( ) ,
} ,
] ,
indexes : vec ! [ ] ,
links : vec ! [ ] ,
} ;
let response = post_table_definition ( pool , request ) . await . unwrap ( ) ;
assert! ( response . success ) ;
// Get table definition ID
let schema_row = sqlx ::query! ( " SELECT id FROM schemas WHERE name = $1 " , profile_name )
. fetch_one ( pool )
. await
. unwrap ( ) ;
let table_row = sqlx ::query! (
" SELECT id FROM table_definitions WHERE schema_id = $1 AND table_name = $2 " ,
schema_row . id ,
table_name
)
. fetch_one ( pool )
. await
. unwrap ( ) ;
table_row . id
}
async fn create_indexer_channel ( ) -> mpsc ::Sender < IndexCommand > {
let ( tx , mut rx ) = mpsc ::channel ( 100 ) ;
tokio ::spawn ( async move {
while let Some ( _ ) = rx . recv ( ) . await {
// Just consume messages for testing
}
} ) ;
tx
}
// Helper function to create initial record and return its ID
async fn create_initial_record (
pool : & PgPool ,
profile_name : & str ,
table_name : & str ,
indexer_tx : & mpsc ::Sender < IndexCommand > ,
) -> i64 {
let mut data = HashMap ::new ( ) ;
data . insert ( " price " . to_string ( ) , ProtoValue {
kind : Some ( Kind ::StringValue ( " 10.00 " . to_string ( ) ) ) ,
} ) ;
data . insert ( " quantity " . to_string ( ) , ProtoValue {
kind : Some ( Kind ::NumberValue ( 1.0 ) ) ,
} ) ;
data . insert ( " total " . to_string ( ) , ProtoValue {
kind : Some ( Kind ::StringValue ( " 10.00 " . to_string ( ) ) ) ,
} ) ;
// Add percentage to satisfy all potential validation scripts during creation
data . insert ( " percentage " . to_string ( ) , ProtoValue {
kind : Some ( Kind ::StringValue ( " 100.00 " . to_string ( ) ) ) ,
} ) ;
let data_request = PostTableDataRequest {
profile_name : profile_name . to_string ( ) ,
table_name : table_name . to_string ( ) ,
data ,
} ;
let response = post_table_data ( pool , data_request , indexer_tx ) . await . unwrap ( ) ;
response . inserted_id
}
#[ sqlx::test ]
async fn test_put_basic_arithmetic_validation_success ( pool : PgPool ) {
let table_def_id = setup_test_schema ( & pool , " test_put_arithmetic " , " invoice " ) . await ;
let indexer_tx = create_indexer_channel ( ) . await ;
let script_request = PostTableScriptRequest {
table_definition_id : table_def_id ,
target_column : " total " . to_string ( ) ,
script : " (* $price $quantity) " . to_string ( ) ,
description : " Total = Price × Quantity " . to_string ( ) ,
} ;
post_table_script ( & pool , script_request ) . await . unwrap ( ) ;
let record_id = create_initial_record ( & pool , " test_put_arithmetic " , " invoice " , & indexer_tx ) . await ;
let mut update_data = HashMap ::new ( ) ;
update_data . insert ( " price " . to_string ( ) , ProtoValue {
kind : Some ( Kind ::StringValue ( " 25.50 " . to_string ( ) ) ) ,
} ) ;
update_data . insert ( " quantity " . to_string ( ) , ProtoValue {
kind : Some ( Kind ::NumberValue ( 3.0 ) ) ,
} ) ;
update_data . insert ( " total " . to_string ( ) , ProtoValue {
kind : Some ( Kind ::StringValue ( " 76.50 " . to_string ( ) ) ) ,
} ) ;
let put_request = PutTableDataRequest {
profile_name : " test_put_arithmetic " . to_string ( ) ,
table_name : " invoice " . to_string ( ) ,
id : record_id ,
data : update_data ,
} ;
let response = put_table_data ( & pool , put_request , & indexer_tx ) . await . unwrap ( ) ;
assert! ( response . success ) ;
assert_eq! ( response . updated_id , record_id ) ;
}
#[ sqlx::test ]
async fn test_put_basic_arithmetic_validation_failure ( pool : PgPool ) {
let table_def_id = setup_test_schema ( & pool , " test_put_arithmetic_fail " , " invoice " ) . await ;
let indexer_tx = create_indexer_channel ( ) . await ;
let script_request = PostTableScriptRequest {
table_definition_id : table_def_id ,
target_column : " total " . to_string ( ) ,
script : " (* $price $quantity) " . to_string ( ) ,
description : " Total = Price × Quantity " . to_string ( ) ,
} ;
post_table_script ( & pool , script_request ) . await . unwrap ( ) ;
let record_id = create_initial_record ( & pool , " test_put_arithmetic_fail " , " invoice " , & indexer_tx ) . await ;
let mut update_data = HashMap ::new ( ) ;
update_data . insert ( " price " . to_string ( ) , ProtoValue {
kind : Some ( Kind ::StringValue ( " 25.50 " . to_string ( ) ) ) ,
} ) ;
update_data . insert ( " quantity " . to_string ( ) , ProtoValue {
kind : Some ( Kind ::NumberValue ( 3.0 ) ) ,
} ) ;
update_data . insert ( " total " . to_string ( ) , ProtoValue {
kind : Some ( Kind ::StringValue ( " 70.00 " . to_string ( ) ) ) ,
} ) ;
let put_request = PutTableDataRequest {
profile_name : " test_put_arithmetic_fail " . to_string ( ) ,
table_name : " invoice " . to_string ( ) ,
id : record_id ,
data : update_data ,
} ;
let result = put_table_data ( & pool , put_request , & indexer_tx ) . await ;
assert! ( result . is_err ( ) ) ;
let error = result . unwrap_err ( ) ;
assert_eq! ( error . code ( ) , tonic ::Code ::InvalidArgument ) ;
let msg = error . message ( ) ;
assert! ( msg . contains ( " Validation failed for column 'total' " ) ) ;
assert! ( msg . contains ( " Script calculated '76.5' " ) ) ;
assert! ( msg . contains ( " but user provided '70.00' " ) ) ;
}
#[ sqlx::test ]
async fn test_put_complex_formula_validation ( pool : PgPool ) {
let table_def_id = setup_test_schema ( & pool , " test_put_complex " , " order " ) . await ;
let indexer_tx = create_indexer_channel ( ) . await ;
let script_request = PostTableScriptRequest {
table_definition_id : table_def_id ,
target_column : " total " . to_string ( ) ,
script : " (+ (* $price $quantity) (* (* $price $quantity) 0.08)) " . to_string ( ) ,
description : " Total with 8% tax " . to_string ( ) ,
} ;
post_table_script ( & pool , script_request ) . await . unwrap ( ) ;
let record_id = create_initial_record ( & pool , " test_put_complex " , " order " , & indexer_tx ) . await ;
let mut update_data = HashMap ::new ( ) ;
update_data . insert ( " price " . to_string ( ) , ProtoValue {
kind : Some ( Kind ::StringValue ( " 100.00 " . to_string ( ) ) ) ,
} ) ;
update_data . insert ( " quantity " . to_string ( ) , ProtoValue {
kind : Some ( Kind ::NumberValue ( 2.0 ) ) ,
} ) ;
update_data . insert ( " total " . to_string ( ) , ProtoValue {
kind : Some ( Kind ::StringValue ( " 216.00 " . to_string ( ) ) ) ,
} ) ;
let put_request = PutTableDataRequest {
profile_name : " test_put_complex " . to_string ( ) ,
table_name : " order " . to_string ( ) ,
id : record_id ,
data : update_data ,
} ;
let response = put_table_data ( & pool , put_request , & indexer_tx ) . await . unwrap ( ) ;
assert! ( response . success ) ;
}
#[ sqlx::test ]
async fn test_put_division_with_precision ( pool : PgPool ) {
let table_def_id = setup_test_schema ( & pool , " test_put_division " , " calculation " ) . await ;
let indexer_tx = create_indexer_channel ( ) . await ;
let script_request = PostTableScriptRequest {
table_definition_id : table_def_id ,
target_column : " percentage " . to_string ( ) ,
script : " (/ $total $price) " . to_string ( ) ,
description : " Percentage = Total / Price " . to_string ( ) ,
} ;
post_table_script ( & pool , script_request ) . await . unwrap ( ) ;
let record_id = create_initial_record ( & pool , " test_put_division " , " calculation " , & indexer_tx ) . await ;
let mut update_data = HashMap ::new ( ) ;
update_data . insert ( " price " . to_string ( ) , ProtoValue {
kind : Some ( Kind ::StringValue ( " 3.00 " . to_string ( ) ) ) ,
} ) ;
update_data . insert ( " total " . to_string ( ) , ProtoValue {
kind : Some ( Kind ::StringValue ( " 10.00 " . to_string ( ) ) ) ,
} ) ;
update_data . insert ( " percentage " . to_string ( ) , ProtoValue {
kind : Some ( Kind ::StringValue ( " 3.333333333333333333333333 " . to_string ( ) ) ) ,
} ) ;
let put_request = PutTableDataRequest {
profile_name : " test_put_division " . to_string ( ) ,
table_name : " calculation " . to_string ( ) ,
id : record_id ,
data : update_data ,
} ;
let response = put_table_data ( & pool , put_request , & indexer_tx ) . await . unwrap ( ) ;
assert! ( response . success ) ;
}
#[ sqlx::test ]
async fn test_put_advanced_math_functions ( pool : PgPool ) {
let request = PostTableDefinitionRequest {
profile_name : " test_put_advanced_math " . to_string ( ) ,
table_name : " calculations " . to_string ( ) ,
columns : vec ! [
ColumnDefinition {
name : " input " . to_string ( ) ,
field_type : " decimal(10, 4) " . to_string ( ) ,
} ,
ColumnDefinition {
name : " square_root " . to_string ( ) ,
field_type : " decimal(28, 24) " . to_string ( ) ,
} ,
ColumnDefinition {
name : " power_result " . to_string ( ) ,
field_type : " decimal(10, 4) " . to_string ( ) ,
} ,
] ,
indexes : vec ! [ ] ,
links : vec ! [ ] ,
} ;
post_table_definition ( & pool , request ) . await . unwrap ( ) ;
let schema_row = sqlx ::query! ( " SELECT id FROM schemas WHERE name = $1 " , " test_put_advanced_math " )
. fetch_one ( & pool ) . await . unwrap ( ) ;
let table_row = sqlx ::query! (
" SELECT id FROM table_definitions WHERE schema_id = $1 AND table_name = $2 " ,
schema_row . id , " calculations "
) . fetch_one ( & pool ) . await . unwrap ( ) ;
let indexer_tx = create_indexer_channel ( ) . await ;
let sqrt_script = PostTableScriptRequest {
table_definition_id : table_row . id ,
target_column : " square_root " . to_string ( ) ,
script : " (sqrt $input) " . to_string ( ) ,
description : " Square root validation " . to_string ( ) ,
} ;
post_table_script ( & pool , sqrt_script ) . await . unwrap ( ) ;
let power_script = PostTableScriptRequest {
table_definition_id : table_row . id ,
target_column : " power_result " . to_string ( ) ,
script : " (^ $input 2.0) " . to_string ( ) ,
description : " Power function validation " . to_string ( ) ,
} ;
post_table_script ( & pool , power_script ) . await . unwrap ( ) ;
let mut initial_data = HashMap ::new ( ) ;
initial_data . insert ( " input " . to_string ( ) , ProtoValue { kind : Some ( Kind ::StringValue ( " 4.0000 " . to_string ( ) ) ) } ) ;
initial_data . insert ( " square_root " . to_string ( ) , ProtoValue { kind : Some ( Kind ::StringValue ( " 2.0 " . to_string ( ) ) ) } ) ;
initial_data . insert ( " power_result " . to_string ( ) , ProtoValue { kind : Some ( Kind ::StringValue ( " 16.0000 " . to_string ( ) ) ) } ) ;
let initial_request = PostTableDataRequest {
profile_name : " test_put_advanced_math " . to_string ( ) ,
table_name : " calculations " . to_string ( ) ,
data : initial_data ,
} ;
let record_id = post_table_data ( & pool , initial_request , & indexer_tx ) . await . unwrap ( ) . inserted_id ;
let mut update_data = HashMap ::new ( ) ;
update_data . insert ( " input " . to_string ( ) , ProtoValue { kind : Some ( Kind ::StringValue ( " 16.0000 " . to_string ( ) ) ) } ) ;
update_data . insert ( " square_root " . to_string ( ) , ProtoValue { kind : Some ( Kind ::StringValue ( " 4.0 " . to_string ( ) ) ) } ) ;
update_data . insert ( " power_result " . to_string ( ) , ProtoValue { kind : Some ( Kind ::StringValue ( " 256.0000 " . to_string ( ) ) ) } ) ;
let put_request = PutTableDataRequest {
profile_name : " test_put_advanced_math " . to_string ( ) ,
table_name : " calculations " . to_string ( ) ,
id : record_id ,
data : update_data ,
} ;
let response = put_table_data ( & pool , put_request , & indexer_tx ) . await . unwrap ( ) ;
assert! ( response . success ) ;
}
#[ sqlx::test ]
async fn test_put_financial_calculations ( pool : PgPool ) {
let request = PostTableDefinitionRequest {
profile_name : " test_put_financial " . to_string ( ) ,
table_name : " finance " . to_string ( ) ,
columns : vec ! [
ColumnDefinition { name : " principal " . to_string ( ) , field_type : " decimal(12, 2) " . to_string ( ) } ,
ColumnDefinition { name : " rate " . to_string ( ) , field_type : " decimal(6, 4) " . to_string ( ) } ,
ColumnDefinition { name : " time " . to_string ( ) , field_type : " decimal(4, 1) " . to_string ( ) } ,
ColumnDefinition { name : " compound_result " . to_string ( ) , field_type : " decimal(12, 4) " . to_string ( ) } ,
ColumnDefinition { name : " percentage_result " . to_string ( ) , field_type : " decimal(10, 2) " . to_string ( ) } ,
] ,
indexes : vec ! [ ] , links : vec ! [ ] ,
} ;
post_table_definition ( & pool , request ) . await . unwrap ( ) ;
let schema_row = sqlx ::query! ( " SELECT id FROM schemas WHERE name = $1 " , " test_put_financial " ) . fetch_one ( & pool ) . await . unwrap ( ) ;
let table_row = sqlx ::query! ( " SELECT id FROM table_definitions WHERE schema_id = $1 AND table_name = $2 " , schema_row . id , " finance " ) . fetch_one ( & pool ) . await . unwrap ( ) ;
let indexer_tx = create_indexer_channel ( ) . await ;
let compound_script = PostTableScriptRequest {
table_definition_id : table_row . id ,
target_column : " compound_result " . to_string ( ) ,
script : " (* $principal (^ (+ 1.0 $rate) $time)) " . to_string ( ) ,
description : " Compound interest calculation " . to_string ( ) ,
} ;
post_table_script ( & pool , compound_script ) . await . unwrap ( ) ;
let percentage_script = PostTableScriptRequest {
table_definition_id : table_row . id ,
target_column : " percentage_result " . to_string ( ) ,
script : " (* $principal $rate) " . to_string ( ) ,
description : " Percentage calculation " . to_string ( ) ,
} ;
post_table_script ( & pool , percentage_script ) . await . unwrap ( ) ;
let mut initial_data = HashMap ::new ( ) ;
initial_data . insert ( " principal " . to_string ( ) , ProtoValue { kind : Some ( Kind ::StringValue ( " 500.00 " . to_string ( ) ) ) } ) ;
initial_data . insert ( " rate " . to_string ( ) , ProtoValue { kind : Some ( Kind ::StringValue ( " 0.0300 " . to_string ( ) ) ) } ) ;
initial_data . insert ( " time " . to_string ( ) , ProtoValue { kind : Some ( Kind ::StringValue ( " 1.0 " . to_string ( ) ) ) } ) ;
initial_data . insert ( " compound_result " . to_string ( ) , ProtoValue { kind : Some ( Kind ::StringValue ( " 515.0000 " . to_string ( ) ) ) } ) ;
initial_data . insert ( " percentage_result " . to_string ( ) , ProtoValue { kind : Some ( Kind ::StringValue ( " 15.00 " . to_string ( ) ) ) } ) ;
let initial_request = PostTableDataRequest {
profile_name : " test_put_financial " . to_string ( ) ,
table_name : " finance " . to_string ( ) ,
data : initial_data ,
} ;
let record_id = post_table_data ( & pool , initial_request , & indexer_tx ) . await . unwrap ( ) . inserted_id ;
let mut update_data = HashMap ::new ( ) ;
update_data . insert ( " principal " . to_string ( ) , ProtoValue { kind : Some ( Kind ::StringValue ( " 1000.00 " . to_string ( ) ) ) } ) ;
update_data . insert ( " rate " . to_string ( ) , ProtoValue { kind : Some ( Kind ::StringValue ( " 0.0500 " . to_string ( ) ) ) } ) ;
update_data . insert ( " time " . to_string ( ) , ProtoValue { kind : Some ( Kind ::StringValue ( " 2.0 " . to_string ( ) ) ) } ) ;
update_data . insert ( " compound_result " . to_string ( ) , ProtoValue { kind : Some ( Kind ::StringValue ( " 1102.5000 " . to_string ( ) ) ) } ) ;
update_data . insert ( " percentage_result " . to_string ( ) , ProtoValue { kind : Some ( Kind ::StringValue ( " 50.00 " . to_string ( ) ) ) } ) ;
let put_request = PutTableDataRequest {
profile_name : " test_put_financial " . to_string ( ) ,
table_name : " finance " . to_string ( ) ,
id : record_id ,
data : update_data ,
} ;
let response = put_table_data ( & pool , put_request , & indexer_tx ) . await . unwrap ( ) ;
assert! ( response . success ) ;
}
#[ sqlx::test ]
async fn test_put_partial_update_with_validation ( pool : PgPool ) {
let table_def_id = setup_test_schema ( & pool , " test_put_partial " , " invoice " ) . await ;
let indexer_tx = create_indexer_channel ( ) . await ;
let script_request = PostTableScriptRequest {
table_definition_id : table_def_id ,
target_column : " total " . to_string ( ) ,
script : " (* $price $quantity) " . to_string ( ) ,
description : " Total = Price × Quantity " . to_string ( ) ,
} ;
post_table_script ( & pool , script_request ) . await . unwrap ( ) ;
let record_id = create_initial_record ( & pool , " test_put_partial " , " invoice " , & indexer_tx ) . await ;
// Partial update: only update quantity. Validation for total should still run and pass.
// The merged context will be { price: 10.00, quantity: 5, total: 10.00, ... }
// The script will calculate total as 10.00 * 5 = 50.00.
// Since we are not providing 'total' in the update, validation for it is skipped.
let mut update_data = HashMap ::new ( ) ;
update_data . insert ( " quantity " . to_string ( ) , ProtoValue {
kind : Some ( Kind ::NumberValue ( 5.0 ) ) ,
} ) ;
let put_request = PutTableDataRequest {
profile_name : " test_put_partial " . to_string ( ) ,
table_name : " invoice " . to_string ( ) ,
id : record_id ,
data : update_data ,
} ;
let response = put_table_data ( & pool , put_request , & indexer_tx ) . await . unwrap ( ) ;
assert! ( response . success ) ;
// Now, test a partial update that SHOULD fail validation.
// We update quantity and provide an incorrect total.
let mut failing_update_data = HashMap ::new ( ) ;
failing_update_data . insert ( " quantity " . to_string ( ) , ProtoValue {
kind : Some ( Kind ::NumberValue ( 3.0 ) ) ,
} ) ;
failing_update_data . insert ( " total " . to_string ( ) , ProtoValue {
kind : Some ( Kind ::StringValue ( " 99.99 " . to_string ( ) ) ) , // Wrong! Should be 10.00 * 3 = 30.00
} ) ;
let failing_put_request = PutTableDataRequest {
profile_name : " test_put_partial " . to_string ( ) ,
table_name : " invoice " . to_string ( ) ,
id : record_id ,
data : failing_update_data ,
} ;
let result = put_table_data ( & pool , failing_put_request , & indexer_tx ) . await ;
assert! ( result . is_err ( ) ) ;
let error = result . unwrap_err ( ) ;
assert_eq! ( error . code ( ) , tonic ::Code ::InvalidArgument ) ;
assert! ( error . message ( ) . contains ( " Script calculated '30' " ) ) ;
}
#[ sqlx::test ]
async fn test_put_no_data_update ( pool : PgPool ) {
let _table_def_id = setup_test_schema ( & pool , " test_put_empty " , " invoice " ) . await ;
let indexer_tx = create_indexer_channel ( ) . await ;
let record_id = create_initial_record ( & pool , " test_put_empty " , " invoice " , & indexer_tx ) . await ;
let update_data = HashMap ::new ( ) ;
let put_request = PutTableDataRequest {
profile_name : " test_put_empty " . to_string ( ) ,
table_name : " invoice " . to_string ( ) ,
id : record_id ,
data : update_data ,
} ;
let response = put_table_data ( & pool , put_request , & indexer_tx ) . await . unwrap ( ) ;
assert! ( response . success ) ;
assert! ( response . message . contains ( " No fields to update " ) ) ;
}
#[ sqlx::test ]
async fn test_put_record_not_found ( pool : PgPool ) {
let _table_def_id = setup_test_schema ( & pool , " test_put_not_found " , " invoice " ) . await ;
let indexer_tx = create_indexer_channel ( ) . await ;
let mut update_data = HashMap ::new ( ) ;
update_data . insert ( " price " . to_string ( ) , ProtoValue {
kind : Some ( Kind ::StringValue ( " 100.00 " . to_string ( ) ) ) ,
} ) ;
let put_request = PutTableDataRequest {
profile_name : " test_put_not_found " . to_string ( ) ,
table_name : " invoice " . to_string ( ) ,
id : 99999 ,
data : update_data ,
} ;
let result = put_table_data ( & pool , put_request , & indexer_tx ) . await ;
assert! ( result . is_err ( ) ) ;
let error = result . unwrap_err ( ) ;
assert_eq! ( error . code ( ) , tonic ::Code ::NotFound ) ;
assert! ( error . message ( ) . contains ( " Record not found " ) ) ;
}
#[ sqlx::test ]
async fn test_put_steel_script_error_handling ( pool : PgPool ) {
let table_def_id = setup_test_schema ( & pool , " test_put_errors " , " error_test " ) . await ;
let indexer_tx = create_indexer_channel ( ) . await ;
let script_request = PostTableScriptRequest {
table_definition_id : table_def_id ,
target_column : " total " . to_string ( ) ,
script : " (/ $price 0.0) " . to_string ( ) ,
description : " Error test " . to_string ( ) ,
} ;
post_table_script ( & pool , script_request ) . await . unwrap ( ) ;
let record_id = create_initial_record ( & pool , " test_put_errors " , " error_test " , & indexer_tx ) . await ;
let mut update_data = HashMap ::new ( ) ;
update_data . insert ( " price " . to_string ( ) , ProtoValue {
kind : Some ( Kind ::StringValue ( " 100.00 " . to_string ( ) ) ) ,
} ) ;
update_data . insert ( " total " . to_string ( ) , ProtoValue {
kind : Some ( Kind ::StringValue ( " 999.99 " . to_string ( ) ) ) ,
} ) ;
let put_request = PutTableDataRequest {
profile_name : " test_put_errors " . to_string ( ) ,
table_name : " error_test " . to_string ( ) ,
id : record_id ,
data : update_data ,
} ;
let result = put_table_data ( & pool , put_request , & indexer_tx ) . await ;
assert! ( result . is_err ( ) ) ;
let error = result . unwrap_err ( ) ;
assert_eq! ( error . code ( ) , tonic ::Code ::InvalidArgument ) ;
assert! ( error . message ( ) . contains ( " Script execution failed " ) ) ;
assert! ( error . message ( ) . contains ( " Division by zero " ) ) ;
}