use super::*; fn acceptance(connection: serde_json::Value, name: &str) { let directory = Directory::new(); let project = Project::load(&fixture().with_file_name("database-read")).unwrap(); let program = project.check().unwrap(); let binary = build::build(&program, &project.sources, "main", &directory.0.join(name)).unwrap(); std::fs::create_dir(directory.0.join("config")).unwrap(); std::fs::write( directory.0.join("config/setting.json"), serde_json::json!({"database":{"default":connection}}).to_string(), ) .unwrap(); for (command, input, expected) in [ ( "lookup", serde_json::json!({"value":"alpha"}), serde_json::json!("alpha"), ), ( "lookup", serde_json::json!({"value":"雪' OR 1=1 --"}), serde_json::json!("雪' OR 1=1 --"), ), ( "lookup", serde_json::json!({"value":"unknown"}), serde_json::json!("missing"), ), ( "names", serde_json::json!({"limit":2}), serde_json::json!([{"name":"alpha"},{"name":"beta"}]), ), ("count", serde_json::json!({}), serde_json::json!(3)), ("early", serde_json::json!({}), serde_json::json!(4)), ("closed", serde_json::json!({}), serde_json::json!(3)), ] { for _ in 0..3 { let result = execute( &binary, &format!("demo.account.{command}"), &input.to_string(), ); assert!( result.status.success(), "{command}: {}", String::from_utf8_lossy(&result.stderr) ); assert_eq!( serde_json::from_slice::(&result.stdout).unwrap()["data"], expected ); } } for (command, input) in [("names", "{\"limit\":3}"), ("broken", "{}")] { let result = execute(&binary, &format!("demo.account.{command}"), input); assert!(!result.status.success()); assert!( String::from_utf8_lossy(&result.stderr).contains("database operation failed"), "{command}: {}", String::from_utf8_lossy(&result.stderr) ); } let result = execute(&binary, "demo.account.probe", "{}"); assert!( result.status.success(), "{}", String::from_utf8_lossy(&result.stderr) ); assert_eq!( serde_json::from_slice::(&result.stdout).unwrap()["data"], "InvalidData" ); } #[test] fn typed_sql_and_row_stream_run_with_one_sqlite_connection() { acceptance( serde_json::json!({"type":"sqlite","path":"read.db","max_connections":1,"max_page_size":2}), "read-sqlite", ); } #[cfg(feature = "postgres")] #[test] #[ignore = "requires isolated database.postgres_test"] fn typed_sql_and_row_stream_run_with_one_postgres_connection() { let directory = Directory::new(); let schema = super::postgres::Schema::new( &directory.0, "dever_native_read", "CREATE SCHEMA dever_native_read", "DROP SCHEMA dever_native_read CASCADE", ); let mut connection = schema.connection.clone(); connection["max_connections"] = 1.into(); connection["max_page_size"] = 2.into(); acceptance(connection, "read-postgres"); }