actix_embed/
lib.rs

1//! # actix-embed
2//!
3//! Serve embedded file with actix.
4//!
5//! ```
6//! use actix_web::App;
7//! use actix_embed::Embed;
8//! use rust_embed::RustEmbed;
9//!
10//! #[derive(RustEmbed)]
11//! #[folder = "testdata/"]
12//! struct Assets;
13//!
14//! let app = App::new()
15//!     .service(Embed::new("/static", &Assets));
16//! ```
17#![warn(missing_docs, missing_debug_implementations)]
18#![allow(dead_code)]
19
20pub use fallback_handler::{DefaultFallbackHandler, FallbackHandler};
21pub use service::Embed;
22
23mod fallback_handler;
24mod service;
25
26#[cfg(test)]
27mod tests {
28    use actix_web::http::StatusCode;
29    use actix_web::test::TestRequest;
30    use actix_web::{test, App, HttpResponse};
31    use bytes::Bytes;
32    use rust_embed::RustEmbed;
33
34    use crate::Embed;
35
36    #[derive(RustEmbed)]
37    #[folder = "testdata/"]
38    struct Assets;
39
40    #[actix_web::test]
41    async fn test_basic() {
42        let srv = test::init_service(App::new().service(Embed::new("/", &Assets))).await;
43
44        let cases = [
45            ("/index.html", StatusCode::OK),
46            ("/assets/index.css", StatusCode::OK),
47            ("/assets/index.js", StatusCode::NOT_FOUND),
48        ];
49
50        for (path, status) in cases {
51            let req = TestRequest::get().uri(path).to_request();
52            let resp = test::call_service(&srv, req).await;
53            assert_eq!(resp.status(), status);
54        }
55    }
56
57    #[actix_web::test]
58    async fn test_fallback() {
59        let srv = test::init_service(App::new().service(
60            Embed::new("/", &Assets).fallback_handler(|_: &_| HttpResponse::Ok().body("not found")),
61        ))
62        .await;
63
64        let req = TestRequest::get().uri("/index.js").to_request();
65        let resp = test::call_service(&srv, req).await;
66        assert_eq!(resp.status(), StatusCode::OK);
67        let body = test::read_body(resp).await;
68        assert_eq!(body, Bytes::from("not found"));
69    }
70
71    #[actix_web::test]
72    async fn test_strict_slash() {
73        // not strict
74        {
75            let srv = test::init_service(
76                App::new().service(Embed::new("/", &Assets).strict_slash(false)),
77            )
78            .await;
79
80            let req = TestRequest::get().uri("/index.html/").to_request();
81            let resp = test::call_service(&srv, req).await;
82            assert_eq!(resp.status(), StatusCode::OK);
83        }
84
85        // strict
86        {
87            let srv =
88                test::init_service(App::new().service(Embed::new("/", &Assets).strict_slash(true)))
89                    .await;
90
91            let req = TestRequest::get().uri("/index.html/").to_request();
92            let resp = test::call_service(&srv, req).await;
93            assert_eq!(resp.status(), StatusCode::NOT_FOUND);
94        }
95    }
96
97    #[actix_web::test]
98    async fn test_index_file() {
99        // not index file
100        {
101            let srv = test::init_service(App::new().service(Embed::new("/", &Assets))).await;
102
103            let req = TestRequest::get().uri("/").to_request();
104            let resp = test::call_service(&srv, req).await;
105            assert_eq!(resp.status(), StatusCode::NOT_FOUND);
106        }
107
108        // has index file
109        {
110            let srv = test::init_service(
111                App::new().service(Embed::new("/", &Assets).index_file("/index.html")),
112            )
113            .await;
114
115            let req = TestRequest::get().uri("/").to_request();
116            let resp_a = test::call_service(&srv, req).await;
117            assert_eq!(resp_a.status(), StatusCode::OK);
118
119            let req = TestRequest::get().uri("/index.html").to_request();
120            let resp_b = test::call_service(&srv, req).await;
121            assert_eq!(resp_b.status(), StatusCode::OK);
122
123            assert_eq!(test::read_body(resp_a).await, test::read_body(resp_b).await);
124        }
125    }
126}