mirror of https://github.com/rwf2/Rocket.git
Adds tests for JSON example. Emit warning from JSON FromData.
This also includes a tiny change to the `mk-docs` script to build a blank index at the root of the docs.
This commit is contained in:
parent
b9742c1202
commit
2dc1ba29f0
|
@ -4,7 +4,7 @@ extern crate serde_json;
|
|||
use std::ops::{Deref, DerefMut};
|
||||
use std::io::Read;
|
||||
|
||||
use rocket::outcome::{Outcome, IntoOutcome};
|
||||
use rocket::outcome::Outcome;
|
||||
use rocket::request::Request;
|
||||
use rocket::data::{self, Data, FromData};
|
||||
use rocket::response::{self, Responder, content};
|
||||
|
@ -78,7 +78,13 @@ impl<T: Deserialize> FromData for JSON<T> {
|
|||
}
|
||||
|
||||
let reader = data.open().take(MAX_SIZE);
|
||||
serde_json::from_reader(reader).map(|val| JSON(val)).into_outcome()
|
||||
match serde_json::from_reader(reader).map(|val| JSON(val)) {
|
||||
Ok(value) => Outcome::Success(value),
|
||||
Err(e) => {
|
||||
error_!("Couldn't parse JSON body: {:?}", e);
|
||||
Outcome::Failure((Status::BadRequest, e))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ extern crate rocket;
|
|||
#[cfg(test)] mod tests;
|
||||
|
||||
#[get("/hello/<name>/<age>")]
|
||||
fn hello(name: &str, age: i8) -> String {
|
||||
fn hello(name: &str, age: u8) -> String {
|
||||
format!("Hello, {} year old named {}!", age, name)
|
||||
}
|
||||
|
||||
|
|
|
@ -29,8 +29,8 @@ fn test_hello() {
|
|||
#[test]
|
||||
fn test_failing_hello() {
|
||||
test_404("/hello/Mike/1000");
|
||||
test_404("/hello/Mike/128");
|
||||
test_404("/hello/Mike/-129");
|
||||
test_404("/hello/Mike/-1");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -16,3 +16,6 @@ lazy_static = "*"
|
|||
path = "../../contrib"
|
||||
default-features = false
|
||||
features = ["json"]
|
||||
|
||||
[dev-dependencies]
|
||||
rocket = { path = "../../lib", features = ["testing"] }
|
||||
|
|
|
@ -7,6 +7,8 @@ extern crate serde_json;
|
|||
#[macro_use] extern crate rocket_contrib;
|
||||
#[macro_use] extern crate serde_derive;
|
||||
|
||||
#[cfg(test)] mod tests;
|
||||
|
||||
use rocket_contrib::JSON;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Mutex;
|
||||
|
@ -27,22 +29,9 @@ struct Message {
|
|||
}
|
||||
|
||||
// TODO: This example can be improved by using `route` with muliple HTTP verbs.
|
||||
// To be precise, put/post could/should look like:
|
||||
// #[route(PUT, POST, path = "/<id>", format = "application/json")]
|
||||
// fn f(method: Method, id: ID, message: JSON<Message>) -> Option<JSON<SimpleMap>> {
|
||||
// let mut hashmap = MAP.lock().unwrap();
|
||||
// let exists = hashmap.contains_key(&id);
|
||||
// if method == Method::Put && exists || method == Method::Post && !exists {
|
||||
// hashmap.insert(id, message.0.contents);
|
||||
// return Ok(JSON(map!{ "status" => "ok" }))
|
||||
// }
|
||||
//
|
||||
// None
|
||||
// }
|
||||
|
||||
#[post("/<id>", format = "application/json", data = "<message>")]
|
||||
fn new(id: ID, message: JSON<Message>) -> JSON<SimpleMap> {
|
||||
let mut hashmap = MAP.lock().unwrap();
|
||||
let mut hashmap = MAP.lock().expect("map lock.");
|
||||
if hashmap.contains_key(&id) {
|
||||
JSON(map!{
|
||||
"status" => "error",
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
use rocket;
|
||||
use rocket::testing::MockRequest;
|
||||
use rocket::http::Method::*;
|
||||
use rocket::http::{Status, ContentType};
|
||||
use rocket::Response;
|
||||
|
||||
macro_rules! run_test {
|
||||
($req:expr, $test_fn:expr) => ({
|
||||
let rocket = rocket::ignite()
|
||||
.mount("/message", routes![super::new, super::update, super::get])
|
||||
.catch(errors![super::not_found]);
|
||||
|
||||
$test_fn($req.dispatch_with(&rocket));
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bad_get_put() {
|
||||
// Try to get a message with an ID that doesn't exist.
|
||||
let mut req = MockRequest::new(Get, "/message/99").header(ContentType::JSON);
|
||||
run_test!(req, |mut response: Response| {
|
||||
assert_eq!(response.status(), Status::NotFound);
|
||||
|
||||
let body = response.body().unwrap().into_string().unwrap();
|
||||
assert!(body.contains("error"));
|
||||
assert!(body.contains("Resource was not found."));
|
||||
});
|
||||
|
||||
// Try to get a message with an invalid ID.
|
||||
let mut req = MockRequest::new(Get, "/message/hi").header(ContentType::JSON);
|
||||
run_test!(req, |mut response: Response| {
|
||||
assert_eq!(response.status(), Status::NotFound);
|
||||
let body = response.body().unwrap().into_string().unwrap();
|
||||
assert!(body.contains("error"));
|
||||
});
|
||||
|
||||
// Try to put a message without a proper body.
|
||||
let mut req = MockRequest::new(Put, "/message/80").header(ContentType::JSON);
|
||||
run_test!(req, |response: Response| {
|
||||
assert_eq!(response.status(), Status::BadRequest);
|
||||
});
|
||||
|
||||
// Try to put a message for an ID that doesn't exist.
|
||||
let mut req = MockRequest::new(Put, "/message/80")
|
||||
.header(ContentType::JSON)
|
||||
.body(r#"{ "contents": "Bye bye, world!" }"#);
|
||||
|
||||
run_test!(req, |response: Response| {
|
||||
assert_eq!(response.status(), Status::NotFound);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn post_get_put_get() {
|
||||
// Check that a message with ID 1 doesn't exist.
|
||||
let mut req = MockRequest::new(Get, "/message/1").header(ContentType::JSON);
|
||||
run_test!(req, |response: Response| {
|
||||
assert_eq!(response.status(), Status::NotFound);
|
||||
});
|
||||
|
||||
// Add a new message with ID 1.
|
||||
let mut req = MockRequest::new(Post, "/message/1")
|
||||
.header(ContentType::JSON)
|
||||
.body(r#"{ "contents": "Hello, world!" }"#);
|
||||
|
||||
run_test!(req, |response: Response| {
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
});
|
||||
|
||||
// Check that the message exists with the correct contents.
|
||||
let mut req = MockRequest::new(Get, "/message/1") .header(ContentType::JSON);
|
||||
run_test!(req, |mut response: Response| {
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
let body = response.body().unwrap().into_string().unwrap();
|
||||
assert!(body.contains("Hello, world!"));
|
||||
});
|
||||
|
||||
// Change the message contents.
|
||||
let mut req = MockRequest::new(Put, "/message/1")
|
||||
.header(ContentType::JSON)
|
||||
.body(r#"{ "contents": "Bye bye, world!" }"#);
|
||||
|
||||
run_test!(req, |response: Response| {
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
});
|
||||
|
||||
// Check that the message exists with the updated contents.
|
||||
let mut req = MockRequest::new(Get, "/message/1") .header(ContentType::JSON);
|
||||
run_test!(req, |mut response: Response| {
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
let body = response.body().unwrap().into_string().unwrap();
|
||||
assert!(!body.contains("Hello, world!"));
|
||||
assert!(body.contains("Bye bye, world!"));
|
||||
});
|
||||
}
|
|
@ -224,13 +224,13 @@ impl<'r, R: Responder<'r>> Responder<'r> for Option<R> {
|
|||
}
|
||||
}
|
||||
|
||||
/// If `self` is `Ok`, responds with the wrapped `Responder`. Otherwise prints a
|
||||
/// warning message with the `Err` value returns an `Err` of
|
||||
/// If `self` is `Ok`, responds with the wrapped `Responder`. Otherwise prints
|
||||
/// an error message with the `Err` value returns an `Err` of
|
||||
/// `Status::InternalServerError`.
|
||||
impl<'r, R: Responder<'r>, E: fmt::Debug> Responder<'r> for Result<R, E> {
|
||||
default fn respond(self) -> Result<Response<'r>, Status> {
|
||||
self.map(|r| r.respond()).unwrap_or_else(|e| {
|
||||
warn_!("Response was `Err`: {:?}.", e);
|
||||
error_!("Response was `Err`: {:?}.", e);
|
||||
Err(Status::InternalServerError)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -25,3 +25,6 @@ cargo clean
|
|||
mk_doc $LIB_DIR
|
||||
mk_doc $CODEGEN_DIR
|
||||
mk_doc $CONTRIB_DIR --all-features
|
||||
|
||||
# Blank index, for redirection.
|
||||
touch ${DOC_DIR}/index.html
|
||||
|
|
Loading…
Reference in New Issue