Rocket/core/codegen/tests/responder.rs
Sergio Benitez 2465e2f136 Make 'Responder' trait sync; fix its lifetimes.
In summary, this commit modifies 'Responder' so that:

  * ..it is no longer 'async'. To accommodate, the 'sized_body' methods
    in 'Response' and 'ResponseBuilder' are no longer 'async' and accept
    an optional size directly. If none is supplied, Rocket will attempt
    to compute the size, by seeking, before writing out the response.
    The 'Body' type was also changed to differentiate between its sized
    'Seek' and chunked body variants.

  * ..'&Request' gains a lifetime: 'r, and the returned 'Response' is
    parameterized by a new 'o: 'r. This allows responders to return
    references from the request or those that live longer.
2020-07-11 09:24:29 -07:00

112 lines
3.5 KiB
Rust

#![feature(proc_macro_hygiene)]
use rocket::local::Client;
use rocket::response::Responder;
use rocket::http::{Status, ContentType, Cookie};
#[derive(Responder)]
pub enum Foo<'r> {
First(String),
#[response(status = 500)]
Second(Vec<u8>),
#[response(status = 404, content_type = "html")]
Third {
responder: &'r str,
ct: rocket::http::ContentType,
},
#[response(status = 105)]
Fourth {
string: &'r str,
ct: rocket::http::ContentType,
},
}
#[rocket::async_test]
async fn responder_foo() {
let client = Client::new(rocket::ignite()).await.expect("valid rocket");
let local_req = client.get("/");
let req = local_req.inner();
let mut response = Foo::First("hello".into())
.respond_to(req)
.expect("response okay");
assert_eq!(response.status(), Status::Ok);
assert_eq!(response.content_type(), Some(ContentType::Plain));
assert_eq!(response.body_string().await, Some("hello".into()));
let mut response = Foo::Second("just a test".into())
.respond_to(req)
.expect("response okay");
assert_eq!(response.status(), Status::InternalServerError);
assert_eq!(response.content_type(), Some(ContentType::Binary));
assert_eq!(response.body_string().await, Some("just a test".into()));
let mut response = Foo::Third { responder: "well, hi", ct: ContentType::JSON }
.respond_to(req)
.expect("response okay");
assert_eq!(response.status(), Status::NotFound);
assert_eq!(response.content_type(), Some(ContentType::HTML));
assert_eq!(response.body_string().await, Some("well, hi".into()));
let mut response = Foo::Fourth { string: "goodbye", ct: ContentType::JSON }
.respond_to(req)
.expect("response okay");
assert_eq!(response.status(), Status::raw(105));
assert_eq!(response.content_type(), Some(ContentType::JSON));
assert_eq!(response.body_string().await, Some("goodbye".into()));
}
#[derive(Responder)]
#[response(content_type = "plain")]
pub struct Bar<'r> {
responder: Foo<'r>,
other: ContentType,
third: Cookie<'static>,
#[response(ignore)]
_yet_another: String,
}
#[rocket::async_test]
async fn responder_bar() {
let client = Client::new(rocket::ignite()).await.expect("valid rocket");
let local_req = client.get("/");
let req = local_req.inner();
let mut response = Bar {
responder: Foo::Second("foo foo".into()),
other: ContentType::HTML,
third: Cookie::new("cookie", "here!"),
_yet_another: "uh..hi?".into()
}.respond_to(req).expect("response okay");
assert_eq!(response.status(), Status::InternalServerError);
assert_eq!(response.content_type(), Some(ContentType::Plain));
assert_eq!(response.body_string().await, Some("foo foo".into()));
assert_eq!(response.headers().get_one("Set-Cookie"), Some("cookie=here!"));
}
#[derive(Responder)]
#[response(content_type = "application/x-custom")]
pub struct Baz {
responder: &'static str,
}
#[rocket::async_test]
async fn responder_baz() {
let client = Client::new(rocket::ignite()).await.expect("valid rocket");
let local_req = client.get("/");
let req = local_req.inner();
let mut response = Baz { responder: "just a custom" }
.respond_to(req)
.expect("response okay");
assert_eq!(response.status(), Status::Ok);
assert_eq!(response.content_type(), Some(ContentType::new("application", "x-custom")));
assert_eq!(response.body_string().await, Some("just a custom".into()));
}