//! Contract tests for client install-time security defaults. //! //! Scope: inspect the client installer shell contract without running it. //! Targets: `scripts/install/client.sh`. //! Why: secure-by-default relay transport depends on installing the server-issued //! client cert bundle exactly where the desktop app auto-discovers it. const CLIENT_INSTALL: &str = include_str!("../../scripts/install/client.sh"); #[test] fn client_install_accepts_server_generated_tls_bundle() { for expected in [ "LESAVKA_CLIENT_PKI_BUNDLE", "CLIENT_PKI_DIR", "ca.crt", "client.crt", "client.key", "install_client_pki_bundle", "fetch_client_pki_bundle", "LESAVKA_CLIENT_PKI_SSH_SOURCE", "LESAVKA_CLIENT_CAPTURE_DIR", "theia:/etc/lesavka/lesavka-client-pki.tar.gz", "Pictures/lesavka", "HTTPS/mTLS relay connections will not work until this bundle is installed", "TLS identity:", "Captures:", "$USER_HOME/.local/bin/lesavka-client", "User PATH alias:", ] { assert!( CLIENT_INSTALL.contains(expected), "client installer should include TLS bundle contract fragment {expected}" ); } assert!( CLIENT_INSTALL.contains(".config/lesavka/pki"), "client cert bundle should land in the same path the desktop app auto-loads" ); assert!( CLIENT_INSTALL.contains("0600"), "client private key should be installed with private permissions" ); assert!( CLIENT_INSTALL.contains("scp -q -o BatchMode=yes"), "client installer should auto-fetch the server enrollment bundle without hanging" ); assert!( CLIENT_INSTALL.contains("run_as_user mktemp"), "auto-fetch destination should be owned by the user who runs scp" ); } #[test] fn client_install_prefers_invoked_checkout_for_development_installs() { for expected in [ "INSTALL_SOURCE=${LESAVKA_INSTALL_SOURCE:-auto}", "resolve_source_checkout", "Using local source checkout", "set LESAVKA_INSTALL_SOURCE=ref", "LESAVKA_INSTALL_SOURCE=local requested", "unsupported LESAVKA_INSTALL_SOURCE", "source_revision", "+dirty", ] { assert!( CLIENT_INSTALL.contains(expected), "client installer should preserve local-source install marker {expected}" ); } assert!( CLIENT_INSTALL.find("resolve_source_checkout").unwrap() < CLIENT_INSTALL .find("cargo clean && cargo build --release") .unwrap(), "client installer should resolve source before building" ); }