use actix_web::{HttpResponse, Responder, http::header};
const FAVICON: &[u8] = include_bytes!("../../../static/favicon.ico");
const CACHE_CONTROL: &str = "public, max-age=86400";
pub(crate) async fn get_favicon() -> impl Responder {
HttpResponse::Ok()
.content_type("image/x-icon")
.insert_header((header::CACHE_CONTROL, CACHE_CONTROL))
.body(FAVICON)
}
#[cfg(test)]
mod tests {
use super::*;
use actix_web::body::MessageBody;
use actix_web::http::StatusCode;
#[actix_web::test]
async fn test_the_favicon_is_served_from_the_binary() {
let response = get_favicon().await;
let response =
response.respond_to(&actix_web::test::TestRequest::default().to_http_request());
assert_eq!(response.status(), StatusCode::OK);
assert_eq!(
response
.headers()
.get(header::CONTENT_TYPE)
.and_then(|value| value.to_str().ok()),
Some("image/x-icon")
);
match response.into_body().try_into_bytes() {
Ok(bytes) => {
assert!(!bytes.is_empty(), "the icon must carry bytes");
assert_eq!(bytes.len(), FAVICON.len());
}
Err(_) => panic!("the icon body must be readable in one piece"),
}
}
#[actix_web::test]
async fn test_the_favicon_does_not_depend_on_the_working_directory() {
let elsewhere = std::env::temp_dir();
let original = match std::env::current_dir() {
Ok(original) => original,
Err(error) => panic!("the working directory must be readable: {error}"),
};
if std::env::set_current_dir(&elsewhere).is_err() {
return;
}
let response = get_favicon().await;
let response =
response.respond_to(&actix_web::test::TestRequest::default().to_http_request());
let status = response.status();
let _ = std::env::set_current_dir(original);
assert_eq!(
status,
StatusCode::OK,
"the icon must serve from a directory that has no static/ in it"
);
}
}