From c395edca424dbec71f25532e9f945adf6a1b8e91 Mon Sep 17 00:00:00 2001 From: Dave Date: Mon, 23 Feb 2026 22:24:29 +0000 Subject: [PATCH] story-kit: merge 107_story_test_coverage_http_assets_rs_to_85 --- Cargo.lock | 153 +++++++++++++++++++++++++++----------- Cargo.toml | 2 +- server/src/http/assets.rs | 47 ++++++++++-- 3 files changed, 150 insertions(+), 52 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 422c833..e133310 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -45,7 +45,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.116", ] [[package]] @@ -56,7 +56,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.116", ] [[package]] @@ -136,6 +136,12 @@ version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +[[package]] +name = "bytes" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" + [[package]] name = "bytes" version = "1.11.1" @@ -207,7 +213,7 @@ version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" dependencies = [ - "bytes", + "bytes 1.11.1", "memchr", ] @@ -311,7 +317,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn", + "syn 2.0.116", ] [[package]] @@ -322,7 +328,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", - "syn", + "syn 2.0.116", ] [[package]] @@ -350,7 +356,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn", + "syn 2.0.116", "unicode-xid", ] @@ -372,7 +378,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.116", ] [[package]] @@ -544,7 +550,7 @@ checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.116", ] [[package]] @@ -576,6 +582,18 @@ dependencies = [ "slab", ] +[[package]] +name = "futures_codec" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce54d63f8b0c75023ed920d46fd71d0cbbb830b0ee012726b5b4f506fb6dea5b" +dependencies = [ + "bytes 0.5.6", + "futures", + "memchr", + "pin-project", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -646,7 +664,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" dependencies = [ "atomic-waker", - "bytes", + "bytes 1.11.1", "fnv", "futures-core", "futures-sink", @@ -680,7 +698,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb" dependencies = [ "base64", - "bytes", + "bytes 1.11.1", "headers-core", "http", "httpdate", @@ -721,7 +739,7 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" dependencies = [ - "bytes", + "bytes 1.11.1", "itoa", ] @@ -731,7 +749,7 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ - "bytes", + "bytes 1.11.1", "http", ] @@ -741,7 +759,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ - "bytes", + "bytes 1.11.1", "futures-core", "http", "http-body", @@ -767,7 +785,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" dependencies = [ "atomic-waker", - "bytes", + "bytes 1.11.1", "futures-channel", "futures-core", "h2", @@ -806,7 +824,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ "base64", - "bytes", + "bytes 1.11.1", "futures-channel", "futures-util", "http", @@ -1200,7 +1218,7 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b" dependencies = [ - "bytes", + "bytes 1.11.1", "encoding_rs", "futures-util", "http", @@ -1323,6 +1341,26 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +[[package]] +name = "pin-project" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ef0f924a5ee7ea9cbcea77529dba45f8a9ba9f622419fe3386ca581a3ae9d5a" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "851c8d0ce9bebe43790dedfc86614c23494ac9f423dd618d3a61fc693eafe61e" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "pin-project-lite" version = "0.2.16" @@ -1342,7 +1380,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f977080932c87287147dca052951c3e2696f8759863f6b4e4c0c9ffe7a4cc8b" dependencies = [ "base64", - "bytes", + "bytes 1.11.1", "futures-util", "headers", "http", @@ -1364,6 +1402,7 @@ dependencies = [ "serde_urlencoded", "serde_yaml", "smallvec", + "sse-codec", "sync_wrapper", "tempfile", "thiserror 2.0.18", @@ -1384,7 +1423,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn", + "syn 2.0.116", ] [[package]] @@ -1394,7 +1433,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ccbcc395bf4dd03df1da32da351b6b6732e4074ce27ddec315650e52a2be44c" dependencies = [ "base64", - "bytes", + "bytes 1.11.1", "derive_more", "futures-util", "indexmap", @@ -1427,7 +1466,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn", + "syn 2.0.116", "thiserror 2.0.18", ] @@ -1477,7 +1516,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn", + "syn 2.0.116", ] [[package]] @@ -1514,7 +1553,7 @@ version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" dependencies = [ - "bytes", + "bytes 1.11.1", "cfg_aliases 0.2.1", "pin-project-lite", "quinn-proto", @@ -1535,7 +1574,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" dependencies = [ "aws-lc-rs", - "bytes", + "bytes 1.11.1", "getrandom 0.3.4", "lru-slab", "rand", @@ -1653,7 +1692,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801" dependencies = [ "base64", - "bytes", + "bytes 1.11.1", "encoding_rs", "futures-core", "futures-util", @@ -1732,7 +1771,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn", + "syn 2.0.116", "walkdir", ] @@ -1941,7 +1980,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.116", ] [[package]] @@ -2074,6 +2113,18 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "sse-codec" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84a59f811350c44b4a037aabeb72dc6a9591fc22aa95a036db9a96297c58085a" +dependencies = [ + "bytes 0.5.6", + "futures-io", + "futures_codec", + "memchr", +] + [[package]] name = "stable_deref_trait" version = "1.2.1" @@ -2086,7 +2137,7 @@ version = "0.1.0" dependencies = [ "async-stream", "async-trait", - "bytes", + "bytes 1.11.1", "chrono", "eventsource-stream", "futures", @@ -2131,6 +2182,17 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.116" @@ -2159,7 +2221,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.116", ] [[package]] @@ -2222,7 +2284,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.116", ] [[package]] @@ -2233,7 +2295,7 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.116", ] [[package]] @@ -2267,7 +2329,7 @@ version = "1.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" dependencies = [ - "bytes", + "bytes 1.11.1", "libc", "mio", "pin-project-lite", @@ -2284,7 +2346,7 @@ checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.116", ] [[package]] @@ -2326,8 +2388,9 @@ version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" dependencies = [ - "bytes", + "bytes 1.11.1", "futures-core", + "futures-io", "futures-sink", "pin-project-lite", "tokio", @@ -2415,7 +2478,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ "bitflags 2.11.0", - "bytes", + "bytes 1.11.1", "futures-util", "http", "http-body", @@ -2457,7 +2520,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.116", ] [[package]] @@ -2481,7 +2544,7 @@ version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eadc29d668c91fcc564941132e17b28a7ceb2f3ebf0b9dae3e03fd7a6748eb0d" dependencies = [ - "bytes", + "bytes 1.11.1", "data-encoding", "http", "httparse", @@ -2683,7 +2746,7 @@ dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn", + "syn 2.0.116", "wasm-bindgen-shared", ] @@ -2882,7 +2945,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.116", ] [[package]] @@ -2893,7 +2956,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.116", ] [[package]] @@ -3244,7 +3307,7 @@ dependencies = [ "heck", "indexmap", "prettyplease", - "syn", + "syn 2.0.116", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -3260,7 +3323,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn", + "syn 2.0.116", "wit-bindgen-core", "wit-bindgen-rust", ] @@ -3327,7 +3390,7 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.116", "synstructure", ] @@ -3348,7 +3411,7 @@ checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.116", ] [[package]] @@ -3368,7 +3431,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.116", "synstructure", ] @@ -3408,7 +3471,7 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.116", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index d6f5a1c..78c663c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ homedir = "0.3.6" ignore = "0.4.25" mime_guess = "2" notify = "8.2.0" -poem = { version = "3", features = ["websocket"] } +poem = { version = "3", features = ["websocket", "test"] } poem-openapi = { version = "5", features = ["swagger-ui"] } portable-pty = "0.9.0" reqwest = { version = "0.13.2", features = ["json", "stream"] } diff --git a/server/src/http/assets.rs b/server/src/http/assets.rs index b35d638..8bccee7 100644 --- a/server/src/http/assets.rs +++ b/server/src/http/assets.rs @@ -77,10 +77,10 @@ mod tests { // In release builds (with embedded dist/) this returns 200. // In debug builds without a built frontend dist/ it returns 404. let response = serve_embedded("__nonexistent_spa_route__.html"); + let status = response.status(); assert!( - response.status() == StatusCode::OK || response.status() == StatusCode::NOT_FOUND, - "unexpected status: {}", - response.status() + status == StatusCode::OK || status == StatusCode::NOT_FOUND, + "unexpected status: {status}", ); } @@ -95,10 +95,10 @@ mod tests { fn serve_embedded_does_not_panic_on_empty_path() { // Empty path normalises to index.html; OK in release, 404 in debug without dist/ let response = serve_embedded(""); + let status = response.status(); assert!( - response.status() == StatusCode::OK || response.status() == StatusCode::NOT_FOUND, - "unexpected status: {}", - response.status() + status == StatusCode::OK || status == StatusCode::NOT_FOUND, + "unexpected status: {status}", ); } @@ -110,4 +110,39 @@ mod tests { let _files: Vec<_> = EmbeddedAssets::iter().collect(); // No assertion needed – the test passes as long as it compiles and does not panic. } + + #[tokio::test] + async fn embedded_index_handler_returns_ok_or_not_found() { + // Route the handler through TestClient; index.html is the SPA entry point. + let app = poem::Route::new().at("/", poem::get(embedded_index)); + let cli = poem::test::TestClient::new(app); + let resp = cli.get("/").send().await; + let status = resp.0.status(); + assert!( + status == StatusCode::OK || status == StatusCode::NOT_FOUND, + "unexpected status: {status}", + ); + } + + #[tokio::test] + async fn embedded_file_handler_with_path_returns_ok_or_not_found() { + // Non-asset paths fall back to index.html (SPA routing) or 404. + let app = poem::Route::new().at("/*path", poem::get(embedded_file)); + let cli = poem::test::TestClient::new(app); + let resp = cli.get("/__spa_route__").send().await; + let status = resp.0.status(); + assert!( + status == StatusCode::OK || status == StatusCode::NOT_FOUND, + "unexpected status: {status}", + ); + } + + #[tokio::test] + async fn embedded_asset_handler_missing_file_returns_not_found() { + // The assets/ prefix disables SPA fallback; missing files must return 404. + let app = poem::Route::new().at("/assets/*path", poem::get(embedded_asset)); + let cli = poem::test::TestClient::new(app); + let resp = cli.get("/assets/__nonexistent__.js").send().await; + assert_eq!(resp.0.status(), StatusCode::NOT_FOUND); + } }