test: add functioning tests
This commit is contained in:
		
							parent
							
								
									c459800fca
								
							
						
					
					
						commit
						57f5404fde
					
				
							
								
								
									
										13
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										13
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							@ -362,18 +362,18 @@ checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "serde"
 | 
					name = "serde"
 | 
				
			||||||
version = "1.0.219"
 | 
					version = "1.0.218"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
 | 
					checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "serde_derive",
 | 
					 "serde_derive",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "serde_derive"
 | 
					name = "serde_derive"
 | 
				
			||||||
version = "1.0.219"
 | 
					version = "1.0.218"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
 | 
					checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "proc-macro2",
 | 
					 "proc-macro2",
 | 
				
			||||||
 "quote",
 | 
					 "quote",
 | 
				
			||||||
@ -403,7 +403,12 @@ version = "0.1.0"
 | 
				
			|||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "axum",
 | 
					 "axum",
 | 
				
			||||||
 "bytes",
 | 
					 "bytes",
 | 
				
			||||||
 | 
					 "flate2",
 | 
				
			||||||
 | 
					 "http-body-util",
 | 
				
			||||||
 "static-serve-macro",
 | 
					 "static-serve-macro",
 | 
				
			||||||
 | 
					 "tokio",
 | 
				
			||||||
 | 
					 "tower",
 | 
				
			||||||
 | 
					 "zstd",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
 | 
				
			|||||||
@ -14,5 +14,12 @@ static-serve-macro = { path = "../static-serve-macro", version = "0.1.0" }
 | 
				
			|||||||
axum = { version = "0.8", default-features = false }
 | 
					axum = { version = "0.8", default-features = false }
 | 
				
			||||||
bytes = "1.10"
 | 
					bytes = "1.10"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[dev-dependencies]
 | 
				
			||||||
 | 
					http-body-util = "0.1"
 | 
				
			||||||
 | 
					tokio = { version = "1.44", features = ["rt", "macros"] }
 | 
				
			||||||
 | 
					tower = { version = "0.5", features = ["util"] }
 | 
				
			||||||
 | 
					zstd = "0.13"
 | 
				
			||||||
 | 
					flate2 = "1.1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[lints]
 | 
					[lints]
 | 
				
			||||||
workspace = true
 | 
					workspace = true
 | 
				
			||||||
 | 
				
			|||||||
@ -127,66 +127,3 @@ where
 | 
				
			|||||||
        ),
 | 
					        ),
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[cfg(test)]
 | 
					 | 
				
			||||||
mod tests {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[test]
 | 
					 | 
				
			||||||
    fn router_created_with_test_routes_lit_str() {
 | 
					 | 
				
			||||||
        embed_assets!("test_assets/small", compress = false);
 | 
					 | 
				
			||||||
        let router: Router<()> = static_router();
 | 
					 | 
				
			||||||
        assert!(router.has_routes());
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[test]
 | 
					 | 
				
			||||||
    fn router_created_not_compressed_because_not_worthwhile() {
 | 
					 | 
				
			||||||
        embed_assets!("test_assets/small", compress = true);
 | 
					 | 
				
			||||||
        let router: Router<()> = static_router();
 | 
					 | 
				
			||||||
        assert!(router.has_routes());
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[test]
 | 
					 | 
				
			||||||
    fn router_created_compressed() {
 | 
					 | 
				
			||||||
        embed_assets!("test_assets/big", compress = true);
 | 
					 | 
				
			||||||
        let router: Router<()> = static_router();
 | 
					 | 
				
			||||||
        assert!(router.has_routes());
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[test]
 | 
					 | 
				
			||||||
    fn router_created_with_test_routes_ident() {
 | 
					 | 
				
			||||||
        embed_assets!(test_assets, compress = true);
 | 
					 | 
				
			||||||
        let router: Router<()> = static_router();
 | 
					 | 
				
			||||||
        assert!(router.has_routes());
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[test]
 | 
					 | 
				
			||||||
    fn router_created_ignore_dirs_one() {
 | 
					 | 
				
			||||||
        embed_assets!(test_assets, ignore_dirs = ["test_assets/big"]);
 | 
					 | 
				
			||||||
        let router: Router<()> = static_router();
 | 
					 | 
				
			||||||
        assert!(router.has_routes());
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[test]
 | 
					 | 
				
			||||||
    fn router_created_ignore_dirs_two() {
 | 
					 | 
				
			||||||
        embed_assets!(
 | 
					 | 
				
			||||||
            test_assets,
 | 
					 | 
				
			||||||
            ignore_dirs = ["test_assets/big", "test_assets/small"]
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
        let router: Router<()> = static_router();
 | 
					 | 
				
			||||||
        // all directories ignored, so router has no routes
 | 
					 | 
				
			||||||
        assert!(!router.has_routes());
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[test]
 | 
					 | 
				
			||||||
    fn router_created_ignore_dirs_with_defaults() {
 | 
					 | 
				
			||||||
        // TODO: actually create one of the default ignore directories
 | 
					 | 
				
			||||||
        // in `test_assets` to make sure this works
 | 
					 | 
				
			||||||
        embed_assets!(
 | 
					 | 
				
			||||||
            test_assets,
 | 
					 | 
				
			||||||
            ignore_dirs = ["test_assets/big"],
 | 
					 | 
				
			||||||
            use_default_ignore_dirs = true
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
        let router: Router<()> = static_router();
 | 
					 | 
				
			||||||
        assert!(router.has_routes());
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										342
									
								
								static-serve/tests/tests.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										342
									
								
								static-serve/tests/tests.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,342 @@
 | 
				
			|||||||
 | 
					//! Integration tests for static-serve and macro
 | 
				
			||||||
 | 
					use std::io::Read;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use axum::{
 | 
				
			||||||
 | 
					    body::Body,
 | 
				
			||||||
 | 
					    http::{
 | 
				
			||||||
 | 
					        header::{ACCEPT_ENCODING, CONTENT_ENCODING, IF_NONE_MATCH},
 | 
				
			||||||
 | 
					        HeaderValue, Request, Response, StatusCode,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    Router,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					use http_body_util::BodyExt;
 | 
				
			||||||
 | 
					use tower::ServiceExt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use static_serve_macro::embed_assets;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum Compression {
 | 
				
			||||||
 | 
					    Zstd,
 | 
				
			||||||
 | 
					    Gzip,
 | 
				
			||||||
 | 
					    Both,
 | 
				
			||||||
 | 
					    None,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async fn get_response(
 | 
				
			||||||
 | 
					    router: Router<()>,
 | 
				
			||||||
 | 
					    request: Request<axum::body::Body>,
 | 
				
			||||||
 | 
					) -> Response<axum::body::Body> {
 | 
				
			||||||
 | 
					    router
 | 
				
			||||||
 | 
					        .into_service()
 | 
				
			||||||
 | 
					        .oneshot(request)
 | 
				
			||||||
 | 
					        .await
 | 
				
			||||||
 | 
					        .expect("sending request")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn create_request(route: &str, compression: &Compression) -> Request<axum::body::Body> {
 | 
				
			||||||
 | 
					    let accept_encoding_header = match compression {
 | 
				
			||||||
 | 
					        Compression::Both => Some(HeaderValue::from_static("zstd, gzip")),
 | 
				
			||||||
 | 
					        Compression::Zstd => Some(HeaderValue::from_static("zstd")),
 | 
				
			||||||
 | 
					        Compression::Gzip => Some(HeaderValue::from_static("gzip")),
 | 
				
			||||||
 | 
					        Compression::None => None,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    match accept_encoding_header {
 | 
				
			||||||
 | 
					        Some(v) => Request::builder()
 | 
				
			||||||
 | 
					            .uri(route)
 | 
				
			||||||
 | 
					            .header(ACCEPT_ENCODING, v)
 | 
				
			||||||
 | 
					            .body(Body::empty())
 | 
				
			||||||
 | 
					            .unwrap(),
 | 
				
			||||||
 | 
					        None => Request::builder().uri(route).body(Body::empty()).unwrap(),
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn decompress_zstd(compressed_body: &[u8]) -> Vec<u8> {
 | 
				
			||||||
 | 
					    let mut decoder = zstd::Decoder::new(compressed_body).expect("failed to create decoder");
 | 
				
			||||||
 | 
					    let mut decompressed_body = Vec::new();
 | 
				
			||||||
 | 
					    std::io::copy(&mut decoder, &mut decompressed_body).expect("failed to decompress");
 | 
				
			||||||
 | 
					    decompressed_body
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn decompress_gzip(compressed_body: &[u8]) -> Vec<u8> {
 | 
				
			||||||
 | 
					    let mut decompressed_body = Vec::new();
 | 
				
			||||||
 | 
					    let mut decoder = flate2::bufread::GzDecoder::new(compressed_body);
 | 
				
			||||||
 | 
					    decoder
 | 
				
			||||||
 | 
					        .read_to_end(&mut decompressed_body)
 | 
				
			||||||
 | 
					        .expect("can't decode body");
 | 
				
			||||||
 | 
					    decompressed_body
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[tokio::test]
 | 
				
			||||||
 | 
					async fn router_created_with_lit_str() {
 | 
				
			||||||
 | 
					    embed_assets!("../static-serve/test_assets/small", compress = false);
 | 
				
			||||||
 | 
					    let router: Router<()> = static_router();
 | 
				
			||||||
 | 
					    assert!(router.has_routes());
 | 
				
			||||||
 | 
					    let request = create_request("/app.js", &Compression::None);
 | 
				
			||||||
 | 
					    let response = get_response(router, request).await;
 | 
				
			||||||
 | 
					    let (parts, body) = response.into_parts();
 | 
				
			||||||
 | 
					    assert!(parts.status.is_success());
 | 
				
			||||||
 | 
					    assert_eq!(
 | 
				
			||||||
 | 
					        parts.headers.get("content-type").unwrap(),
 | 
				
			||||||
 | 
					        "text/javascript"
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    assert!(parts.headers.contains_key("etag"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let collected_body_bytes = body.into_data_stream().collect().await.unwrap().to_bytes();
 | 
				
			||||||
 | 
					    let expected_body_bytes = include_bytes!("../../test_assets/small/app.js");
 | 
				
			||||||
 | 
					    assert_eq!(*collected_body_bytes, *expected_body_bytes);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[tokio::test]
 | 
				
			||||||
 | 
					async fn router_created_uncompressed_because_not_worthwhile() {
 | 
				
			||||||
 | 
					    embed_assets!("../static-serve/test_assets/small", compress = true);
 | 
				
			||||||
 | 
					    let router: Router<()> = static_router();
 | 
				
			||||||
 | 
					    assert!(router.has_routes());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let request = create_request("/app.js", &Compression::Zstd);
 | 
				
			||||||
 | 
					    let response = get_response(router, request).await;
 | 
				
			||||||
 | 
					    let (parts, body) = response.into_parts();
 | 
				
			||||||
 | 
					    assert!(parts.status.is_success());
 | 
				
			||||||
 | 
					    assert_eq!(
 | 
				
			||||||
 | 
					        parts.headers.get("content-type").unwrap(),
 | 
				
			||||||
 | 
					        "text/javascript"
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    assert!(parts.headers.contains_key("etag"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let collected_body_bytes = body.into_data_stream().collect().await.unwrap().to_bytes();
 | 
				
			||||||
 | 
					    // Response should not be compressed since the benefit is insignificant
 | 
				
			||||||
 | 
					    let expected_body_bytes = include_bytes!("../../test_assets/small/app.js");
 | 
				
			||||||
 | 
					    assert_eq!(*collected_body_bytes, *expected_body_bytes);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[tokio::test]
 | 
				
			||||||
 | 
					async fn router_created_compressed_zstd_only() {
 | 
				
			||||||
 | 
					    embed_assets!("../static-serve/test_assets/big", compress = true);
 | 
				
			||||||
 | 
					    let router: Router<()> = static_router();
 | 
				
			||||||
 | 
					    assert!(router.has_routes());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let request = create_request("/app.js", &Compression::Zstd);
 | 
				
			||||||
 | 
					    let response = get_response(router, request).await;
 | 
				
			||||||
 | 
					    let (parts, body) = response.into_parts();
 | 
				
			||||||
 | 
					    assert!(parts.status.is_success());
 | 
				
			||||||
 | 
					    assert_eq!(
 | 
				
			||||||
 | 
					        parts.headers.get(CONTENT_ENCODING),
 | 
				
			||||||
 | 
					        Some(&HeaderValue::from_str("zstd").unwrap())
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    assert_eq!(
 | 
				
			||||||
 | 
					        parts.headers.get("content-type").unwrap(),
 | 
				
			||||||
 | 
					        "text/javascript"
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    assert!(parts.headers.contains_key("etag"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let collected_body_bytes = body.into_data_stream().collect().await.unwrap().to_bytes();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Decompress the response body
 | 
				
			||||||
 | 
					    let decompressed_body = decompress_zstd(&collected_body_bytes);
 | 
				
			||||||
 | 
					    assert_eq!(
 | 
				
			||||||
 | 
					        decompressed_body,
 | 
				
			||||||
 | 
					        include_bytes!("../../test_assets/big/app.js")
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Expect the compressed version
 | 
				
			||||||
 | 
					    let expected_body_bytes = include_bytes!("../../test_assets/dist/app.js.zst");
 | 
				
			||||||
 | 
					    assert_eq!(*collected_body_bytes, *expected_body_bytes);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[tokio::test]
 | 
				
			||||||
 | 
					async fn router_created_compressed_gzip_only() {
 | 
				
			||||||
 | 
					    embed_assets!("../static-serve/test_assets/big", compress = true);
 | 
				
			||||||
 | 
					    let router: Router<()> = static_router();
 | 
				
			||||||
 | 
					    assert!(router.has_routes());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let request = create_request("/app.js", &Compression::Gzip);
 | 
				
			||||||
 | 
					    let response = get_response(router, request).await;
 | 
				
			||||||
 | 
					    let (parts, body) = response.into_parts();
 | 
				
			||||||
 | 
					    assert!(parts.status.is_success());
 | 
				
			||||||
 | 
					    assert_eq!(
 | 
				
			||||||
 | 
					        parts.headers.get(CONTENT_ENCODING),
 | 
				
			||||||
 | 
					        Some(&HeaderValue::from_str("gzip").unwrap())
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    assert_eq!(
 | 
				
			||||||
 | 
					        parts.headers.get("content-type").unwrap(),
 | 
				
			||||||
 | 
					        "text/javascript"
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    assert!(parts.headers.contains_key("etag"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let collected_body_bytes = body.into_data_stream().collect().await.unwrap().to_bytes();
 | 
				
			||||||
 | 
					    let decompressed_body = decompress_gzip(&collected_body_bytes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert_eq!(
 | 
				
			||||||
 | 
					        decompressed_body,
 | 
				
			||||||
 | 
					        include_bytes!("../../test_assets/big/app.js"),
 | 
				
			||||||
 | 
					        "decompressed body is not as expected"
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Expect the compressed version
 | 
				
			||||||
 | 
					    let expected_body_bytes = include_bytes!("../../test_assets/dist/app.js.gz");
 | 
				
			||||||
 | 
					    assert_eq!(*collected_body_bytes, *expected_body_bytes);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[tokio::test]
 | 
				
			||||||
 | 
					async fn router_created_compressed_zstd_or_gzip_accepted() {
 | 
				
			||||||
 | 
					    embed_assets!("../static-serve/test_assets/big", compress = true);
 | 
				
			||||||
 | 
					    let router: Router<()> = static_router();
 | 
				
			||||||
 | 
					    assert!(router.has_routes());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let request = create_request("/app.js", &Compression::Both);
 | 
				
			||||||
 | 
					    let response = get_response(router, request).await;
 | 
				
			||||||
 | 
					    let (parts, body) = response.into_parts();
 | 
				
			||||||
 | 
					    assert!(parts.status.is_success());
 | 
				
			||||||
 | 
					    assert_eq!(
 | 
				
			||||||
 | 
					        parts.headers.get(CONTENT_ENCODING),
 | 
				
			||||||
 | 
					        Some(&HeaderValue::from_str("zstd").unwrap())
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    assert_eq!(
 | 
				
			||||||
 | 
					        parts.headers.get("content-type").unwrap(),
 | 
				
			||||||
 | 
					        "text/javascript"
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    assert!(parts.headers.contains_key("etag"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let collected_body_bytes = body.into_data_stream().collect().await.unwrap().to_bytes();
 | 
				
			||||||
 | 
					    let decompressed_body = decompress_zstd(&collected_body_bytes);
 | 
				
			||||||
 | 
					    assert_eq!(
 | 
				
			||||||
 | 
					        decompressed_body,
 | 
				
			||||||
 | 
					        include_bytes!("../../test_assets/big/app.js")
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Expect the compressed version
 | 
				
			||||||
 | 
					    let expected_body_bytes = include_bytes!("../../test_assets/dist/app.js.zst");
 | 
				
			||||||
 | 
					    assert_eq!(*collected_body_bytes, *expected_body_bytes);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[tokio::test]
 | 
				
			||||||
 | 
					async fn router_created_ignore_dirs_one() {
 | 
				
			||||||
 | 
					    embed_assets!("../static-serve/test_assets", ignore_dirs = ["dist"]);
 | 
				
			||||||
 | 
					    let router: Router<()> = static_router();
 | 
				
			||||||
 | 
					    assert!(router.has_routes());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let request = create_request("/small/app.js", &Compression::None);
 | 
				
			||||||
 | 
					    let response = get_response(router, request).await;
 | 
				
			||||||
 | 
					    let (parts, body) = response.into_parts();
 | 
				
			||||||
 | 
					    assert!(parts.status.is_success());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let collected_body_bytes = body.into_data_stream().collect().await.unwrap().to_bytes();
 | 
				
			||||||
 | 
					    let expected_body_bytes = include_bytes!("../../test_assets/small/app.js");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert_eq!(
 | 
				
			||||||
 | 
					        parts.headers.get("content-type").unwrap(),
 | 
				
			||||||
 | 
					        "text/javascript"
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    assert!(parts.headers.contains_key("etag"));
 | 
				
			||||||
 | 
					    assert_eq!(*collected_body_bytes, *expected_body_bytes);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[tokio::test]
 | 
				
			||||||
 | 
					async fn router_created_ignore_dirs_three() {
 | 
				
			||||||
 | 
					    embed_assets!(
 | 
				
			||||||
 | 
					        "../static-serve/test_assets",
 | 
				
			||||||
 | 
					        ignore_dirs = ["big", "small", "dist"]
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    let router: Router<()> = static_router();
 | 
				
			||||||
 | 
					    // all directories ignored, so router has no routes
 | 
				
			||||||
 | 
					    assert!(!router.has_routes());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let request = create_request("/app.js", &Compression::None);
 | 
				
			||||||
 | 
					    let response = get_response(router, request).await;
 | 
				
			||||||
 | 
					    let (parts, body) = response.into_parts();
 | 
				
			||||||
 | 
					    let collected_body_bytes = body.into_data_stream().collect().await.unwrap().to_bytes();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Expect a 404 Not Found with empty body
 | 
				
			||||||
 | 
					    assert_eq!(parts.status, StatusCode::NOT_FOUND);
 | 
				
			||||||
 | 
					    assert!(collected_body_bytes.is_empty());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[tokio::test]
 | 
				
			||||||
 | 
					async fn handles_conditional_requests_same_etag() {
 | 
				
			||||||
 | 
					    embed_assets!("../static-serve/test_assets/big", compress = true);
 | 
				
			||||||
 | 
					    let router: Router<()> = static_router();
 | 
				
			||||||
 | 
					    assert!(router.has_routes());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let request = create_request("/app.js", &Compression::Zstd);
 | 
				
			||||||
 | 
					    let response = get_response(router.clone(), request).await;
 | 
				
			||||||
 | 
					    let (parts, body) = response.into_parts();
 | 
				
			||||||
 | 
					    assert!(parts.status.is_success());
 | 
				
			||||||
 | 
					    assert_eq!(
 | 
				
			||||||
 | 
					        parts.headers.get(CONTENT_ENCODING),
 | 
				
			||||||
 | 
					        Some(&HeaderValue::from_str("zstd").unwrap())
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    assert_eq!(
 | 
				
			||||||
 | 
					        parts.headers.get("content-type").unwrap(),
 | 
				
			||||||
 | 
					        "text/javascript"
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    let etag = parts
 | 
				
			||||||
 | 
					        .headers
 | 
				
			||||||
 | 
					        .get("etag")
 | 
				
			||||||
 | 
					        .expect("no etag header when there should be one!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let collected_body_bytes = body.into_data_stream().collect().await.unwrap().to_bytes();
 | 
				
			||||||
 | 
					    let decompressed_body = decompress_zstd(&collected_body_bytes);
 | 
				
			||||||
 | 
					    assert_eq!(
 | 
				
			||||||
 | 
					        decompressed_body,
 | 
				
			||||||
 | 
					        include_bytes!("../../test_assets/big/app.js")
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Expect the compressed version
 | 
				
			||||||
 | 
					    let expected_body_bytes = include_bytes!("../../test_assets/dist/app.js.zst");
 | 
				
			||||||
 | 
					    assert_eq!(*collected_body_bytes, *expected_body_bytes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let request = Request::builder()
 | 
				
			||||||
 | 
					        .uri("/app.js")
 | 
				
			||||||
 | 
					        .header(IF_NONE_MATCH, etag)
 | 
				
			||||||
 | 
					        .header(ACCEPT_ENCODING, "zstd")
 | 
				
			||||||
 | 
					        .body(Body::empty())
 | 
				
			||||||
 | 
					        .unwrap();
 | 
				
			||||||
 | 
					    let response = get_response(router, request).await;
 | 
				
			||||||
 | 
					    let (parts, body) = response.into_parts();
 | 
				
			||||||
 | 
					    assert_eq!(parts.status, StatusCode::NOT_MODIFIED);
 | 
				
			||||||
 | 
					    assert_eq!(
 | 
				
			||||||
 | 
					        parts
 | 
				
			||||||
 | 
					            .headers
 | 
				
			||||||
 | 
					            .get("content-length")
 | 
				
			||||||
 | 
					            .expect("no content-length header!"),
 | 
				
			||||||
 | 
					        "0"
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    let collected_body_bytes = body.into_data_stream().collect().await.unwrap().to_bytes();
 | 
				
			||||||
 | 
					    assert!(collected_body_bytes.is_empty());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[tokio::test]
 | 
				
			||||||
 | 
					async fn handles_conditional_requests_different_etag() {
 | 
				
			||||||
 | 
					    embed_assets!("../static-serve/test_assets/big", compress = true);
 | 
				
			||||||
 | 
					    let router: Router<()> = static_router();
 | 
				
			||||||
 | 
					    assert!(router.has_routes());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let request = Request::builder()
 | 
				
			||||||
 | 
					        .uri("/app.js")
 | 
				
			||||||
 | 
					        .header(IF_NONE_MATCH, "n0t4r34l3t4g")
 | 
				
			||||||
 | 
					        .header(ACCEPT_ENCODING, "zstd")
 | 
				
			||||||
 | 
					        .body(Body::empty())
 | 
				
			||||||
 | 
					        .unwrap();
 | 
				
			||||||
 | 
					    let response = get_response(router, request).await;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let (parts, body) = response.into_parts();
 | 
				
			||||||
 | 
					    assert_eq!(parts.status, StatusCode::OK);
 | 
				
			||||||
 | 
					    assert_ne!(
 | 
				
			||||||
 | 
					        parts
 | 
				
			||||||
 | 
					            .headers
 | 
				
			||||||
 | 
					            .get("content-length")
 | 
				
			||||||
 | 
					            .expect("no content-length header!"),
 | 
				
			||||||
 | 
					        "0",
 | 
				
			||||||
 | 
					        "content length is unexpectedly zero!"
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let collected_body_bytes = body.into_data_stream().collect().await.unwrap().to_bytes();
 | 
				
			||||||
 | 
					    assert!(!collected_body_bytes.is_empty());
 | 
				
			||||||
 | 
					    let decompressed_body = decompress_zstd(&collected_body_bytes);
 | 
				
			||||||
 | 
					    assert_eq!(
 | 
				
			||||||
 | 
					        decompressed_body,
 | 
				
			||||||
 | 
					        include_bytes!("../../test_assets/big/app.js")
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Expect the compressed version
 | 
				
			||||||
 | 
					    let expected_body_bytes = include_bytes!("../../test_assets/dist/app.js.zst");
 | 
				
			||||||
 | 
					    assert_eq!(*collected_body_bytes, *expected_body_bytes);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										20
									
								
								test_assets/big/app.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								test_assets/big/app.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					console.log("Hello, world!");
 | 
				
			||||||
 | 
					console.log("Hello, world!");
 | 
				
			||||||
 | 
					console.log("Hello, world!");
 | 
				
			||||||
 | 
					console.log("Hello, world!");
 | 
				
			||||||
 | 
					console.log("Hello, world!");
 | 
				
			||||||
 | 
					console.log("Hello, world!");
 | 
				
			||||||
 | 
					console.log("Hello, world!");
 | 
				
			||||||
 | 
					console.log("Hello, world!");
 | 
				
			||||||
 | 
					console.log("Hello, world!");
 | 
				
			||||||
 | 
					console.log("Hello, world!");
 | 
				
			||||||
 | 
					console.log("Hello, world!");
 | 
				
			||||||
 | 
					console.log("Hello, world!");
 | 
				
			||||||
 | 
					console.log("Hello, world!");
 | 
				
			||||||
 | 
					console.log("Hello, world!");
 | 
				
			||||||
 | 
					console.log("Hello, world!");
 | 
				
			||||||
 | 
					console.log("Hello, world!");
 | 
				
			||||||
 | 
					console.log("Hello, world!");
 | 
				
			||||||
 | 
					console.log("Hello, world!");
 | 
				
			||||||
 | 
					console.log("Hello, world!");
 | 
				
			||||||
 | 
					console.log("Hello, world!");
 | 
				
			||||||
							
								
								
									
										50
									
								
								test_assets/big/styles.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								test_assets/big/styles.css
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,50 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					body {
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    background:             black       ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					body {
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    background:             black       ;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					body {
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    background:             black       ;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					body {
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    background:             black       ;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					body {
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    background:             black       ;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								test_assets/dist/app.js.gz
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test_assets/dist/app.js.gz
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test_assets/dist/app.js.zst
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test_assets/dist/app.js.zst
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										1
									
								
								test_assets/dist/ignore_me_plz.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								test_assets/dist/ignore_me_plz.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					This file should only get included and served when the default ignore list is disabled.
 | 
				
			||||||
							
								
								
									
										1
									
								
								test_assets/small/app.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								test_assets/small/app.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					console.log("Hello, world!");
 | 
				
			||||||
							
								
								
									
										1
									
								
								test_assets/small/styles.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								test_assets/small/styles.css
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					body { background: black; }
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user