mirror of https://github.com/rwf2/Rocket.git
Update parts of contrib and associated tests and examples:
* json * templates * helmet * databases * serve * examples/cookies * examples/handlebars_templates * examples/json * examples/session * examples/static_files * examples/tera_templates
This commit is contained in:
parent
7c34a3a93e
commit
6044961680
|
@ -42,6 +42,7 @@ memcache_pool = ["databases", "memcache", "r2d2-memcache"]
|
|||
|
||||
[dependencies]
|
||||
# Global dependencies.
|
||||
futures-preview = { version = "0.3.0-alpha.17" }
|
||||
rocket_contrib_codegen = { version = "0.5.0-dev", path = "../codegen", optional = true }
|
||||
rocket = { version = "0.5.0-dev", path = "../../core/lib/", default-features = false }
|
||||
log = "0.4"
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
//! Whenever a connection to the database is needed:
|
||||
//!
|
||||
//! ```rust
|
||||
//! # #![feature(proc_macro_hygiene)]
|
||||
//! # #![feature(proc_macro_hygiene, async_await)]
|
||||
//! #
|
||||
//! # #[macro_use] extern crate rocket;
|
||||
//! # #[macro_use] extern crate rocket_contrib;
|
||||
|
@ -289,7 +289,7 @@
|
|||
//! connection to a given database:
|
||||
//!
|
||||
//! ```rust
|
||||
//! # #![feature(proc_macro_hygiene)]
|
||||
//! # #![feature(proc_macro_hygiene, async_await)]
|
||||
//! #
|
||||
//! # #[macro_use] extern crate rocket;
|
||||
//! # #[macro_use] extern crate rocket_contrib;
|
||||
|
@ -311,7 +311,7 @@
|
|||
//! connection type:
|
||||
//!
|
||||
//! ```rust
|
||||
//! # #![feature(proc_macro_hygiene)]
|
||||
//! # #![feature(proc_macro_hygiene, async_await)]
|
||||
//! #
|
||||
//! # #[macro_use] extern crate rocket;
|
||||
//! # #[macro_use] extern crate rocket_contrib;
|
||||
|
|
|
@ -196,8 +196,10 @@ impl Fairing for SpaceHelmet {
|
|||
}
|
||||
}
|
||||
|
||||
fn on_response(&self, _request: &Request<'_>, response: &mut Response<'_>) {
|
||||
fn on_response<'a>(&'a self, _request: &'a Request<'_>, response: &'a mut Response<'_>) -> std::pin::Pin<Box<dyn std::future::Future<Output=()> + Send + 'a>> {
|
||||
Box::pin(async move {
|
||||
self.apply(response);
|
||||
})
|
||||
}
|
||||
|
||||
fn on_launch(&self, rocket: &Rocket) {
|
||||
|
|
|
@ -15,14 +15,17 @@
|
|||
//! ```
|
||||
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::io::{self, Read};
|
||||
use std::io;
|
||||
use std::iter::FromIterator;
|
||||
|
||||
use futures::io::AsyncReadExt;
|
||||
|
||||
use rocket::request::Request;
|
||||
use rocket::outcome::Outcome::*;
|
||||
use rocket::data::{Outcome, Transform, Transform::*, Transformed, Data, FromData};
|
||||
use rocket::data::{Transform::*, Transformed, Data, FromData, TransformFuture, FromDataFuture};
|
||||
use rocket::response::{self, Responder, content};
|
||||
use rocket::http::Status;
|
||||
use rocket::AsyncReadExt as _;
|
||||
|
||||
use serde::{Serialize, Serializer};
|
||||
use serde::de::{Deserialize, Deserializer};
|
||||
|
@ -41,7 +44,7 @@ pub use serde_json::{json_internal, json_internal_vec};
|
|||
/// or from [`serde`]. The data is parsed from the HTTP request body.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![feature(proc_macro_hygiene)]
|
||||
/// # #![feature(proc_macro_hygiene, async_await)]
|
||||
/// # #[macro_use] extern crate rocket;
|
||||
/// # extern crate rocket_contrib;
|
||||
/// # type User = usize;
|
||||
|
@ -65,7 +68,7 @@ pub use serde_json::{json_internal, json_internal_vec};
|
|||
/// set to `application/json` automatically.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![feature(proc_macro_hygiene)]
|
||||
/// # #![feature(proc_macro_hygiene, async_await)]
|
||||
/// # #[macro_use] extern crate rocket;
|
||||
/// # extern crate rocket_contrib;
|
||||
/// # type User = usize;
|
||||
|
@ -133,16 +136,25 @@ impl<'a, T: Deserialize<'a>> FromData<'a> for Json<T> {
|
|||
type Owned = String;
|
||||
type Borrowed = str;
|
||||
|
||||
fn transform(r: &Request<'_>, d: Data) -> Transform<Outcome<Self::Owned, Self::Error>> {
|
||||
fn transform(r: &Request<'_>, d: Data) -> TransformFuture<'a, Self::Owned, Self::Error> {
|
||||
let size_limit = r.limits().get("json").unwrap_or(LIMIT);
|
||||
let mut s = String::with_capacity(512);
|
||||
match d.open().take(size_limit).read_to_string(&mut s) {
|
||||
Ok(_) => Borrowed(Success(s)),
|
||||
Box::pin(async move {
|
||||
let mut v = Vec::with_capacity(512);
|
||||
let mut reader = d.open().take(size_limit);
|
||||
match reader.read_to_end(&mut v).await {
|
||||
Ok(_) => {
|
||||
match String::from_utf8(v) {
|
||||
Ok(s) => Borrowed(Success(s)),
|
||||
Err(e) => Borrowed(Failure((Status::BadRequest, JsonError::Io(std::io::Error::new(std::io::ErrorKind::Other, e))))),
|
||||
}
|
||||
},
|
||||
Err(e) => Borrowed(Failure((Status::BadRequest, JsonError::Io(e))))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn from_data(_: &Request<'_>, o: Transformed<'a, Self>) -> Outcome<Self, Self::Error> {
|
||||
fn from_data(_: &Request<'_>, o: Transformed<'a, Self>) -> FromDataFuture<'a, Self, Self::Error> {
|
||||
Box::pin(async move {
|
||||
let string = try_outcome!(o.borrowed());
|
||||
match serde_json::from_str(&string) {
|
||||
Ok(v) => Success(Json(v)),
|
||||
|
@ -155,22 +167,24 @@ impl<'a, T: Deserialize<'a>> FromData<'a> for Json<T> {
|
|||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Serializes the wrapped value into JSON. Returns a response with Content-Type
|
||||
/// JSON and a fixed-size body with the serialized value. If serialization
|
||||
/// fails, an `Err` of `Status::InternalServerError` is returned.
|
||||
impl<'a, T: Serialize> Responder<'a> for Json<T> {
|
||||
fn respond_to(self, req: &Request<'_>) -> response::Result<'a> {
|
||||
serde_json::to_string(&self.0).map(|string| {
|
||||
content::Json(string).respond_to(req).unwrap()
|
||||
}).map_err(|e| {
|
||||
impl<'r, T: Serialize> Responder<'r> for Json<T> {
|
||||
fn respond_to(self, req: &'r Request<'_>) -> response::ResultFuture<'r> {
|
||||
match serde_json::to_string(&self.0) {
|
||||
Ok(string) => Box::pin(async move { Ok(content::Json(string).respond_to(req).await.unwrap()) }),
|
||||
Err(e) => Box::pin(async move {
|
||||
error_!("JSON failed to serialize: {:?}", e);
|
||||
Status::InternalServerError
|
||||
Err(Status::InternalServerError)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Deref for Json<T> {
|
||||
type Target = T;
|
||||
|
@ -210,7 +224,7 @@ impl<T> DerefMut for Json<T> {
|
|||
/// fashion during request handling. This looks something like:
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![feature(proc_macro_hygiene)]
|
||||
/// # #![feature(proc_macro_hygiene, async_await)]
|
||||
/// # #[macro_use] extern crate rocket;
|
||||
/// # #[macro_use] extern crate rocket_contrib;
|
||||
/// use rocket_contrib::json::JsonValue;
|
||||
|
@ -283,9 +297,9 @@ impl<T> FromIterator<T> for JsonValue where serde_json::Value: FromIterator<T> {
|
|||
|
||||
/// Serializes the value into JSON. Returns a response with Content-Type JSON
|
||||
/// and a fixed-size body with the serialized value.
|
||||
impl<'a> Responder<'a> for JsonValue {
|
||||
impl<'r> Responder<'r> for JsonValue {
|
||||
#[inline]
|
||||
fn respond_to(self, req: &Request<'_>) -> response::Result<'a> {
|
||||
fn respond_to(self, req: &'r Request<'_>) -> response::ResultFuture<'r> {
|
||||
content::Json(self.0.to_string()).respond_to(req)
|
||||
}
|
||||
}
|
||||
|
@ -305,7 +319,7 @@ impl<'a> Responder<'a> for JsonValue {
|
|||
/// value created with this macro can be returned from a handler as follows:
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![feature(proc_macro_hygiene)]
|
||||
/// # #![feature(proc_macro_hygiene, async_await)]
|
||||
/// # #[macro_use] extern crate rocket;
|
||||
/// # #[macro_use] extern crate rocket_contrib;
|
||||
/// use rocket_contrib::json::JsonValue;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#![feature(async_await)]
|
||||
#![doc(html_root_url = "https://api.rocket.rs/v0.5")]
|
||||
#![doc(html_favicon_url = "https://rocket.rs/images/favicon.ico")]
|
||||
#![doc(html_logo_url = "https://rocket.rs/images/logo-boxed.png")]
|
||||
|
|
|
@ -18,7 +18,7 @@ use std::path::{PathBuf, Path};
|
|||
|
||||
use rocket::{Request, Data, Route};
|
||||
use rocket::http::{Method, uri::Segments, ext::IntoOwned};
|
||||
use rocket::handler::{Handler, Outcome};
|
||||
use rocket::handler::{Handler, HandlerFuture, Outcome};
|
||||
use rocket::response::{NamedFile, Redirect};
|
||||
|
||||
/// A bitset representing configurable options for the [`StaticFiles`] handler.
|
||||
|
@ -290,18 +290,20 @@ impl Into<Vec<Route>> for StaticFiles {
|
|||
}
|
||||
|
||||
impl Handler for StaticFiles {
|
||||
fn handle<'r>(&self, req: &'r Request<'_>, data: Data) -> Outcome<'r> {
|
||||
fn handle_dir<'r>(opt: Options, r: &'r Request<'_>, d: Data, path: &Path) -> Outcome<'r> {
|
||||
fn handle<'r>(&self, req: &'r Request<'_>, data: Data) -> HandlerFuture<'r> {
|
||||
fn handle_dir<'r>(opt: Options, r: &'r Request<'_>, d: Data, path: &Path) -> HandlerFuture<'r> {
|
||||
if opt.contains(Options::NormalizeDirs) && !r.uri().path().ends_with('/') {
|
||||
let new_path = r.uri().map_path(|p| p.to_owned() + "/")
|
||||
.expect("adding a trailing slash to a known good path results in a valid path")
|
||||
.into_owned();
|
||||
|
||||
return Outcome::from_or_forward(r, d, Redirect::permanent(new_path));
|
||||
return Box::pin(async move {
|
||||
Outcome::from_or_forward(r, d, Redirect::permanent(new_path))
|
||||
});
|
||||
}
|
||||
|
||||
if !opt.contains(Options::Index) {
|
||||
return Outcome::forward(d);
|
||||
return Box::pin(async move { Outcome::forward(d) });
|
||||
}
|
||||
|
||||
let file = NamedFile::open(path.join("index.html")).ok();
|
||||
|
@ -327,7 +329,7 @@ impl Handler for StaticFiles {
|
|||
match &path {
|
||||
Some(path) if path.is_dir() => handle_dir(self.options, req, data, path),
|
||||
Some(path) => Outcome::from_or_forward(req, data, NamedFile::open(path).ok()),
|
||||
None => Outcome::forward(data)
|
||||
None => Box::pin(async move { Outcome::forward(data) }),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::templates::ContextManager;
|
|||
/// used as a request guard in any request handler.
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![feature(proc_macro_hygiene)]
|
||||
/// # #![feature(proc_macro_hygiene, async_await)]
|
||||
/// # #[macro_use] extern crate rocket;
|
||||
/// # #[macro_use] extern crate rocket_contrib;
|
||||
/// use rocket_contrib::templates::{Template, Metadata};
|
||||
|
@ -46,7 +46,7 @@ impl Metadata<'_> {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![feature(proc_macro_hygiene)]
|
||||
/// # #![feature(proc_macro_hygiene, async_await)]
|
||||
/// # #[macro_use] extern crate rocket;
|
||||
/// # extern crate rocket_contrib;
|
||||
/// #
|
||||
|
@ -67,7 +67,7 @@ impl Metadata<'_> {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![feature(proc_macro_hygiene)]
|
||||
/// # #![feature(proc_macro_hygiene, async_await)]
|
||||
/// # #[macro_use] extern crate rocket;
|
||||
/// # extern crate rocket_contrib;
|
||||
/// #
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
//! of the template file minus the last two extensions, from a handler.
|
||||
//!
|
||||
//! ```rust
|
||||
//! # #![feature(proc_macro_hygiene)]
|
||||
//! # #![feature(proc_macro_hygiene, async_await)]
|
||||
//! # #[macro_use] extern crate rocket;
|
||||
//! # #[macro_use] extern crate rocket_contrib;
|
||||
//! # fn context() { }
|
||||
|
@ -180,7 +180,7 @@ const DEFAULT_TEMPLATE_DIR: &str = "templates";
|
|||
/// returned from a request handler directly:
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![feature(proc_macro_hygiene)]
|
||||
/// # #![feature(proc_macro_hygiene, async_await)]
|
||||
/// # #[macro_use] extern crate rocket;
|
||||
/// # #[macro_use] extern crate rocket_contrib;
|
||||
/// # fn context() { }
|
||||
|
@ -383,8 +383,10 @@ impl Template {
|
|||
/// Returns a response with the Content-Type derived from the template's
|
||||
/// extension and a fixed-size body containing the rendered template. If
|
||||
/// rendering fails, an `Err` of `Status::InternalServerError` is returned.
|
||||
impl Responder<'static> for Template {
|
||||
fn respond_to(self, req: &Request<'_>) -> response::Result<'static> {
|
||||
impl<'r> Responder<'r> for Template {
|
||||
fn respond_to(self, req: &'r Request<'_>) -> response::ResultFuture<'r> {
|
||||
Box::pin(async move {
|
||||
let (render, content_type) = {
|
||||
let ctxt = req.guard::<State<'_, ContextManager>>().succeeded().ok_or_else(|| {
|
||||
error_!("Uninitialized template context: missing fairing.");
|
||||
info_!("To use templates, you must attach `Template::fairing()`.");
|
||||
|
@ -392,7 +394,10 @@ impl Responder<'static> for Template {
|
|||
Status::InternalServerError
|
||||
})?.inner().context();
|
||||
|
||||
let (render, content_type) = self.finalize(&ctxt)?;
|
||||
Content(content_type, render).respond_to(req)
|
||||
self.finalize(&ctxt)?
|
||||
};
|
||||
|
||||
Content(content_type, render).respond_to(req).await
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#![feature(proc_macro_hygiene)]
|
||||
#![feature(proc_macro_hygiene, async_await)]
|
||||
|
||||
#[macro_use]
|
||||
#[cfg(feature = "helmet")]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#![feature(proc_macro_hygiene)]
|
||||
#![feature(proc_macro_hygiene, async_await)]
|
||||
|
||||
#[cfg(feature = "serve")]
|
||||
mod static_tests {
|
||||
|
@ -59,7 +59,7 @@ mod static_tests {
|
|||
let mut file = File::open(path).expect("open file");
|
||||
let mut expected_contents = String::new();
|
||||
file.read_to_string(&mut expected_contents).expect("read file");
|
||||
assert_eq!(response.body_string(), Some(expected_contents));
|
||||
assert_eq!(response.body_string_wait(), Some(expected_contents));
|
||||
} else {
|
||||
assert_eq!(response.status(), Status::NotFound);
|
||||
}
|
||||
|
@ -135,11 +135,11 @@ mod static_tests {
|
|||
|
||||
let mut response = client.get("/default/ireallydontexist").dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
assert_eq!(response.body_string().unwrap(), "ireallydontexist");
|
||||
assert_eq!(response.body_string_wait().unwrap(), "ireallydontexist");
|
||||
|
||||
let mut response = client.get("/default/idont/exist").dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
assert_eq!(response.body_string().unwrap(), "idont/exist");
|
||||
assert_eq!(response.body_string_wait().unwrap(), "idont/exist");
|
||||
|
||||
assert_all(&client, "both", REGULAR_FILES, true);
|
||||
assert_all(&client, "both", HIDDEN_FILES, true);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#![feature(proc_macro_hygiene)]
|
||||
#![feature(proc_macro_hygiene, async_await)]
|
||||
|
||||
#[cfg(feature = "templates")]
|
||||
#[macro_use] extern crate rocket;
|
||||
|
|
|
@ -137,6 +137,7 @@ pub use crate::router::Route;
|
|||
pub use crate::request::{Request, State};
|
||||
pub use crate::catcher::Catcher;
|
||||
pub use crate::rocket::Rocket;
|
||||
pub use ext::AsyncReadExt;
|
||||
|
||||
/// Alias to [`Rocket::ignite()`] Creates a new instance of `Rocket`.
|
||||
pub fn ignite() -> Rocket {
|
||||
|
|
|
@ -30,7 +30,7 @@ fn test_body(optional_cookie: Option<Cookie<'static>>, expected_body: String) {
|
|||
};
|
||||
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
assert_eq!(response.body_string(), Some(expected_body));
|
||||
assert_eq!(response.body_string_wait(), Some(expected_body));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -33,7 +33,7 @@ fn test_root() {
|
|||
let expected = Template::show(client.rocket(), "error/404", &map).unwrap();
|
||||
|
||||
assert_eq!(response.status(), Status::NotFound);
|
||||
assert_eq!(response.body_string(), Some(expected));
|
||||
assert_eq!(response.body_string_wait(), Some(expected));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ fn test_name() {
|
|||
|
||||
let expected = Template::show(client.rocket(), "index", &context).unwrap();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
assert_eq!(response.body_string(), Some(expected));
|
||||
assert_eq!(response.body_string_wait(), Some(expected));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -64,6 +64,6 @@ fn test_404() {
|
|||
|
||||
let expected = Template::show(client.rocket(), "error/404", &map).unwrap();
|
||||
assert_eq!(response.status(), Status::NotFound);
|
||||
assert_eq!(response.body_string(), Some(expected));
|
||||
assert_eq!(response.body_string_wait(), Some(expected));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -10,13 +10,13 @@ fn bad_get_put() {
|
|||
let mut res = client.get("/message/99").header(ContentType::JSON).dispatch();
|
||||
assert_eq!(res.status(), Status::NotFound);
|
||||
|
||||
let body = res.body_string().unwrap();
|
||||
let body = res.body_string_wait().unwrap();
|
||||
assert!(body.contains("error"));
|
||||
assert!(body.contains("Resource was not found."));
|
||||
|
||||
// Try to get a message with an invalid ID.
|
||||
let mut res = client.get("/message/hi").header(ContentType::JSON).dispatch();
|
||||
let body = res.body_string().unwrap();
|
||||
let body = res.body_string_wait().unwrap();
|
||||
assert_eq!(res.status(), Status::NotFound);
|
||||
assert!(body.contains("error"));
|
||||
|
||||
|
@ -52,7 +52,7 @@ fn post_get_put_get() {
|
|||
// Check that the message exists with the correct contents.
|
||||
let mut res = client.get("/message/1").header(ContentType::JSON).dispatch();
|
||||
assert_eq!(res.status(), Status::Ok);
|
||||
let body = res.body().unwrap().into_string().unwrap();
|
||||
let body = res.body_string_wait().unwrap();
|
||||
assert!(body.contains("Hello, world!"));
|
||||
|
||||
// Change the message contents.
|
||||
|
@ -66,7 +66,7 @@ fn post_get_put_get() {
|
|||
// Check that the message exists with the updated contents.
|
||||
let mut res = client.get("/message/1").header(ContentType::JSON).dispatch();
|
||||
assert_eq!(res.status(), Status::Ok);
|
||||
let body = res.body().unwrap().into_string().unwrap();
|
||||
let body = res.body_string_wait().unwrap();
|
||||
assert!(!body.contains("Hello, world!"));
|
||||
assert!(body.contains("Bye bye, world!"));
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ fn can_login() {
|
|||
let client = Client::new(rocket()).unwrap();
|
||||
|
||||
let mut response = client.get("/login").dispatch();
|
||||
let body = response.body_string().unwrap();
|
||||
let body = response.body_string_wait().unwrap();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
assert!(body.contains("Please login to continue."));
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ fn login_logout_succeeds() {
|
|||
|
||||
// Ensure we're logged in.
|
||||
let mut response = client.get("/").cookie(login_cookie.clone()).dispatch();
|
||||
let body = response.body_string().unwrap();
|
||||
let body = response.body_string_wait().unwrap();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
assert!(body.contains("Logged in with user ID 1"));
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ fn test_query_file<T> (path: &str, file: T, status: Status)
|
|||
let mut response = client.get(path).dispatch();
|
||||
assert_eq!(response.status(), status);
|
||||
|
||||
let body_data = response.body().and_then(|body| body.into_bytes());
|
||||
let body_data = response.body_bytes_wait();
|
||||
if let Some(filename) = file.into() {
|
||||
let expected_data = read_file_content(filename);
|
||||
assert!(body_data.map_or(false, |s| s == expected_data));
|
||||
|
|
|
@ -32,7 +32,7 @@ fn test_root() {
|
|||
let expected = Template::show(client.rocket(), "error/404", &map).unwrap();
|
||||
|
||||
assert_eq!(response.status(), Status::NotFound);
|
||||
assert_eq!(response.body_string(), Some(expected));
|
||||
assert_eq!(response.body_string_wait(), Some(expected));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ fn test_name() {
|
|||
|
||||
let expected = Template::show(client.rocket(), "index", &context).unwrap();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
assert_eq!(response.body_string(), Some(expected));
|
||||
assert_eq!(response.body_string_wait(), Some(expected));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,6 @@ fn test_404() {
|
|||
|
||||
let expected = Template::show(client.rocket(), "error/404", &map).unwrap();
|
||||
assert_eq!(response.status(), Status::NotFound);
|
||||
assert_eq!(response.body_string(), Some(expected));
|
||||
assert_eq!(response.body_string_wait(), Some(expected));
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue