// file: crates/ksp-app-config-desk/tests/desktop_contract.rs // version: 7 //! Desktop build/shell contract audits for Config Desk. fn app_root() -> std::path::PathBuf { return std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")); } fn read_text(path: &std::path::Path) -> String { let source = std::fs::read_to_string(path); assert!(source.is_ok(), "unable to read {}", path.display()); return match source { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => String::new(), }; } fn read_json(path: &std::path::Path) -> serde_json::Value { let source = read_text(path); let parsed = serde_json::from_str::(source.as_str()); assert!(parsed.is_ok(), "unable to parse {}", path.display()); return match parsed { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => serde_json::Value::Null, }; } fn parse_semver_core(value: &str) -> std::option::Option<(u64, u64, u64)> { let core = match value.split_once('-') { std::option::Option::Some((core, _)) => core, std::option::Option::None => value, }; let mut parts = core.split('.'); let major = match parts.next().and_then(|part| return part.parse::().ok()) { std::option::Option::Some(value) => value, std::option::Option::None => return std::option::Option::None, }; let minor = match parts.next().and_then(|part| return part.parse::().ok()) { std::option::Option::Some(value) => value, std::option::Option::None => return std::option::Option::None, }; let patch = match parts.next().and_then(|part| return part.parse::().ok()) { std::option::Option::Some(value) => value, std::option::Option::None => return std::option::Option::None, }; if parts.next().is_some() { return std::option::Option::None; } return std::option::Option::Some((major, minor, patch)); } fn assert_packaged_version_floor(value: std::option::Option<&str>, field: &str) { assert!(value.is_some(), "{field} packaged version must exist"); let value = match value { std::option::Option::Some(value) => value, std::option::Option::None => return, }; let parsed = parse_semver_core(value); assert!(parsed.is_some(), "{field} packaged version must be SemVer-like"); if let std::option::Option::Some(parsed) = parsed { assert!(parsed >= (0, 2, 6), "{field} packaged version must be >= 0.2.6"); } } #[test] fn tauri_and_frontend_build_contracts_remain_explicit() { let root = app_root(); let tauri = read_json(root.join("tauri.conf.json").as_path()); assert_eq!(tauri.pointer("/build/devUrl").and_then(serde_json::Value::as_str), std::option::Option::Some("http://localhost:1430")); assert_eq!(tauri.pointer("/build/beforeDevCommand/script").and_then(serde_json::Value::as_str), std::option::Option::Some("npm run dev")); assert_eq!(tauri.pointer("/build/beforeDevCommand/cwd").and_then(serde_json::Value::as_str), std::option::Option::Some(".")); assert_eq!(tauri.pointer("/build/beforeBuildCommand/script").and_then(serde_json::Value::as_str), std::option::Option::Some("npm run build")); assert_eq!(tauri.pointer("/build/beforeBuildCommand/cwd").and_then(serde_json::Value::as_str), std::option::Option::Some(".")); let windows = tauri.pointer("/app/windows").and_then(serde_json::Value::as_array); assert!(windows.is_some()); let windows = match windows { std::option::Option::Some(value) => value, std::option::Option::None => return, }; assert_eq!(windows.len(), 2); let labels = windows.iter().filter_map(|window| return window.get("label").and_then(serde_json::Value::as_str)).collect::>(); assert_eq!(labels, ["splash", "main"]); let main = windows.iter().find(|window| return window.get("label").and_then(serde_json::Value::as_str) == std::option::Option::Some("main")); assert!(main.is_some()); if let std::option::Option::Some(main) = main { assert_eq!(main.get("visible").and_then(serde_json::Value::as_bool), std::option::Option::Some(false)); } let manifest = read_text(root.join("Cargo.toml").as_path()); assert!(manifest.contains("name = \"ksp-app-config-desk\"")); let package = read_json(root.join("package.json").as_path()); let build = package.pointer("/scripts/build").and_then(serde_json::Value::as_str); assert!(build.is_some_and(|value| return value.contains("tsc") && value.contains("vite build"))); assert!(package.pointer("/scripts/check").is_none()); assert!(package.pointer("/scripts/preview").is_none()); } #[test] fn shell_registry_owns_view_activation_and_specialized_editor_dispatch() { let root = app_root(); let registry = read_text(root.join("frontend/ts/shell_registry.ts").as_path()); let main = read_text(root.join("frontend/ts/main.ts").as_path()); let documents = read_text(root.join("frontend/ts/documents.ts").as_path()); let html = read_text(root.join("frontend/main.html").as_path()); assert!(registry.contains("export const viewRegistry")); assert!(registry.contains("fileId: \"cfg.std.logging\"")); assert!(registry.contains("viewId: \"logging\"")); assert!(main.contains("registeredViewIds()")); assert!(main.contains("ksp:activate-view")); assert!(documents.contains("specializedEditorForFileId")); assert!(documents.contains("requestViewActivation")); assert!(html.contains("id=\"openSpecializedEditor\"")); } #[test] fn pre_014_template_uses_sidebar_navigation_and_kbot_style_splash_contract() { let root = app_root(); let main = read_text(root.join("frontend/main.html").as_path()); let splash = read_text(root.join("frontend/splash.html").as_path()); let app_style = read_text(root.join("frontend/sass/_app.scss").as_path()); let splash_style = read_text(root.join("frontend/sass/splash.scss").as_path()); let splash_ts = read_text(root.join("frontend/ts/splash.ts").as_path()); assert!(main.starts_with("")); assert!(main.contains("app-sidebar")); assert!(main.contains("row g-0 h-100 flex-nowrap")); assert!(app_style.contains("flex-wrap: nowrap")); assert!(app_style.contains("min-width: 0")); assert!(main.contains("nav nav-pills flex-column")); assert!(splash.starts_with("")); assert!(splash.contains("id=\"debug-info\"")); assert!(splash.contains("id=\"messages-container\"")); assert!(splash.contains("sass/splash.scss")); assert!(splash_style.contains("overflow: hidden")); assert!(splash_style.contains("width: 100%")); assert!(splash_style.contains("user-select: none")); assert!(splash_ts.contains("add_debug")); assert!(splash_ts.contains("add_message")); } #[test] fn pre_018_packaged_runtime_bundles_config_resources_and_activates_shared_writable_root() { let root = app_root(); let tauri = read_json(root.join("tauri.conf.json").as_path()); let tauri_version = tauri.pointer("/version").and_then(serde_json::Value::as_str); assert_packaged_version_floor(tauri_version, "tauri.conf.json"); let package = read_json(root.join("package.json").as_path()); let package_version = package.pointer("/version").and_then(serde_json::Value::as_str); assert_packaged_version_floor(package_version, "package.json"); assert_eq!(tauri_version, package_version, "desktop package metadata versions must remain synchronized"); let resources = tauri.pointer("/bundle/resources").and_then(serde_json::Value::as_object); assert!(resources.is_some(), "packaged Config resources map must exist"); if let std::option::Option::Some(resources) = resources { assert_eq!(resources.len(), 8); assert_eq!(resources.get("../../config/std.logging.json").and_then(serde_json::Value::as_str), std::option::Option::Some("config/std.logging.json")); assert_eq!( resources.get("../../config/schemas/std.wallet.schema.json").and_then(serde_json::Value::as_str), std::option::Option::Some("config/schemas/std.wallet.schema.json"), ); } let tauri_source = read_text(root.join("src/tauri.rs").as_path()); assert!(tauri_source.contains("ksp_config_lib::prepare_packaged_runtime")); assert!(tauri_source.contains("tauri::utils::platform::resource_dir")); assert!(tauri_source.contains("std::env::set_current_dir(layout.runtime_root())")); }