use super::*;
use std::fs;
use std::time::Duration;
use tempfile::TempDir;
use tokio::time::sleep;
#[tokio::test]
async fn asset_folder_overlapping_output_dir_is_rejected() {
let root = TempDir::new().unwrap();
let result = Server::new(root.path())
.unwrap()
.with_asset_folder(root.path());
assert!(
result.is_err(),
"an asset folder equal to the output dir must be rejected"
);
}
#[tokio::test]
async fn asset_folder_overlapping_an_existing_asset_folder_is_rejected() {
let root = TempDir::new().unwrap();
let assets = TempDir::new().unwrap();
let result = Server::new(root.path())
.unwrap()
.with_asset_folder(assets.path())
.unwrap()
.with_asset_folder(assets.path());
assert!(
result.is_err(),
"registering the same asset folder twice must be rejected"
);
}
#[tokio::test]
async fn asset_folder_overlapping_a_source_folder_is_rejected_both_ways() {
let root = TempDir::new().unwrap();
let shared = TempDir::new().unwrap();
let via_asset_then_source = Server::new(root.path())
.unwrap()
.with_asset_folder(shared.path())
.unwrap()
.with_source_folder(shared.path());
assert!(
via_asset_then_source.is_err(),
"a source folder overlapping an already-registered asset folder must be rejected"
);
let via_source_then_asset = Server::new(root.path())
.unwrap()
.with_source_folder(shared.path())
.unwrap()
.with_asset_folder(shared.path());
assert!(
via_source_then_asset.is_err(),
"an asset folder overlapping an already-registered source folder must be rejected"
);
}
#[tokio::test]
async fn asset_folder_files_are_served_after_startup_build() {
let assets = TempDir::new().unwrap();
let out = TempDir::new().unwrap();
fs::write(assets.path().join("index.html"), "<html>hi</html>").unwrap();
fs::create_dir(assets.path().join("images")).unwrap();
fs::write(assets.path().join("images/logo.svg"), "<svg></svg>").unwrap();
let server = Server::new(out.path())
.unwrap()
.with_asset_folder(assets.path())
.unwrap();
let (port, handle) = server.run_ephemeral().await.unwrap();
sleep(Duration::from_millis(200)).await;
let index = fs::read_to_string(out.path().join("index.html")).unwrap();
assert_eq!(index, "<html>hi</html>");
let logo = fs::read_to_string(out.path().join("images/logo.svg")).unwrap();
assert_eq!(logo, "<svg></svg>");
let mut conn = tokio::net::TcpStream::connect(("127.0.0.1", port))
.await
.unwrap();
use tokio::io::{AsyncReadExt, AsyncWriteExt};
conn.write_all(b"GET /index.html HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n")
.await
.unwrap();
let mut response = Vec::new();
conn.read_to_end(&mut response).await.unwrap();
let response = String::from_utf8_lossy(&response);
assert!(response.contains("HTTP/1.1 200"), "got: {response}");
assert!(response.contains("<html>hi</html>"), "got: {response}");
handle.shutdown().await;
}
#[tokio::test]
async fn asset_folder_change_rebuilds_and_live_reloads() {
let assets = TempDir::new().unwrap();
let out = TempDir::new().unwrap();
fs::write(assets.path().join("index.html"), "v1").unwrap();
let server = Server::new(out.path())
.unwrap()
.with_live_reload()
.with_asset_folder(assets.path())
.unwrap();
let (_port, handle) = server.run_ephemeral().await.unwrap();
sleep(Duration::from_millis(800)).await;
assert_eq!(
fs::read_to_string(out.path().join("index.html")).unwrap(),
"v1"
);
fs::write(assets.path().join("index.html"), "v2").unwrap();
sleep(Duration::from_millis(1500)).await;
assert_eq!(
fs::read_to_string(out.path().join("index.html")).unwrap(),
"v2",
"editing the source asset must re-copy it into the output dir"
);
handle.shutdown().await;
}