use std::collections::HashMap; use sqlx::{Pool, Postgres}; use windmill_api_client::types::{NewScript, ScriptLang}; use windmill_test_utils::init_client; fn quick_ns(content: &str, path: &str, kind: Option<&str>) -> NewScript { NewScript { draft_only: None, content: content.into(), language: ScriptLang::Bun, lock: None, parent_hash: None, path: path.into(), concurrent_limit: None, concurrency_time_window_s: None, cache_ttl: None, dedicated_worker: None, description: "".to_string(), envs: vec![], is_template: None, kind: kind.map(|s| s.to_string()), summary: "".to_string(), tag: None, schema: HashMap::new(), ws_error_handler_muted: Some(false), priority: None, delete_after_secs: None, timeout: None, restart_unless_cancelled: None, deployment_message: None, concurrency_key: None, visible_to_runner_only: None, auto_kind: None, codebase: None, has_preprocessor: None, on_behalf_of_email: None, assets: vec![], modules: None, } } /// Regression: a `failure`-kind script must never be marked `auto_kind = 'lib'` /// even if the parser fails to detect a `main` function, because the flow /// error-handler picker filters out lib scripts and would otherwise hide it. #[sqlx::test(fixtures("base"))] async fn failure_kind_script_without_main_is_not_marked_lib( db: Pool, ) -> anyhow::Result<()> { let (client, _port, _s) = init_client(db.clone()).await; // Content with no `main` — TS parser would normally set auto_kind = 'lib'. client .create_script( "test-workspace", &quick_ns( "export function notMain() { return 42 }", "u/test-user/failure_no_main", Some("failure"), ), ) .await .unwrap(); let auto_kind: Option = sqlx::query_scalar( "SELECT auto_kind FROM script \ WHERE workspace_id = $1 AND path = $2", ) .bind("test-workspace") .bind("u/test-user/failure_no_main") .fetch_one(&db) .await?; assert_ne!( auto_kind.as_deref(), Some("lib"), "failure-kind script must not be marked as 'lib' auto_kind, got {:?}", auto_kind ); Ok(()) } /// Sibling: a normal `script` kind WITHOUT main should still be marked `lib` /// (so it stays hidden from the regular script picker). Guards against an /// over-broad sanitizer accidentally clearing the value for plain scripts. #[sqlx::test(fixtures("base"))] async fn regular_script_without_main_is_still_marked_lib( db: Pool, ) -> anyhow::Result<()> { let (client, _port, _s) = init_client(db.clone()).await; client .create_script( "test-workspace", &quick_ns( "export function notMain() { return 42 }", "u/test-user/script_no_main", Some("script"), ), ) .await .unwrap(); let auto_kind: Option = sqlx::query_scalar( "SELECT auto_kind FROM script \ WHERE workspace_id = $1 AND path = $2", ) .bind("test-workspace") .bind("u/test-user/script_no_main") .fetch_one(&db) .await?; assert_eq!( auto_kind.as_deref(), Some("lib"), "regular script without main should be marked 'lib', got {:?}", auto_kind ); Ok(()) }