1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-11-28 01:52:57 +01:00

fix state factory support, tests for state and state factory

This commit is contained in:
Nikolay Kim 2019-03-03 21:40:03 -08:00
parent 34171fa7f5
commit 5c61321565
3 changed files with 208 additions and 6 deletions

View File

@ -14,7 +14,7 @@ use futures::future::{ok, Either, FutureResult};
use futures::{Async, Future, IntoFuture, Poll}; use futures::{Async, Future, IntoFuture, Poll};
use crate::resource::Resource; use crate::resource::Resource;
use crate::scope::Scope; use crate::scope::{insert_slash, Scope};
use crate::service::{ServiceRequest, ServiceResponse}; use crate::service::{ServiceRequest, ServiceResponse};
use crate::state::{State, StateFactory, StateFactoryResult}; use crate::state::{State, StateFactory, StateFactoryResult};
@ -103,13 +103,13 @@ where
/// Set application state factory. This function is /// Set application state factory. This function is
/// similar to `.state()` but it accepts state factory. State get /// similar to `.state()` but it accepts state factory. State get
/// constructed asynchronously during application initialization. /// constructed asynchronously during application initialization.
pub fn state_factory<S, F, Out>(mut self, state: F) -> Self pub fn state_factory<F, Out>(mut self, state: F) -> Self
where where
F: Fn() -> Out + 'static, F: Fn() -> Out + 'static,
Out: IntoFuture + 'static, Out: IntoFuture + 'static,
Out::Error: std::fmt::Debug, Out::Error: std::fmt::Debug,
{ {
self.state.push(Box::new(State::new(state))); self.state.push(Box::new(state));
self self
} }
@ -200,7 +200,7 @@ where
InitError = (), InitError = (),
> + 'static, > + 'static,
{ {
let rdef = ResourceDef::new(path); let rdef = ResourceDef::new(&insert_slash(path));
let resource = f(Resource::new()); let resource = f(Resource::new());
let default = resource.get_default(); let default = resource.get_default();
@ -408,7 +408,7 @@ where
InitError = (), InitError = (),
> + 'static, > + 'static,
{ {
let rdef = ResourceDef::new(path); let rdef = ResourceDef::new(&insert_slash(path));
let resource = f(Resource::new()); let resource = f(Resource::new());
self.defaults.push(resource.get_default()); self.defaults.push(resource.get_default());
self.services self.services
@ -891,3 +891,168 @@ where
self.chain.call(req) self.chain.call(req)
} }
} }
#[cfg(test)]
mod tests {
use actix_http::http::StatusCode;
use super::*;
use crate::test::TestRequest;
use crate::{HttpResponse, State};
#[test]
fn test_default_resource() {
let mut rt = actix_rt::Runtime::new().unwrap();
let app = App::new()
.resource("/test", |r| r.to(|| HttpResponse::Ok()))
.into_new_service();
let mut srv = rt.block_on(app.new_service(&())).unwrap();
let req = TestRequest::with_uri("/test").to_request();
let resp = rt.block_on(srv.call(req)).unwrap();
assert_eq!(resp.status(), StatusCode::OK);
let req = TestRequest::with_uri("/blah").to_request();
let resp = rt.block_on(srv.call(req)).unwrap();
assert_eq!(resp.status(), StatusCode::NOT_FOUND);
let app = App::new()
.resource("/test", |r| r.to(|| HttpResponse::Ok()))
.default_resource(|r| r.to(|| HttpResponse::MethodNotAllowed()))
.into_new_service();
let mut srv = rt.block_on(app.new_service(&())).unwrap();
let req = TestRequest::with_uri("/blah").to_request();
let resp = rt.block_on(srv.call(req)).unwrap();
assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED);
}
#[test]
fn test_state() {
let mut rt = actix_rt::Runtime::new().unwrap();
let app = App::new()
.state(10usize)
.resource("/", |r| r.to(|_: State<usize>| HttpResponse::Ok()))
.into_new_service();
let mut srv = rt.block_on(app.new_service(&())).unwrap();
let req = TestRequest::default().to_request();
let resp = rt.block_on(srv.call(req)).unwrap();
assert_eq!(resp.status(), StatusCode::OK);
let app = App::new()
.state(10u32)
.resource("/", |r| r.to(|_: State<usize>| HttpResponse::Ok()))
.into_new_service();
let mut srv = rt.block_on(app.new_service(&())).unwrap();
let req = TestRequest::default().to_request();
let resp = rt.block_on(srv.call(req)).unwrap();
assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
}
#[test]
fn test_state_factory() {
let mut rt = actix_rt::Runtime::new().unwrap();
let app = App::new()
.state_factory(|| Ok::<_, ()>(10usize))
.resource("/", |r| r.to(|_: State<usize>| HttpResponse::Ok()))
.into_new_service();
let mut srv = rt.block_on(app.new_service(&())).unwrap();
let req = TestRequest::default().to_request();
let resp = rt.block_on(srv.call(req)).unwrap();
assert_eq!(resp.status(), StatusCode::OK);
let app = App::new()
.state_factory(|| Ok::<_, ()>(10u32))
.resource("/", |r| r.to(|_: State<usize>| HttpResponse::Ok()))
.into_new_service();
let mut srv = rt.block_on(app.new_service(&())).unwrap();
let req = TestRequest::default().to_request();
let resp = rt.block_on(srv.call(req)).unwrap();
assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
}
// #[test]
// fn test_handler() {
// let app = App::new()
// .handler("/test", |_: &_| HttpResponse::Ok())
// .finish();
// let req = TestRequest::with_uri("/test").request();
// let resp = app.run(req);
// assert_eq!(resp.as_msg().status(), StatusCode::OK);
// let req = TestRequest::with_uri("/test/").request();
// let resp = app.run(req);
// assert_eq!(resp.as_msg().status(), StatusCode::OK);
// let req = TestRequest::with_uri("/test/app").request();
// let resp = app.run(req);
// assert_eq!(resp.as_msg().status(), StatusCode::OK);
// let req = TestRequest::with_uri("/testapp").request();
// let resp = app.run(req);
// assert_eq!(resp.as_msg().status(), StatusCode::NOT_FOUND);
// let req = TestRequest::with_uri("/blah").request();
// let resp = app.run(req);
// assert_eq!(resp.as_msg().status(), StatusCode::NOT_FOUND);
// }
// #[test]
// fn test_handler2() {
// let app = App::new()
// .handler("test", |_: &_| HttpResponse::Ok())
// .finish();
// let req = TestRequest::with_uri("/test").request();
// let resp = app.run(req);
// assert_eq!(resp.as_msg().status(), StatusCode::OK);
// let req = TestRequest::with_uri("/test/").request();
// let resp = app.run(req);
// assert_eq!(resp.as_msg().status(), StatusCode::OK);
// let req = TestRequest::with_uri("/test/app").request();
// let resp = app.run(req);
// assert_eq!(resp.as_msg().status(), StatusCode::OK);
// let req = TestRequest::with_uri("/testapp").request();
// let resp = app.run(req);
// assert_eq!(resp.as_msg().status(), StatusCode::NOT_FOUND);
// let req = TestRequest::with_uri("/blah").request();
// let resp = app.run(req);
// assert_eq!(resp.as_msg().status(), StatusCode::NOT_FOUND);
// }
// #[test]
// fn test_route() {
// let app = App::new()
// .route("/test", Method::GET, |_: HttpRequest| HttpResponse::Ok())
// .route("/test", Method::POST, |_: HttpRequest| {
// HttpResponse::Created()
// })
// .finish();
// let req = TestRequest::with_uri("/test").method(Method::GET).request();
// let resp = app.run(req);
// assert_eq!(resp.as_msg().status(), StatusCode::OK);
// let req = TestRequest::with_uri("/test")
// .method(Method::POST)
// .request();
// let resp = app.run(req);
// assert_eq!(resp.as_msg().status(), StatusCode::CREATED);
// let req = TestRequest::with_uri("/test")
// .method(Method::HEAD)
// .request();
// let resp = app.run(req);
// assert_eq!(resp.as_msg().status(), StatusCode::NOT_FOUND);
// }
}

View File

@ -272,3 +272,40 @@ where
Ok(self.0.poll().map_err(|e| e.into())?) Ok(self.0.poll().map_err(|e| e.into())?)
} }
} }
#[cfg(test)]
mod tests {
// use actix_http::body::Body;
use actix_http::body::{Body, ResponseBody};
use actix_http::http::StatusCode;
use actix_service::{IntoNewService, NewService, Service};
use bytes::Bytes;
use crate::test::TestRequest;
use crate::App;
#[test]
fn test_option_responder() {
let mut rt = actix_rt::Runtime::new().unwrap();
let app = App::new()
.resource("/none", |r| r.to(|| -> Option<&'static str> { None }))
.resource("/some", |r| r.to(|| Some("some")))
.into_new_service();
let mut srv = rt.block_on(app.new_service(&())).unwrap();
let req = TestRequest::with_uri("/none").to_request();
let resp = rt.block_on(srv.call(req)).unwrap();
assert_eq!(resp.status(), StatusCode::NOT_FOUND);
let req = TestRequest::with_uri("/some").to_request();
let resp = rt.block_on(srv.call(req)).unwrap();
assert_eq!(resp.status(), StatusCode::OK);
match resp.body() {
ResponseBody::Body(Body::Bytes(ref b)) => {
let bytes: Bytes = b.clone().into();
assert_eq!(bytes, Bytes::from_static(b"some"));
}
_ => panic!(),
}
}
}

View File

@ -272,7 +272,7 @@ where
} }
} }
fn insert_slash(path: &str) -> String { pub(crate) fn insert_slash(path: &str) -> String {
let mut path = path.to_owned(); let mut path = path.to_owned();
if !path.is_empty() && !path.starts_with('/') { if !path.is_empty() && !path.starts_with('/') {
path.insert(0, '/'); path.insert(0, '/');