128 lines
4.6 KiB
Rust
128 lines
4.6 KiB
Rust
use wip_https::http::{Method, Request, StatusCode};
|
|
use wip_https::{Endpoint, RequestMetadataError, Route, validate_http_request};
|
|
|
|
#[test]
|
|
fn endpoint_is_https_absolute_queryless_and_canonical() {
|
|
let endpoint = Endpoint::parse("https://example.test/root/prefix").unwrap();
|
|
assert_eq!(endpoint.to_string(), "https://example.test/root/prefix/");
|
|
|
|
let expected = [
|
|
(Route::Fetch, "https://example.test/root/prefix/v1/fetch"),
|
|
(
|
|
Route::FetchTree,
|
|
"https://example.test/root/prefix/v1/fetch_tree",
|
|
),
|
|
(
|
|
Route::FetchInterface,
|
|
"https://example.test/root/prefix/v1/fetch_interface",
|
|
),
|
|
(
|
|
Route::CallOperation,
|
|
"https://example.test/root/prefix/v1/call_operation",
|
|
),
|
|
(Route::Batch, "https://example.test/root/prefix/v1/batch"),
|
|
];
|
|
for (route, url) in expected {
|
|
assert_eq!(endpoint.route(route).as_str(), url);
|
|
assert_eq!(
|
|
endpoint.recognize(&wip_https::url::Url::parse(url).unwrap()),
|
|
Some(route)
|
|
);
|
|
}
|
|
assert_eq!(
|
|
endpoint.recognize(
|
|
&wip_https::url::Url::parse("https://example.test/root/prefix/v1/fetch?path=/items")
|
|
.unwrap()
|
|
),
|
|
None
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn routes_never_mix_worldspace_paths_into_endpoint_prefixes() {
|
|
let endpoint = Endpoint::parse("https://example.test/wip/%E4%B8%96%E7%95%8C/").unwrap();
|
|
let route = endpoint.route(Route::Fetch);
|
|
assert_eq!(route.path(), "/wip/%E4%B8%96%E7%95%8C/v1/fetch");
|
|
assert!(!route.as_str().contains("items"));
|
|
}
|
|
|
|
#[test]
|
|
fn inbound_http_metadata_enforces_post_route_and_json() {
|
|
let endpoint = Endpoint::parse("https://example.test/wip").unwrap();
|
|
let valid = Request::builder()
|
|
.method(Method::POST)
|
|
.uri("/wip/v1/fetch")
|
|
.header("content-type", "application/json; charset=utf-8")
|
|
.body(Vec::<u8>::new())
|
|
.unwrap();
|
|
assert!(validate_http_request(&endpoint, Route::Fetch, &valid).is_ok());
|
|
|
|
let wrong_method = Request::builder()
|
|
.method(Method::GET)
|
|
.uri("/wip/v1/fetch")
|
|
.header("content-type", "application/json")
|
|
.body(Vec::<u8>::new())
|
|
.unwrap();
|
|
assert!(validate_http_request(&endpoint, Route::Fetch, &wrong_method).is_err());
|
|
|
|
let wrong_route = Request::builder()
|
|
.method(Method::POST)
|
|
.uri("/wip/v1/fetch_tree")
|
|
.header("content-type", "application/json")
|
|
.body(Vec::<u8>::new())
|
|
.unwrap();
|
|
assert!(validate_http_request(&endpoint, Route::Fetch, &wrong_route).is_err());
|
|
|
|
for accept in [
|
|
"text/plain, */*;q=1, application/json;q=0",
|
|
"application/json; charset=utf-16",
|
|
"application/json; profile=future",
|
|
] {
|
|
let incompatible_accept = Request::builder()
|
|
.method(Method::POST)
|
|
.uri("/wip/v1/fetch")
|
|
.header("content-type", "application/json")
|
|
.header("accept", accept)
|
|
.body(Vec::<u8>::new())
|
|
.unwrap();
|
|
let error =
|
|
validate_http_request(&endpoint, Route::Fetch, &incompatible_accept).unwrap_err();
|
|
assert!(matches!(&error, RequestMetadataError::NotAcceptable));
|
|
assert_eq!(error.status(), StatusCode::NOT_ACCEPTABLE);
|
|
}
|
|
|
|
for accept in [
|
|
"application/json; charset=UTF-8",
|
|
"application/json; q=1; profile=accept-extension",
|
|
] {
|
|
let compatible_accept = Request::builder()
|
|
.method(Method::POST)
|
|
.uri("/wip/v1/fetch")
|
|
.header("content-type", "application/json")
|
|
.header("accept", accept)
|
|
.body(Vec::<u8>::new())
|
|
.unwrap();
|
|
assert!(validate_http_request(&endpoint, Route::Fetch, &compatible_accept).is_ok());
|
|
}
|
|
|
|
let unsupported_media_type = Request::builder()
|
|
.method(Method::POST)
|
|
.uri("/wip/v1/fetch")
|
|
.header("content-type", "text/plain")
|
|
.header("accept", "application/json")
|
|
.body(Vec::<u8>::new())
|
|
.unwrap();
|
|
let error =
|
|
validate_http_request(&endpoint, Route::Fetch, &unsupported_media_type).unwrap_err();
|
|
assert!(matches!(&error, RequestMetadataError::UnsupportedMediaType));
|
|
assert_eq!(error.status(), StatusCode::UNSUPPORTED_MEDIA_TYPE);
|
|
}
|
|
|
|
#[test]
|
|
fn invalid_endpoint_components_are_rejected() {
|
|
assert!(Endpoint::parse("http://example.test/wip").is_err());
|
|
assert!(Endpoint::parse("/relative").is_err());
|
|
assert!(Endpoint::parse("https://example.test/wip?q=1").is_err());
|
|
assert!(Endpoint::parse("https://example.test/wip#fragment").is_err());
|
|
}
|