use azure_database_tui::{ domain::{ identifiers::{quote_identifier, quote_qualified}, profile::{ConnectionDraft, TlsPolicy}, sql::{CopyDirection, SqlLexer}, table::{DropTableConfirmation, InsertFieldValue, InsertForm}, }, services::tables::TableService, }; #[test] fn identifiers_are_quoted_per_segment() { assert_eq!( quote_identifier("Order\"Items").unwrap(), "\"Order\"\"Items\"" ); assert_eq!( quote_qualified("Sales", "Order Items").unwrap().0, "\"Sales\".\"Order Items\"" ); } #[test] fn profile_draft_rejects_empty_values() { let draft = ConnectionDraft { azure_resource_id: " ".into(), server_host: "host".into(), port: 5432, database: "db".into(), username: "user".into(), tls: TlsPolicy::SystemTrust, save_secret: false, }; assert!(draft.validate().is_err()); } #[test] fn lexer_keeps_semicolons_inside_lexical_regions() { let sql = "select ';'; -- ;\n select $$;$$; /* outer /* ; */ */ select 3;"; assert_eq!(SqlLexer::split(sql).len(), 3); assert_eq!( SqlLexer::classify_copy("COPY t FROM STDIN"), Some(CopyDirection::FromStdin) ); assert_eq!( SqlLexer::classify_copy("copy t to stdout"), Some(CopyDirection::ToStdout) ); } #[test] fn insert_values_are_not_interpolated_and_drop_needs_exact_name() { let form = InsertForm { schema: "public".into(), relation: "orders".into(), values: vec![ ( "amount".into(), InsertFieldValue::Text("1'); drop table x; --".into()), ), ("note".into(), InsertFieldValue::Null), ("created".into(), InsertFieldValue::UseDefault), ], }; let (sql, values) = TableService::insert_sql(&form).unwrap(); assert_eq!( sql, "INSERT INTO \"public\".\"orders\" (\"amount\", \"note\") VALUES ($1, NULL)" ); assert_eq!(values.len(), 1); assert!(!sql.contains("drop table")); let confirmation = DropTableConfirmation { canonical_name: "\"public\".\"orders\"".into(), typed_name: "\"public\".\"orders\"".into(), }; assert_eq!( TableService::drop_sql("public", "orders", &confirmation).unwrap(), "DROP TABLE \"public\".\"orders\"" ); }