#![deny(clippy::all)]
mod fixtures {
pub mod get_server;
}
use fixtures::get_server::spawn;
#[tokio::test]
async fn conditional_no_headers_existing_returns_200() {
let addr = spawn().await;
let resp = reqwest::get(format!("http://{addr}/cp/conditional/42"))
.await
.expect("request failed");
assert_eq!(resp.status(), 200);
}
#[tokio::test]
async fn conditional_no_headers_nonexistent_returns_404() {
let addr = spawn().await;
let resp = reqwest::get(format!("http://{addr}/cp/conditional/999"))
.await
.expect("request failed");
assert_eq!(resp.status(), 404);
}
#[tokio::test]
async fn conditional_200_includes_etag_and_last_modified() {
let addr = spawn().await;
let resp = reqwest::get(format!("http://{addr}/cp/conditional/42"))
.await
.expect("request failed");
assert_eq!(resp.status(), 200);
assert_eq!(resp.headers()["etag"], "\"known-etag-42\"");
assert_eq!(
resp.headers()["last-modified"],
"Wed, 01 Jan 2025 00:00:00 GMT"
);
assert_eq!(resp.headers()["content-type"], "application/json");
}
#[tokio::test]
async fn conditional_if_none_match_star_existing_returns_304() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/conditional/42"))
.header("If-None-Match", "*")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 304);
}
#[tokio::test]
async fn conditional_if_none_match_star_nonexistent_returns_404() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/conditional/999"))
.header("If-None-Match", "*")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 404);
}
#[tokio::test]
async fn conditional_if_none_match_matching_etag_returns_304() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/conditional/42"))
.header("If-None-Match", "\"known-etag-42\"")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 304);
}
#[tokio::test]
async fn conditional_if_none_match_nonmatching_etag_returns_200() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/conditional/42"))
.header("If-None-Match", "\"wrong-etag\"")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 200);
}
#[tokio::test]
async fn conditional_if_none_match_list_with_match_returns_304() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/conditional/42"))
.header("If-None-Match", "\"other\", \"known-etag-42\", \"another\"")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 304);
}
#[tokio::test]
async fn conditional_if_match_star_existing_returns_200() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/conditional/42"))
.header("If-Match", "*")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 200);
}
#[tokio::test]
async fn conditional_if_match_matching_etag_returns_200() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/conditional/42"))
.header("If-Match", "\"known-etag-42\"")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 200);
}
#[tokio::test]
async fn conditional_if_match_nonmatching_etag_returns_412() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/conditional/42"))
.header("If-Match", "\"wrong-etag\"")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 412);
}
#[tokio::test]
async fn conditional_if_match_nonmatching_nonexistent_returns_404() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/conditional/999"))
.header("If-Match", "\"wrong-etag\"")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 404);
}
#[tokio::test]
async fn conditional_if_unmodified_since_future_returns_200() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/conditional/42"))
.header("If-Unmodified-Since", "Sun, 01 Jun 2025 00:00:00 GMT")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 200);
}
#[tokio::test]
async fn conditional_if_unmodified_since_past_returns_412() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/conditional/42"))
.header("If-Unmodified-Since", "Mon, 01 Jan 2024 00:00:00 GMT")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 412);
}
#[tokio::test]
async fn conditional_if_unmodified_since_skipped_when_if_match_present() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/conditional/42"))
.header("If-Match", "*")
.header("If-Unmodified-Since", "Mon, 01 Jan 2024 00:00:00 GMT")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 200);
}
#[tokio::test]
async fn conditional_if_modified_since_past_returns_200() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/conditional/42"))
.header("If-Modified-Since", "Mon, 01 Jan 2024 00:00:00 GMT")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 200);
}
#[tokio::test]
async fn conditional_if_modified_since_future_returns_304() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/conditional/42"))
.header("If-Modified-Since", "Sun, 01 Jun 2025 00:00:00 GMT")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 304);
}
#[tokio::test]
async fn conditional_if_modified_since_skipped_when_if_none_match_present() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/conditional/42"))
.header("If-None-Match", "\"wrong-etag\"")
.header("If-Modified-Since", "Sun, 01 Jun 2025 00:00:00 GMT")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 200);
}
#[tokio::test]
async fn conditional_if_match_fails_before_if_none_match() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/conditional/42"))
.header("If-Match", "\"wrong-etag\"")
.header("If-None-Match", "\"known-etag-42\"")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 412);
}
#[tokio::test]
async fn range_no_header_existing_returns_200_with_accept_ranges() {
let addr = spawn().await;
let resp = reqwest::get(format!("http://{addr}/cp/range/42"))
.await
.expect("request failed");
assert_eq!(resp.status(), 200);
assert_eq!(resp.headers()["accept-ranges"], "bytes");
}
#[tokio::test]
async fn range_no_header_nonexistent_returns_404() {
let addr = spawn().await;
let resp = reqwest::get(format!("http://{addr}/cp/range/999"))
.await
.expect("request failed");
assert_eq!(resp.status(), 404);
}
#[tokio::test]
async fn range_valid_byte_range_returns_206() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/range/42"))
.header("Range", "bytes=0-4")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 206);
assert!(
resp.headers()["content-range"]
.to_str()
.unwrap()
.starts_with("bytes 0-4/")
);
let body = resp.text().await.expect("body read failed");
assert_eq!(body.len(), 5); }
#[tokio::test]
async fn range_unsatisfiable_returns_416() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/range/42"))
.header("Range", "bytes=9999-10000")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 416);
assert!(
resp.headers()["content-range"]
.to_str()
.unwrap()
.starts_with("bytes */")
);
}
#[tokio::test]
async fn range_valid_range_nonexistent_returns_404() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/range/999"))
.header("Range", "bytes=0-4")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 404);
}
#[tokio::test]
async fn range_suffix_returns_206() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/range/42"))
.header("Range", "bytes=-5")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 206);
let body = resp.text().await.expect("body read failed");
assert_eq!(body.len(), 5);
}
#[tokio::test]
async fn range_open_ended_returns_206() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/range/42"))
.header("Range", "bytes=0-")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 206);
}
#[tokio::test]
async fn range_if_range_matching_etag_returns_206() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/range/42"))
.header("Range", "bytes=0-4")
.header("If-Range", "\"known-etag-42\"")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 206);
}
#[tokio::test]
async fn range_if_range_nonmatching_etag_returns_200() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/range/42"))
.header("Range", "bytes=0-4")
.header("If-Range", "\"stale-etag\"")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 200);
}
#[tokio::test]
async fn range_if_range_nonexistent_returns_404() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/range/999"))
.header("Range", "bytes=0-4")
.header("If-Range", "\"known-etag-999\"")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 404);
}
#[tokio::test]
async fn range_if_range_without_range_ignored() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/range/42"))
.header("If-Range", "\"known-etag-42\"")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 200);
}
#[tokio::test]
async fn negotiated_json_accept_existing_returns_200() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/negotiated/42"))
.header("Accept", "application/json")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 200);
assert_eq!(resp.headers()["content-type"], "application/json");
}
#[tokio::test]
async fn negotiated_no_accept_header_returns_200() {
let addr = spawn().await;
let resp = reqwest::get(format!("http://{addr}/cp/negotiated/42"))
.await
.expect("request failed");
assert_eq!(resp.status(), 200);
}
#[tokio::test]
async fn negotiated_xml_only_returns_406() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/negotiated/42"))
.header("Accept", "application/xml")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 406);
}
#[tokio::test]
async fn negotiated_nonexistent_returns_404() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/negotiated/999"))
.header("Accept", "application/json")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 404);
}
#[tokio::test]
async fn negotiated_wildcard_accept_returns_200() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/negotiated/42"))
.header("Accept", "*/*")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 200);
}
#[tokio::test]
async fn normalized_existing_id_returns_404() {
let addr = spawn().await;
let resp = reqwest::get(format!("http://{addr}/cp/normalized/42"))
.await
.expect("request failed");
assert_eq!(resp.status(), 404);
}
#[tokio::test]
async fn normalized_nonexistent_id_returns_404() {
let addr = spawn().await;
let resp = reqwest::get(format!("http://{addr}/cp/normalized/999"))
.await
.expect("request failed");
assert_eq!(resp.status(), 404);
}
#[tokio::test]
async fn normalized_with_conditional_headers_still_returns_404() {
let addr = spawn().await;
let client = reqwest::Client::new();
let resp = client
.get(format!("http://{addr}/cp/normalized/42"))
.header("If-None-Match", "*")
.send()
.await
.expect("request failed");
assert_eq!(resp.status(), 404);
}