use rs_express::{testing, App, Error, NextFunction, Request, Response, Router}; use hyper::{http::StatusCode, Body, Method}; #[tokio::test] async fn test_app_testing() { let mut app: App<()> = App::new(); app.use_ok( |req: &mut Request<()>, res: &mut Response, _next: &mut NextFunction| { let header_value = req.header("x-custom-header").unwrap(); res.set_header("x-custom-header", header_value.as_str()); res.end(); }, ); let mut test_app = testing(app); let request = hyper::Request::builder() .header("x-custom-header", "rs_express") .body(Body::from("body")) .expect("Request builder failed"); let response = test_app.request(request).await; assert_eq!(response.status(), StatusCode::OK); assert_eq!( response .headers() .get("x-custom-header") .expect("x-custom-header header value") .to_str() .unwrap(), "rs_express" ); } #[tokio::test] #[should_panic] async fn test_next_method_not_called() { let mut app: App<()> = App::new(); app.use_ok( |req: &mut Request<()>, res: &mut Response, _next: &mut NextFunction| { let header_value = req.header("x-custom-header").unwrap(); res.set_header("x-custom-header", header_value.as_str()); }, ); let mut test_app = testing(app); let request = hyper::Request::builder() .header("x-custom-header", "rs_express") .body(Body::from("body")) .expect("Request builder failed"); test_app.request(request).await; } #[tokio::test] async fn test_no_middleware_404() { let app: App<()> = App::new(); let mut test_app = testing(app); let request = hyper::Request::builder() .body(Body::from("body")) .expect("Request builder failed"); let response = test_app.request(request).await; assert_eq!(response.status(), StatusCode::NOT_FOUND); } #[tokio::test] async fn test_use_err() { struct Locals { error: String, } let locals = Locals { error: String::from("my-error"), }; let mut app: App = App::new(); app.set_locals(locals); app.use_ok( |req: &mut Request, _res: &mut Response, next: &mut NextFunction| { next(Err(req.app_locals().unwrap().error.clone())); }, ) .use_err( |error: &Error, _req: &mut Request, res: &mut Response, next: &mut NextFunction| { res.set_header("x-error-message", &error); next(Err(String::from("updated-error"))); }, ) .use_err( |error: &Error, _req: &mut Request, res: &mut Response, _next: &mut NextFunction| { res.set_header("x-error-message2", &error); res.end(); }, ); let mut test_app = testing(app); let request = hyper::Request::builder() .body(Body::from("body")) .expect("Request builder failed"); let response = test_app.request(request).await; assert_eq!(response.status(), StatusCode::INTERNAL_SERVER_ERROR); assert_eq!( response .headers() .get("x-error-message") .expect("x-error-message header value") .to_str() .unwrap(), "my-error" ); assert_eq!( response .headers() .get("x-error-message2") .expect("x-error-message2 header value") .to_str() .unwrap(), "updated-error" ); } #[tokio::test] #[should_panic] async fn test_use_error_next_without_err() { let mut app: App<()> = App::new(); app.use_err( |_error: &Error, _req: &mut Request<()>, _res: &mut Response, next: &mut NextFunction| { next(Ok(())) }, ); let mut test_app = testing(app); let request = hyper::Request::builder() .body(Body::from("body")) .expect("Request builder failed"); test_app.request(request).await; } #[tokio::test] async fn test_get() { let mut app: App<()> = App::new(); app.get( "/hello", |_req: &mut Request<()>, res: &mut Response, _next: &mut NextFunction| { res.status(StatusCode::ACCEPTED).end(); }, ); let mut test_app = testing(app); let get_request = hyper::Request::builder() .uri("http://localhost/hello") .body(Body::from("body")) .expect("Request builder failed"); let get_response = test_app.request(get_request).await; let non_existing_route_get_request = hyper::Request::builder() .uri("http://localhost/hello2") .body(Body::from("body")) .expect("Request builder failed"); let non_existing_route_get_response = test_app.request(non_existing_route_get_request).await; let post_request = hyper::Request::builder() .uri("http://localhost/hello") .method(Method::POST) .body(Body::from("body")) .expect("Request builder failed"); let post_response = test_app.request(post_request).await; assert_eq!(get_response.status(), StatusCode::ACCEPTED); assert_eq!( non_existing_route_get_response.status(), StatusCode::NOT_FOUND ); assert_eq!(post_response.status(), StatusCode::NOT_FOUND); } #[tokio::test] async fn test_post() { let mut app: App<()> = App::new(); app.post( "/hello", |_req: &mut Request<()>, res: &mut Response, _next: &mut NextFunction| { res.end(); }, ); let mut test_app = testing(app); let request = hyper::Request::builder() .uri("http://localhost/hello") .method(Method::POST) .body(Body::from("body")) .expect("Request builder failed"); let response = test_app.request(request).await; assert_eq!(response.status(), StatusCode::OK); } #[tokio::test] async fn test_put() { let mut app: App<()> = App::new(); app.put( "/hello", |_req: &mut Request<()>, res: &mut Response, _next: &mut NextFunction| { res.end(); }, ); let mut test_app = testing(app); let request = hyper::Request::builder() .uri("http://localhost/hello") .method(Method::PUT) .body(Body::from("body")) .expect("Request builder failed"); let response = test_app.request(request).await; assert_eq!(response.status(), StatusCode::OK); } #[tokio::test] async fn test_delete() { let mut app: App<()> = App::new(); app.delete( "/hello", |_req: &mut Request<()>, res: &mut Response, _next: &mut NextFunction| { res.end(); }, ); let mut test_app = testing(app); let request = hyper::Request::builder() .uri("http://localhost/hello") .method(Method::DELETE) .body(Body::from("body")) .expect("Request builder failed"); let response = test_app.request(request).await; assert_eq!(response.status(), StatusCode::OK); } #[tokio::test] async fn test_patch() { let mut app: App<()> = App::new(); app.patch( "/hello", |_req: &mut Request<()>, res: &mut Response, _next: &mut NextFunction| { res.end(); }, ); let mut test_app = testing(app); let request = hyper::Request::builder() .uri("http://localhost/hello") .method(Method::PATCH) .body(Body::from("body")) .expect("Request builder failed"); let response = test_app.request(request).await; assert_eq!(response.status(), StatusCode::OK); } #[tokio::test] async fn test_options() { let mut app: App<()> = App::new(); app.options( "/hello", |_req: &mut Request<()>, res: &mut Response, _next: &mut NextFunction| { res.end(); }, ); let mut test_app = testing(app); let request = hyper::Request::builder() .uri("http://localhost/hello") .method(Method::OPTIONS) .body(Body::from("body")) .expect("Request builder failed"); let response = test_app.request(request).await; assert_eq!(response.status(), StatusCode::OK); } #[tokio::test] async fn test_base_url() { let mut app: App<()> = App::new(); app.use_ok( |req: &mut Request<()>, res: &mut Response, _next: &mut NextFunction| { res.set_header("base-url", req.base_url()); res.end(); }, ); let mut test_app = testing(app); let request = hyper::Request::builder() .body(Body::from("body")) .expect("Request builder failed"); let response = test_app.request(request).await; assert_eq!( response .headers() .get("base-url") .expect("base-url header value") .to_str() .unwrap(), "/" ); } #[tokio::test] async fn test_base_url_in_router() { let mut app: App<()> = App::new(); let mut router = Router::new("/api"); router.use_ok( |req: &mut Request<()>, res: &mut Response, _next: &mut NextFunction| { res.set_header("base-url", req.base_url()); res.end(); }, ); app.router(router); let mut test_app = testing(app); let request = hyper::Request::builder() .uri("http://localhost/api") .body(Body::from("body")) .expect("Request builder failed"); let response = test_app.request(request).await; assert_eq!( response .headers() .get("base-url") .expect("base-url header value") .to_str() .unwrap(), "/api" ); }