Open
Description
Testing forms in Rocket is currently an entirely manual process:
let client = Client::tracked(rocket).unwrap();
let response = client.post("/")
.header(ContentType::Form)
.body("field=value&is+it=a+cat%3F")
.dispatch();
With the addition of multipart form support, form testing verbosity is even further exacerbated:
let client = Client::tracked(rocket).unwrap();
let ct = "multipart/form-data; boundary=X-BOUNDARY"
.parse::<ContentType>()
.unwrap();
let body = &[
"--X-BOUNDARY",
r#"Content-Disposition: form-data; name="names[]""#,
"",
"abcd",
"--X-BOUNDARY",
r#"Content-Disposition: form-data; name="names[]""#,
"",
"123",
"--X-BOUNDARY",
r#"Content-Disposition: form-data; name="file"; filename="foo.txt""#,
"Content-Type: text/plain",
"",
"hi there",
"--X-BOUNDARY--",
"",
].join("\r\n");
let response = client.post("/")
.header(ct)
.body(body)
.dispatch();
Rocket should make testing applications with forms a much simpler task.
Here's how we might hope testing the above forms would look:
let client = Client::tracked(rocket).unwrap();
let response = client.post("/")
.form(&[("field", "value"), ("is it", "a cat?")])
.dispatch();
let client = Client::tracked(rocket).unwrap();
let response = client.post("/")
.form(LocalForm::new()
.field("names[]", "abcd")
.field("names[]", "123")
.file("foo.txt", ContentType::Plain, "hi there"))
.dispatch();
An API enabling this might resemble:
impl Client {
pub fn form<F: Into<LocalForm>>(&mut self, form: F) -> &mut Self {
let form = form.into();
self.set_header(form.content_type());
self.set_body(form.body_data());
self
}
}
struct LocalForm { /* .. */ }
impl LocalForm {
pub fn new() -> Self;
/// A percent-decoded `name` and `value`.
pub fn field<'v, N, V>(mut self, name: N, value: V) -> Self
where N: Into<NameBuf<'v>>, V: AsRef<str>;
/// Adds all of the `fields` to `self`.
pub fn fields<'v, I, F>(mut self, fields: I) -> Self
where I: Iterator<Item = F>, F: Into<ValueField<'v>>;
/// A percent-encoded `name` and `value`.
pub fn raw_field(mut self, name: &'v RawStr, value: &'v RawStr) -> Self;
/// Adds a field for the file with name `file_name`, content-type `ct`, and
/// file contents `data`.
pub fn file<'v, N, V>(mut self, file_name: N, ct: ContentType, data: V) -> Self
where N: Into<Option<&'v str>>, V: AsRef<[u8]>;
/// Add a data field with content-type `ct` and binary `data`.
pub fn data<'v, V>(mut self, ct: ContentType, data: V) -> Self
where V: AsRef<[u8]>;
/// The full content-type for this form.
pub fn content_type(&self) -> ContentType;
/// The full body data for this form.
pub fn body_data(&self) -> Vec<u8>;
}
impl<'v, F: Into<ValueField<'v>>, I: Iterator<Item = F>> From<I> for LocalForm { /* .. */ }
Metadata
Metadata
Assignees
Type
Projects
Status
Ready