/* * Copyright (C) 2026 Mateusz GruszczyƄski @linuxiarz.pl * Source-Available Code / Dual-Licensed. * * Free for non-commercial and evaluation use under terms of BSL/GPLv3. * Commercial or production use requires a valid paid license. * See LICENSE file in repository root for details. */ use super::{ResponseHeaderPolicy, apply_response_headers, response_header_policy}; use axum::http::{HeaderMap, HeaderValue, header}; #[test] fn classifies_assets_and_icons_as_static_assets() { for path in [ "/assets/app.js", "/assets", "/favicon.ico", "/icons/favicon.svg", "/icons/missing.svg", ] { assert_eq!( response_header_policy(path), ResponseHeaderPolicy::StaticAsset ); } } #[test] fn classifies_file_routes_as_files() { for path in ["/f", "/f/token/image.png"] { assert_eq!(response_header_policy(path), ResponseHeaderPolicy::File); } } #[test] fn classifies_other_routes_as_application() { for path in [ "/", "/api/auth/me", "/static/missing.css", "/files/legacy/image.png", "/unknown", ] { assert_eq!( response_header_policy(path), ResponseHeaderPolicy::Application ); } } #[test] fn static_asset_policy_only_adds_nosniff() { let mut headers = HeaderMap::new(); headers.insert( header::CACHE_CONTROL, HeaderValue::from_static("public, max-age=3600"), ); apply_response_headers(ResponseHeaderPolicy::StaticAsset, &mut headers); assert_eq!(headers.len(), 2); assert_eq!(headers[header::X_CONTENT_TYPE_OPTIONS], "nosniff"); assert!(!headers.contains_key("x-frame-options")); assert!(!headers.contains_key("cross-origin-opener-policy")); assert!(!headers.contains_key("cross-origin-resource-policy")); assert!(!headers.contains_key("referrer-policy")); assert!(!headers.contains_key("permissions-policy")); } #[test] fn file_policy_keeps_file_headers_without_document_policies() { let mut headers = HeaderMap::new(); headers.insert( "content-security-policy", HeaderValue::from_static("default-src 'none'; sandbox"), ); headers.insert( header::CONTENT_DISPOSITION, HeaderValue::from_static("attachment; filename=\"manual.pdf\""), ); apply_response_headers(ResponseHeaderPolicy::File, &mut headers); assert_eq!(headers[header::X_CONTENT_TYPE_OPTIONS], "nosniff"); assert_eq!( headers["content-security-policy"], "default-src 'none'; sandbox" ); assert!(headers.contains_key(header::CONTENT_DISPOSITION)); assert!(!headers.contains_key("x-frame-options")); assert!(!headers.contains_key("cross-origin-opener-policy")); assert!(!headers.contains_key("cross-origin-resource-policy")); assert!(!headers.contains_key("referrer-policy")); assert!(!headers.contains_key("permissions-policy")); } #[test] fn application_policy_preserves_handler_headers() { let mut headers = HeaderMap::new(); headers.insert( "content-security-policy", HeaderValue::from_static("default-src 'none'; sandbox"), ); apply_response_headers(ResponseHeaderPolicy::Application, &mut headers); assert_eq!( headers["content-security-policy"], "default-src 'none'; sandbox" ); assert_eq!(headers["x-frame-options"], "DENY"); assert_eq!(headers["cross-origin-opener-policy"], "same-origin"); assert_eq!(headers["cross-origin-resource-policy"], "same-origin"); assert_eq!(headers[header::X_CONTENT_TYPE_OPTIONS], "nosniff"); assert_eq!( headers["referrer-policy"], "strict-origin-when-cross-origin" ); assert!(headers.contains_key("permissions-policy")); }