//! The daemon binary must embed the real SPA bundle, never the placeholder. //! `build.rs` guarantees `web/dist` is populated before `include_dir!` runs. #![cfg(feature = "web")] use axum::body::to_bytes; use maestro_daemon::static_bundle::serve_index; #[tokio::test] async fn embedded_index_is_real_spa_not_placeholder() { let resp = serve_index(); let body = to_bytes(resp.into_body(), usize::MAX).await.unwrap(); let html = String::from_utf8(body.to_vec()).unwrap(); assert!( html.contains(r#"id="app""#), "served index is missing the SPA mount point; got:\n{html}" ); assert!( !html.contains("maestro is running"), "served index is the placeholder, not the built bundle" ); // Stronger signal than `id="app"` (which appears in both source and built // HTML): the vite build rewrites the entry to a hashed `/assets/index-` // bundle, whereas the un-built source references `/src/main.ts`. This catches // both an empty/placeholder embed and the staleness case. assert!( html.contains("/assets/index-"), "served index does not reference a vite-built hashed asset; got:\n{html}" ); }