// file: crates/ksp-app-solprices-desk/tests/desktop_contract.rs // version: 7 //! Desktop scaffold, shared-template and Config packaging contract audits for SOL Prices Desk `0.2.12`. fn app_root() -> std::path::PathBuf { return std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")); } fn read_json(path: &std::path::Path) -> serde_json::Value { let source = std::fs::read_to_string(path); assert!(source.is_ok(), "unable to read {}", path.display()); let source = match source { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return serde_json::Value::Null, }; 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 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 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 pre_002_shell_uses_reserved_ports_windows_and_owned_backend_paths() { let root = app_root(); let tauri = read_json(root.join("tauri.conf.json").as_path()); assert_eq!(tauri.pointer("/productName").and_then(serde_json::Value::as_str), std::option::Option::Some("KSP SOL Prices Desk")); assert_eq!(tauri.pointer("/identifier").and_then(serde_json::Value::as_str), std::option::Option::Some("com.sasedev.ksp-app-solprices-desk")); 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"); assert_eq!(tauri.pointer("/build/devUrl").and_then(serde_json::Value::as_str), std::option::Option::Some("http://localhost:1434")); 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(".")); assert_eq!( tauri.pointer("/build/frontendDist").and_then(serde_json::Value::as_str), std::option::Option::Some("../../../builds/khadhroony-solana-project/ksp-app-solprices-desk/dist"), ); let windows = tauri.pointer("/app/windows").and_then(serde_json::Value::as_array); assert!(windows.is_some()); let labels = match windows { std::option::Option::Some(values) => { values.iter().filter_map(|window| return window.get("label").and_then(serde_json::Value::as_str)).collect::>() }, std::option::Option::None => return, }; assert_eq!(labels, ["splash", "main"]); let vite = read_text(root.join("vite.config.ts").as_path()); assert!(vite.contains("port: 1434")); assert!(vite.contains("port: 1435")); assert!(vite.contains("strictPort: true")); assert!(!vite.contains("ksp-app-wallet-desk")); } #[test] fn pre_002_package_is_mixed_lib_bin_and_frontend_is_scaffold_only() { let root = app_root(); let manifest = read_text(root.join("Cargo.toml").as_path()); assert!(manifest.contains("name = \"ksp-app-solprices-desk\"")); assert!(manifest.contains("name = \"ksp_app_solprices_desk_lib\"")); assert!(manifest.contains("[[bin]]")); let main_rs = read_text(root.join("src/main.rs").as_path()); assert!(main_rs.contains("ksp_app_solprices_desk_lib::run")); let lib_rs = read_text(root.join("src/lib.rs").as_path()); assert!(lib_rs.contains("pub use self::tauri::run")); let tauri_rs = read_text(root.join("src/tauri.rs").as_path()); assert!(tauri_rs.contains("get_runtime_status")); assert!(!tauri_rs.contains("fn runtime_status(")); let main_html = read_text(root.join("frontend/main.html").as_path()); assert!(main_html.contains("data-view=\"prices\"")); assert!(main_html.contains("data-view=\"diagnostics\"")); } #[test] fn pre_003_packaging_contains_current_eleven_config_resources() { let root = app_root(); let tauri = read_json(root.join("tauri.conf.json").as_path()); let resources = tauri.pointer("/bundle/resources").and_then(serde_json::Value::as_object); assert!(resources.is_some()); if let std::option::Option::Some(resources) = resources { assert_eq!(resources.len(), 11); assert_eq!( resources.get("../../config/composite.ksp-app-solprices-desk.json").and_then(serde_json::Value::as_str), std::option::Option::Some("config/composite.ksp-app-solprices-desk.json"), ); assert!(resources.contains_key("../../config/std.offchain_transport.json")); assert!(resources.contains_key("../../config/schemas/std.offchain_transport.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("std::env::set_current_dir(layout.runtime_root())")); } #[test] fn pre_002_fix_001_reuses_the_common_ksp_desktop_template() { let root = app_root(); let package = read_text(root.join("package.json").as_path()); for dependency in ["@fltsci/tauri-plugin-tracing", "@fortawesome/fontawesome-free", "@tauri-apps/api", "bootstrap", "resize-observer-polyfill", "simplebar"] { assert!(package.contains(dependency), "missing common frontend dependency {dependency}"); } let main_typescript = read_text(root.join("frontend/ts/main.ts").as_path()); assert!(main_typescript.contains(r#"import ResizeObserver from "resize-observer-polyfill""#)); assert!(main_typescript.contains(".ResizeObserver = ResizeObserver")); assert!(main_typescript.contains("getCurrentWindow().label")); assert!(main_typescript.contains(r#""get_runtime_status""#)); let main_html = read_text(root.join("frontend/main.html").as_path()); assert!(main_html.contains(r#"