#[macro_use] extern crate json; #[macro_use] extern crate noir; #[macro_use] mod base_test; test!(); use json::JsonValue; // Provided response bodies for request --------------------------------------- #[test] fn test_provided_response_with_response_body_text() { let actual = { API::get("/responses/one") .provide(responses![ EXAMPLE.get("/one").with_body("Response Body") ]) .expected_body("Response Body") .collect() }; assert_pass!(actual); } #[test] fn test_provided_response_with_response_body_raw() { let actual = { API::get("/responses/one") .provide(responses![ EXAMPLE.get("/one").with_body(vec![1, 2, 3, 4, 5]) ]) .expected_body(vec![1, 2, 3, 4, 5]) .collect() }; assert_pass!(actual); } #[test] fn test_provided_response_with_response_body_json() { let actual = { API::get("/responses/one") .provide(responses![ EXAMPLE.get("/one").with_body(object!{ "key" => "value" }) ]) .expected_body(object!{ "key" => "value" }) .collect() }; assert_pass!(actual); } // Request bodies from Responses ---------------------------------------------- #[test] fn test_provided_response_with_expected_body_text() { let actual = { API::post("/response/forward") .with_header(ContentType(Mime(TopLevel::Text, SubLevel::Plain, vec![]))) .provide(responses![ EXAMPLE.post("/forward").expected_body("Response Body") ]) .with_body("Response Body") .collect() }; assert_pass!(actual); } #[test] fn test_provided_response_with_expected_body_text_mismatch_diff_added() { let actual = { API::post("/response/forward") .with_header(ContentType(Mime(TopLevel::Text, SubLevel::Plain, vec![]))) .provide(responses![ EXAMPLE.post("/forward").expected_body("Response") ]) .with_body("Response Body") .collect() }; assert_fail!(r#"
Response Failure: POST request to \"http://localhost:4000/response/forward\" returned
1 error(s)
1)
Request Failure: POST response provided for \"https://example.com/forward\" returned
1 error(s)
1.1) Request does not match, expected: \"Response\" but got: \"
Response Body\" difference: \"Response Body\" "#, actual); } #[test] fn test_provided_response_with_expected_body_text_mismatch_diff_removed() { let actual = { API::post("/response/forward") .with_header(ContentType(Mime(TopLevel::Text, SubLevel::Plain, vec![]))) .provide(responses![ EXAMPLE.post("/forward").expected_body("Response Body") ]) .with_body("Response") .collect() }; assert_fail!(r#"
Response Failure: POST request to \"http://localhost:4000/response/forward\" returned
1 error(s)
1)
Request Failure: POST response provided for \"https://example.com/forward\" returned
1 error(s)
1.1) Request does not match, expected: \"Response Body\" but got: \"
Response\" difference: \"Response Body\" "#, actual); } #[test] fn test_provided_response_with_expected_body_text_invalid_utf8() { let actual = { API::post("/response/forward") .with_header(ContentType(Mime(TopLevel::Text, SubLevel::Plain, vec![]))) .provide(responses![ EXAMPLE.post("/forward").expected_body("Response Body") ]) .with_body([0xf8, 0xa1, 0xa1, 0xa1, 0xa1].to_vec()) .collect() }; assert_fail!(r#"
Response Failure: POST request to \"http://localhost:4000/response/forward\" returned
1 error(s)
1)
Request Failure: POST response provided for \"https://example.com/forward\" returned
1 error(s)
1.1) Request text body contains invalid UTF-8:
Utf8Error { valid_up_to: 0 } "#, actual); } // Raw Body ------------------------------------------------------------------- #[test] fn test_provided_response_with_expected_body_raw() { let actual = { API::post("/response/forward") .provide(responses![ EXAMPLE.post("/forward").expected_body(vec![ 0x00, 0xa0, 0xff, 0x80, 0x45, 0x13, 0x21, 0x78, 0x67, 0x08, 0x90, 0xca, 0xd4, 0xe5, 0xf4, 0x89 ]) ]) .with_body(vec![ 0x00, 0xa0, 0xff, 0x80, 0x45, 0x13, 0x21, 0x78, 0x67, 0x08, 0x90, 0xca, 0xd4, 0xe5, 0xf4, 0x89 ]) .collect() }; assert_pass!(actual); } #[test] fn test_provided_response_with_expected_body_raw_mismatch() { let actual = { API::post("/response/forward") .provide(responses![ EXAMPLE.post("/forward").expected_body(vec![ 0x00, 0xa0, 0xff, 0x80, 0x45, 0x13, 0x21, 0x78, 0x67, 0x08, 0x90, 0xca, 0xd4, 0xe5, 0xf4, 0x89 ]) ]) .with_body(vec![ 0x67, 0x08, 0x90, 0xca, 0xd4, 0xe5, 0xf4, 0x89, 0x00, 0xa0, 0xff, 0x80, 0x45, 0x13, 0x21, 0x78 ]) .collect() }; assert_fail!(r#"
Response Failure: POST request to \"http://localhost:4000/response/forward\" returned
1 error(s)
1)
Request Failure: POST response provided for \"https://example.com/forward\" returned
1 error(s)
1.1) Request raw body data does not match, expected the following 16 bytes: [0x00, 0xA0, 0xFF, 0x80, 0x45, 0x13, 0x21, 0x78, 0x67, 0x08, 0x90, 0xCA, 0xD4, 0xE5, 0xF4, 0x89] but got the following
16 bytes instead: [
0x67,
0x08,
0x90,
0xCA,
0xD4,
0xE5,
0xF4,
0x89,
0x00,
0xA0,
0xFF,
0x80,
0x45,
0x13,
0x21,
0x78] "#, actual); } // JSON Body ------------------------------------------------------------------ #[test] fn test_provided_response_with_expected_body_json() { let actual = { API::post("/response/forward") .provide(responses![ EXAMPLE.post("/forward").expected_body(object! { "key" => "value", "list" => vec![2, 3, 4], "some" => object! { "very" => object! { "deeply" => object! { "nested" => object! { "array" => array![true, false] } } } }, "missing" => JsonValue::Null }) ]) .with_body(object! { "key" => "value", "list" => vec![2, 3, 4], "some" => object! { "very" => object! { "deeply" => object! { "nested" => object! { "array" => array![true, false] } } } }, "missing" => JsonValue::Null }) .collect() }; assert_pass!(actual); } #[test] fn test_provided_response_with_expected_body_json_mismatch() { let actual = { API::post("/response/forward") .provide(responses![ EXAMPLE.post("/forward").expected_body(object! { "key" => "value", "list" => vec![2, 3, 4], "some" => object! { "very" => object! { "deeply" => object! { "nested" => object! { "array" => array![true, false] } } } }, "missing" => JsonValue::Null }) ]) .with_body(object! { "key" => "different value", "list" => vec![2, 3], "some" => object! { "very" => object! { "deeply" => object! { "nested" => object! { "array" => array![false, true, false] } } } }, "additional" => 32 }) .collect() }; assert_fail!(r#"
Response Failure: POST request to \"http://localhost:4000/response/forward\" returned
1 error(s)
1)
Request Failure: POST response provided for \"https://example.com/forward\" returned
1 error(s)
1.1) Request body json does not match, expected: - json.key: String does not match, expected: \"different value\" but got: \"
value\" difference: \"different value\" - json.list: Array with
2 item(s) does not match expected length of 3 - json.some.very.deeply.nested.array: Array with
3 item(s) does not match expected length of 2 - json.some.very.deeply.nested.array[0]: Boolean (
false) does not match expected value (true) - json.some.very.deeply.nested.array[1]: Boolean (
true) does not match expected value (false) - json: Object is missing
1 key(s) (
missing) "#, actual); } #[test] fn test_provided_response_with_expected_body_json_mismatch_exact() { let actual = { API::post("/response/forward") .provide(responses![ EXAMPLE.post("/forward").expected_exact_body(object! { "key" => "value", "list" => vec![2, 3, 4], "some" => object! { "very" => object! { "deeply" => object! { "nested" => object! { "array" => array![true, false] } } } }, "missing" => JsonValue::Null }) ]) .with_body(object! { "key" => "different value", "list" => vec![2, 3], "some" => object! { "very" => object! { "deeply" => object! { "nested" => object! { "array" => array![false, true, false] } } } }, "additional" => 32 }) .collect() }; assert_fail!(r#"
Response Failure: POST request to \"http://localhost:4000/response/forward\" returned
1 error(s)
1)
Request Failure: POST response provided for \"https://example.com/forward\" returned
1 error(s)
1.1) Request body json does not match, expected: - json.key: String does not match, expected: \"different value\" but got: \"
value\" difference: \"different value\" - json.list: Array with
2 item(s) does not match expected length of 3 - json.some.very.deeply.nested.array: Array with
3 item(s) does not match expected length of 2 - json.some.very.deeply.nested.array[0]: Boolean (
false) does not match expected value (true) - json.some.very.deeply.nested.array[1]: Boolean (
true) does not match expected value (false) - json: Object is missing
1 key(s) (
missing) - json: Object has
1 additional unexpected key(s) (
additional) "#, actual); } #[test] fn test_provided_response_with_expected_body_json_invalid() { let actual = { API::post("/response/forward") .with_header(ContentType(Mime(TopLevel::Application, SubLevel::Json, vec![]))) .provide(responses![ EXAMPLE.post("/forward").expected_body(object! { "key" => "value" }) ]) .with_body("{\"foo\": }") .collect() }; assert_fail!(r#"
Response Failure: POST request to \"http://localhost:4000/response/forward\" returned
1 error(s)
1)
Request Failure: POST response provided for \"https://example.com/forward\" returned
1 error(s)
1.1) Request body json is invalid:
UnexpectedCharacter { ch: \'}\', line: 1, column: 9 } "#, actual); } #[test] fn test_provided_response_with_expected_body_json_invalid_utf8() { let actual = { API::post("/response/forward") .with_header(ContentType(Mime(TopLevel::Application, SubLevel::Json, vec![]))) .provide(responses![ EXAMPLE.post("/forward").expected_body(object! { "key" => "value" }) ]) .with_body([0xf8, 0xa1, 0xa1, 0xa1, 0xa1].to_vec()) .collect() }; assert_fail!(r#"
Response Failure: POST request to \"http://localhost:4000/response/forward\" returned
1 error(s)
1)
Request Failure: POST response provided for \"https://example.com/forward\" returned
1 error(s)
1.1) Request body json contains invalid UTF-8:
Utf8Error { valid_up_to: 0 } "#, actual); } #[test] fn test_provided_response_with_expected_body_json_compare_depth_one() { use noir::Options; let actual = { API::post("/response/forward") .provide(responses![ EXAMPLE.post("/forward") .with_options(Options { // This will only enter the first level after the top level json_compare_depth: 1, .. Default::default() }) .expected_body(object! { "key" => "otherValue", "deep" => object! { "compare" => "bar" } }) ]) .with_body(object! { "key" => "value", "deep" => object! { "compare" => "foo" } }) .collect() }; assert_fail!(r#"
Response Failure: POST request to \"http://localhost:4000/response/forward\" returned
1 error(s)
1)
Request Failure: POST response provided for \"https://example.com/forward\" returned
1 error(s)
1.1) Request body json does not match, expected: - json.key: String does not match, expected: \"value\" but got: \"
otherValue\" difference: \"value otherValue\" "#, actual); } #[test] fn test_provided_response_with_expected_body_json_compare_depth_zero() { use noir::Options; let actual = { API::post("/response/forward") .provide(responses![ EXAMPLE.post("/forward") .with_options(Options { // This will perform no comparisons at all json_compare_depth: 0, .. Default::default() }) .expected_body(object! { "key" => "otherValue", "deep" => object! { "compare" => "bar" } }) ]) .with_body(object! { "key" => "value", "deep" => object! { "compare" => "foo" } }) .collect() }; assert_pass!(actual); } // Form Body ------------------------------------------------------------------ #[test] fn test_provided_response_with_expected_body_form() { use std::fs::File; let actual = { API::post("/response/forward") .provide(responses![ EXAMPLE.post("/forward").expected_body(form! { "field" => "someValue\n", "array[]" => vec!["1", "2", "3", "4", "5\n"], "vec_file" => ( "file.bin", Mime(TopLevel::Application, SubLevel::OctetStream, vec![]), vec![1, 2, 3, 4, 5, 6, 7, 8] ), "str_file" => ( "readme.md", Mime(TopLevel::Text, SubLevel::Plain, vec![]), "Hello World" ), "fs_file" => ( "form_test.md", Mime(TopLevel::Text, SubLevel::Plain, vec![]), File::open("./tests/form_test.md").unwrap() ) }) ]) .with_body(form! { "field" => "someValue\n", "array[]" => vec!["1", "2", "3", "4", "5\n"], "vec_file" => ( "file.bin", Mime(TopLevel::Application, SubLevel::OctetStream, vec![]), vec![1, 2, 3, 4, 5, 6, 7, 8] ), "str_file" => ( "readme.md", Mime(TopLevel::Text, SubLevel::Plain, vec![]), "Hello World" ), "fs_file" => ( "form_test.md", Mime(TopLevel::Text, SubLevel::Plain, vec![]), File::open("./tests/form_test.md").unwrap() ) }) .collect() }; assert_pass!(actual); } #[test] fn test_provided_response_with_expected_body_form_mismatch() { let actual = { API::post("/response/forward") .provide(responses![ EXAMPLE.post("/forward").expected_body(form! { "field" => "someValue\n", "missingField" => "value", "mismatchedType" => "plain", "array[]" => vec!["1", "2", "3", "4", "5\n"], "vec_file" => ( "file.bin", Mime(TopLevel::Application, SubLevel::OctetStream, vec![]), vec![1, 2, 3, 4, 5, 6, 7, 8] ), "str_file" => ( "readme.md", Mime(TopLevel::Text, SubLevel::Plain, vec![]), "Hello World" ) }) ]) .with_body(form! { "field" => "different someValue\n", "additionalField" => "value", "mismatchedType" => vec!["array"], "array[]" => vec!["1", "2", "3", "5\n"], "vec_file" => ( "other.bin", Mime(TopLevel::Application, SubLevel::OctetStream, vec![]), vec![1, 2, 3, 4, 5, 6, 7, 8] ), "str_file" => ( "readme.md", Mime(TopLevel::Text, SubLevel::Html, vec![]), "Hello World" ) }) .collect() }; assert_fail!(r#"
Response Failure: POST request to \"http://localhost:4000/response/forward\" returned
1 error(s)
1)
Request Failure: POST response provided for \"https://example.com/forward\" returned
1 error(s)
1.1) Request body form data does not match, expected: - form.array[]: Array with
4 item(s) does not match expected length of 5 - form.array[][3]: ArrayItem value does not match, expected: \"5\\n\" but got: \"
4\" difference: \"5\\n 4\" - form.field: Field value does not match, expected: \"different someValue\\n\" but got: \"
someValue\\n\" difference: \"different someValue\\n\" - form.mismatchedType: Field value does not match, expected: \"array\" but got: \"
plain\" difference: \"array plain\" - form.str_file: Mimetype (
text/html) does not match expected value (text/plain) - form.vec_file: Filename (\"
other.bin\") does not match expected value (\"file.bin\") - form: Is missing
1 plain field(s) (
missingField) "#, actual); } #[test] fn test_provided_response_with_expected_body_form_mismatch_exact() { let actual = { API::post("/response/forward") .provide(responses![ EXAMPLE.post("/forward").expected_exact_body(form! { "field" => "someValue\n", "missingField" => "value", "mismatchedType" => "plain", "array[]" => vec!["1", "2", "3", "4", "5\n"], "vec_file" => ( "file.bin", Mime(TopLevel::Application, SubLevel::OctetStream, vec![]), vec![1, 2, 3, 4, 5, 6, 7, 8] ), "str_file" => ( "readme.md", Mime(TopLevel::Text, SubLevel::Plain, vec![]), "Hello World" ) }) ]) .with_body(form! { "field" => "different someValue\n", "additionalField" => "value", "mismatchedType" => vec!["array"], "array[]" => vec!["1", "2", "3", "5\n"], "vec_file" => ( "other.bin", Mime(TopLevel::Application, SubLevel::OctetStream, vec![]), vec![1, 2, 3, 4, 5, 6, 7, 8] ), "str_file" => ( "readme.md", Mime(TopLevel::Text, SubLevel::Html, vec![]), "Hello World" ) }) .collect() }; assert_fail!(r#"
Response Failure: POST request to \"http://localhost:4000/response/forward\" returned
1 error(s)
1)
Request Failure: POST response provided for \"https://example.com/forward\" returned
1 error(s)
1.1) Request body form data does not match, expected: - form.array[]: Array with
4 item(s) does not match expected length of 5 - form.array[][3]: ArrayItem value does not match, expected: \"5\\n\" but got: \"
4\" difference: \"5\\n 4\" - form.field: Field value does not match, expected: \"different someValue\\n\" but got: \"
someValue\\n\" difference: \"different someValue\\n\" - form.mismatchedType: Field value does not match, expected: \"array\" but got: \"
plain\" difference: \"array plain\" - form.str_file: Mimetype (
text/html) does not match expected value (text/plain) - form.vec_file: Filename (\"
other.bin\") does not match expected value (\"file.bin\") - form: Is missing
1 plain field(s) (
missingField) - form: Has
1 additional unexpected plain field(s) (
additionalField) "#, actual); } // Headers from Body Type ----------------------------------------------------- #[test] fn test_provided_response_set_header_from_body_raw() { let actual = { API::get("/responses/one") .provide(responses![ EXAMPLE.get("/one").with_body(vec![1, 2, 3, 4, 5]) ]) .expected_header(ContentType( Mime(TopLevel::Application, SubLevel::OctetStream, vec![]) )) .expected_body(vec![1, 2, 3, 4, 5]) .collect() }; assert_pass!(actual); } #[test] fn test_provided_response_set_header_from_body_text() { let actual = { API::get("/responses/one") .provide(responses![ EXAMPLE.get("/one").with_body("Hello World") ]) .expected_header(ContentType( Mime(TopLevel::Text, SubLevel::Plain, vec![]) )) .expected_body("Hello World") .collect() }; assert_pass!(actual); } #[test] fn test_provided_response_set_header_from_body_json() { let actual = { API::get("/responses/one") .provide(responses![ EXAMPLE.get("/one").with_body(object! { "key" => "value" }) ]) .expected_header(ContentType( Mime(TopLevel::Application, SubLevel::Json, vec![]) )) .expected_body(object! { "key" => "value" }) .collect() }; assert_pass!(actual); } #[test] fn test_provided_response_set_header_from_body_form() { let actual = { API::get("/responses/one") .provide(responses![ EXAMPLE.get("/one").with_body(form! { "field" => "value" }) ]) .expected_header(ContentType( Mime(TopLevel::Application, SubLevel::WwwFormUrlEncoded, vec![]) )) .collect() }; assert_pass!(actual); } #[test] fn test_provided_response_set_header_from_body_form_with_file() { use hyper::mime::{Attr, Value}; let actual = { API::get("/responses/one") .provide(responses![ EXAMPLE.get("/one").with_body(form! { "file" => ( "filename", Mime(TopLevel::Text, SubLevel::Plain, vec![]), "Data" ) }) ]) .expected_header(ContentType( Mime(TopLevel::Application, SubLevel::FormData, vec![ (Attr::Boundary, Value::Ext("boundary12345".to_string())) ]) )) .collect() }; assert_pass!(actual); } // Body Type Header Override -------------------------------------------------- #[test] fn test_provided_response_override_header_from_body() { let actual = { API::get("/responses/one") .provide(responses![ EXAMPLE.get("/one") .with_header(ContentType( Mime(TopLevel::Text, SubLevel::Plain, vec![]) )) .with_body(object! { "key" => "value" }) ]) .expected_header(ContentType( Mime(TopLevel::Text, SubLevel::Plain, vec![]) )) .expected_body("{\"key\":\"value\"}") .collect() }; assert_pass!(actual); } #[test] fn test_provided_response_override_header_from_form() { let actual = { API::get("/responses/one") .provide(responses![ EXAMPLE.get("/one") .with_header(ContentType( Mime(TopLevel::Text, SubLevel::Plain, vec![]) )) .with_body(form! { "field" => "value" }) ]) .expected_header(ContentType( Mime(TopLevel::Text, SubLevel::Plain, vec![]) )) .collect() }; assert_pass!(actual); } #[test] fn test_provided_response_override_header_from_form_with_file() { let actual = { API::get("/responses/one") .provide(responses![ EXAMPLE.get("/one") .with_header(ContentType( Mime(TopLevel::Text, SubLevel::Plain, vec![]) )) .with_body(form! { "file" => ( "filename", Mime(TopLevel::Text, SubLevel::Plain, vec![]), "Data" ) }) ]) .expected_header(ContentType( Mime(TopLevel::Text, SubLevel::Plain, vec![]) )) .collect() }; assert_pass!(actual); }