use super::*;
fn headers_of(request: &Request) -> Vec<(String, String)> {
request.options.headers.clone().unwrap_or_default()
}
#[test]
fn the_outermost_explicit_value_wins() {
let inner = Request::new("https://example.com/")
.timeout(Duration::from_secs(1))
.build()
.expect("a valid target");
let outer = Request::new(inner)
.timeout(Duration::from_secs(3))
.build()
.expect("layering over a request");
assert_eq!(outer.options.timeout, Some(Duration::from_secs(3)));
}
#[test]
fn an_untouched_setting_is_inherited() {
let inner = Request::new("https://example.com/")
.timeout(Duration::from_secs(1))
.method("POST")
.build()
.expect("a valid target");
let outer = Request::new(inner)
.integrity("sha256-abc")
.build()
.expect("layering over a request");
assert_eq!(outer.options.timeout, Some(Duration::from_secs(1)));
assert_eq!(outer.options.method.as_deref(), Some("POST"));
assert_eq!(outer.options.integrity.as_deref(), Some("sha256-abc"));
}
#[test]
fn wrapping_a_request_carries_its_url_through() {
let inner = Request::new("https://example.com/deep/path?q=1")
.build()
.expect("a valid target");
let outer = Request::new(inner)
.method("HEAD")
.build()
.expect("layering");
assert_eq!(outer.url.as_str(), "https://example.com/deep/path?q=1");
}
#[test]
fn headers_merge_by_name() {
let inner = Request::new("https://example.com/")
.header("x-keep", "inner")
.header("x-replace", "inner")
.build()
.expect("a valid target");
let outer = Request::new(inner)
.header("x-replace", "outer")
.header("x-add", "outer")
.build()
.expect("layering over a request");
let mut headers = headers_of(&outer);
headers.sort();
assert_eq!(
headers,
vec![
("x-add".to_owned(), "outer".to_owned()),
("x-keep".to_owned(), "inner".to_owned()),
("x-replace".to_owned(), "outer".to_owned()),
]
);
}
#[test]
fn removing_a_header_removes_what_is_underneath() {
let inner = Request::new("https://example.com/")
.header("x-gone", "inner")
.build()
.expect("a valid target");
let outer = Request::new(inner)
.remove_header("X-Gone")
.build()
.expect("layering over a request");
assert!(headers_of(&outer).is_empty(), "the name was removed");
}
#[test]
fn the_later_call_wins_on_one_builder() {
let request = Request::new("https://example.com/")
.method("POST")
.method("PUT")
.build()
.expect("a valid target");
assert_eq!(request.options.method.as_deref(), Some("PUT"));
}
#[test]
fn an_http_request_is_a_target() {
let http = http::Request::builder()
.method(http::Method::POST)
.uri("https://example.com/submit")
.header("x-from", "ecosystem")
.body(Bytes::from_static(b"payload"))
.expect("a valid http request");
let request = Request::new(http).build().expect("it converts");
assert_eq!(request.url.as_str(), "https://example.com/submit");
assert_eq!(request.options.method.as_deref(), Some("POST"));
assert_eq!(
headers_of(&request),
vec![("x-from".to_owned(), "ecosystem".to_owned())]
);
assert!(request.try_clone().is_some(), "a buffered body copies");
}
#[test]
fn a_layer_beats_what_an_http_request_carried() {
let http = http::Request::builder()
.method(http::Method::POST)
.uri("https://example.com/")
.body(Bytes::new())
.expect("a valid http request");
let request = Request::new(http)
.method(http::Method::PUT)
.build()
.expect("layering over it");
assert_eq!(request.options.method.as_deref(), Some("PUT"));
}
#[test]
fn an_invalid_header_surfaces_at_build() {
let err = Request::new("https://example.com/")
.header("not a header name", "value")
.build()
.expect_err("the name is not a header name");
assert_eq!(err.kind(), FaithErrorKind::InvalidHeader);
}
#[test]
fn the_first_failure_is_the_one_reported() {
let err = Request::new("not a url")
.header("not a header name", "value")
.build()
.expect_err("both are wrong");
assert_eq!(err.kind(), FaithErrorKind::InvalidUrl);
}
#[test]
fn an_unparseable_target_surfaces_at_build() {
let builder = Request::new("not a url");
let err = builder.build().expect_err("the target does not parse");
assert_eq!(err.kind(), FaithErrorKind::InvalidUrl);
}
#[test]
fn try_clone_copies_what_it_can() {
let buffered = Request::new("https://example.com/")
.body(Bytes::from_static(b"body"))
.build()
.expect("a valid target");
assert!(buffered.try_clone().is_some());
let streamed = Request::new("https://example.com/")
.body_stream(futures::stream::empty())
.build()
.expect("a valid target");
assert!(
streamed.try_clone().is_none(),
"a stream is consumable once"
);
}