Paul Campbell
41973abe18
Changed the way URLs were matched, by breaking them down into their component parts, so that we can match query parameters when they are speciifed in either the URL string, or via the `query` method, or both.
533 lines
13 KiB
Rust
533 lines
13 KiB
Rust
use http::StatusCode;
|
|
//
|
|
use kxio::net::{Error, MockNet, Net};
|
|
|
|
use assert2::let_assert;
|
|
|
|
#[tokio::test]
|
|
async fn test_get_url() {
|
|
//given
|
|
let mock_net = kxio::net::mock();
|
|
|
|
let url = "https://www.example.com";
|
|
let url_alpha = format!("{url}/alpha");
|
|
let url_beta = format!("{url}/beta");
|
|
|
|
mock_net
|
|
.on()
|
|
.get(&url_alpha)
|
|
.respond(StatusCode::OK)
|
|
.body("Get OK alpha")
|
|
.expect("mock alpha");
|
|
mock_net
|
|
.on()
|
|
.get(&url_beta)
|
|
.respond(StatusCode::OK)
|
|
.body("Get OK beta")
|
|
.expect("mock beta");
|
|
mock_net
|
|
.on()
|
|
.get(url)
|
|
.respond(StatusCode::OK)
|
|
.body("Get OK")
|
|
.expect("mock");
|
|
let net = Net::from(mock_net);
|
|
|
|
//when
|
|
let response_alpha = net.get(url_alpha).send().await.expect("response alpha");
|
|
let response_beta = net.get(url_beta).send().await.expect("response beta");
|
|
let response = net.get(url).send().await.expect("response");
|
|
|
|
//then
|
|
assert_eq!(response_alpha.status(), http::StatusCode::OK);
|
|
assert_eq!(
|
|
response_alpha.bytes().await.expect("response body alpha"),
|
|
"Get OK alpha"
|
|
);
|
|
assert_eq!(response_beta.status(), http::StatusCode::OK);
|
|
assert_eq!(
|
|
response_beta.bytes().await.expect("response body beta"),
|
|
"Get OK beta"
|
|
);
|
|
assert_eq!(response.status(), http::StatusCode::OK);
|
|
assert_eq!(response.bytes().await.expect("response body"), "Get OK");
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_post_url() {
|
|
//given
|
|
let net = kxio::net::mock();
|
|
let client = net.client();
|
|
|
|
let url = "https://www.example.com";
|
|
|
|
net.on()
|
|
.post(url)
|
|
.respond(StatusCode::OK)
|
|
.body("post OK")
|
|
.expect("mock");
|
|
|
|
//when
|
|
let response = Net::from(net)
|
|
.send(client.post(url))
|
|
.await
|
|
.expect("reponse");
|
|
|
|
//then
|
|
assert_eq!(response.status(), http::StatusCode::OK);
|
|
assert_eq!(response.bytes().await.expect("response body"), "post OK");
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_put_url() {
|
|
//given
|
|
let net = kxio::net::mock();
|
|
let client = net.client();
|
|
|
|
let url = "https://www.example.com";
|
|
|
|
net.on()
|
|
.put(url)
|
|
.respond(StatusCode::OK)
|
|
.body("put OK")
|
|
.expect("mock");
|
|
|
|
//when
|
|
let response = Net::from(net).send(client.put(url)).await.expect("reponse");
|
|
|
|
//then
|
|
assert_eq!(response.status(), http::StatusCode::OK);
|
|
assert_eq!(response.bytes().await.expect("response body"), "put OK");
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_delete_url() {
|
|
//given
|
|
let net = kxio::net::mock();
|
|
let client = net.client();
|
|
|
|
let url = "https://www.example.com";
|
|
|
|
net.on()
|
|
.delete(url)
|
|
.respond(StatusCode::OK)
|
|
.body("delete OK")
|
|
.expect("mock");
|
|
|
|
//when
|
|
let response = Net::from(net)
|
|
.send(client.delete(url))
|
|
.await
|
|
.expect("reponse");
|
|
|
|
//then
|
|
assert_eq!(response.status(), http::StatusCode::OK);
|
|
assert_eq!(response.bytes().await.expect("response body"), "delete OK");
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_head_url() {
|
|
//given
|
|
let net = kxio::net::mock();
|
|
let client = net.client();
|
|
|
|
let url = "https://www.example.com";
|
|
|
|
net.on()
|
|
.head(url)
|
|
.respond(StatusCode::OK)
|
|
.body("head OK")
|
|
.expect("mock");
|
|
|
|
//when
|
|
let response = Net::from(net)
|
|
.send(client.head(url))
|
|
.await
|
|
.expect("reponse");
|
|
|
|
//then
|
|
assert_eq!(response.status(), http::StatusCode::OK);
|
|
assert_eq!(response.bytes().await.expect("response body"), "head OK");
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_patch_url() {
|
|
//given
|
|
let net = kxio::net::mock();
|
|
let client = net.client();
|
|
|
|
let url = "https://www.example.com";
|
|
|
|
net.on()
|
|
.patch(url)
|
|
.respond(StatusCode::OK)
|
|
.body("patch OK")
|
|
.expect("mock");
|
|
|
|
//when
|
|
let response = Net::from(net)
|
|
.send(client.patch(url))
|
|
.await
|
|
.expect("reponse");
|
|
|
|
//then
|
|
assert_eq!(response.status(), http::StatusCode::OK);
|
|
assert_eq!(response.bytes().await.expect("response body"), "patch OK");
|
|
}
|
|
|
|
// #[tokio::test]
|
|
// async fn test_get_auth_url() {
|
|
// //given
|
|
// let net = kxio::net::mock();
|
|
//
|
|
// let url = "https://user:pass@www.example.com";
|
|
//
|
|
// net.on()
|
|
// .get(url)
|
|
// .respond(StatusCode::OK)
|
|
// .body("post OK")
|
|
// .expect("mock");
|
|
//
|
|
// //when
|
|
// let response = Net::from(net).get(url).send().await.expect("reponse");
|
|
//
|
|
// //then
|
|
// assert_eq!(response.status(), http::StatusCode::OK);
|
|
// assert_eq!(response.bytes().await.expect("response body"), "post OK");
|
|
// }
|
|
|
|
#[tokio::test]
|
|
async fn test_get_wrong_url() {
|
|
//given
|
|
let net = kxio::net::mock();
|
|
let client = net.client();
|
|
|
|
let url = "https://www.example.com";
|
|
|
|
net.on()
|
|
.get(url)
|
|
.respond(StatusCode::OK)
|
|
.body("Get OK")
|
|
.expect("mock");
|
|
|
|
let net = Net::from(net);
|
|
|
|
//when
|
|
let_assert!(
|
|
Err(Error::UnexpectedMockRequest(invalid_request)) =
|
|
net.send(client.get("https://some.other.url/")).await
|
|
);
|
|
|
|
//then
|
|
assert_eq!(invalid_request.url().to_string(), "https://some.other.url/");
|
|
|
|
// remove pending unmatched request - we never meant to match against it
|
|
let mock_net = MockNet::try_from(net).await.expect("recover net");
|
|
mock_net.reset();
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_post_by_method() {
|
|
//given
|
|
let net = kxio::net::mock();
|
|
let client = net.client();
|
|
|
|
// NOTE: No URL specified - so should match any URL
|
|
net.on().respond(StatusCode::OK).body("").expect("mock");
|
|
|
|
//when
|
|
let response = Net::from(net)
|
|
.send(client.post("https://some.other.url"))
|
|
.await
|
|
.expect("response");
|
|
|
|
//then
|
|
assert_eq!(response.status(), http::StatusCode::OK);
|
|
assert_eq!(response.bytes().await.expect("response body"), "");
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_post_by_body() {
|
|
//given
|
|
let net = kxio::net::mock();
|
|
let client = net.client();
|
|
|
|
// No URL - so any POST with a matching body
|
|
net.on()
|
|
.body("match on body")
|
|
.respond(StatusCode::OK)
|
|
.body("response body")
|
|
.expect("mock");
|
|
|
|
//when
|
|
let response = Net::from(net)
|
|
.send(client.post("https://some.other.url").body("match on body"))
|
|
.await
|
|
.expect("response");
|
|
|
|
//then
|
|
assert_eq!(response.status(), http::StatusCode::OK);
|
|
assert_eq!(
|
|
response.bytes().await.expect("response body"),
|
|
"response body"
|
|
);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_post_by_header() {
|
|
//given
|
|
let net = kxio::net::mock();
|
|
let client = net.client();
|
|
|
|
net.on()
|
|
.header("test", "match")
|
|
.respond(StatusCode::OK)
|
|
.body("response body")
|
|
.expect("mock");
|
|
|
|
//when
|
|
let response = Net::from(net)
|
|
.send(
|
|
client
|
|
.post("https://some.other.url")
|
|
.body("nay body")
|
|
.header("test", "match"),
|
|
)
|
|
.await
|
|
.expect("response");
|
|
|
|
//then
|
|
assert_eq!(response.status(), http::StatusCode::OK);
|
|
assert_eq!(
|
|
response.bytes().await.expect("response body"),
|
|
"response body"
|
|
);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_post_by_header_wrong_value() {
|
|
//given
|
|
let mock_net = kxio::net::mock();
|
|
let client = mock_net.client();
|
|
|
|
mock_net
|
|
.on()
|
|
.header("test", "match")
|
|
.respond(StatusCode::OK)
|
|
.body("response body")
|
|
.expect("mock");
|
|
let net = Net::from(mock_net);
|
|
|
|
//when
|
|
let response = net
|
|
.send(
|
|
client
|
|
.post("https://some.other.url")
|
|
.body("nay body")
|
|
.header("test", "no match"),
|
|
)
|
|
.await;
|
|
|
|
//then
|
|
let_assert!(Err(kxio::net::Error::UnexpectedMockRequest(_)) = response);
|
|
|
|
MockNet::try_from(net).await.expect("recover mock").reset();
|
|
}
|
|
|
|
#[tokio::test]
|
|
#[should_panic]
|
|
async fn test_unused_post_as_net() {
|
|
//given
|
|
let mock_net = kxio::net::mock();
|
|
|
|
let url = "https://www.example.com";
|
|
|
|
mock_net
|
|
.on()
|
|
.post(url)
|
|
.respond(StatusCode::OK)
|
|
.body("Post OK")
|
|
.expect("mock");
|
|
|
|
let _net = Net::from(mock_net);
|
|
|
|
//when
|
|
// don't send the planned request
|
|
// let _response = Net::from(net).send(client.post(url)).await.expect("send");
|
|
|
|
//then
|
|
// Drop implementation for net should panic
|
|
}
|
|
|
|
#[tokio::test]
|
|
#[should_panic]
|
|
async fn test_unused_post_as_mocknet() {
|
|
//given
|
|
let mock_net = kxio::net::mock();
|
|
|
|
let url = "https://www.example.com";
|
|
|
|
mock_net
|
|
.on()
|
|
.post(url)
|
|
.respond(StatusCode::OK)
|
|
.body("Post OK")
|
|
.expect("mock");
|
|
|
|
//when
|
|
// don't send the planned request
|
|
// let _response = Net::from(net).send(client.post(url)).await.expect("send");
|
|
|
|
//then
|
|
// Drop implementation for mock_net should panic
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_get_url_with_fragment() {
|
|
//given
|
|
let net = kxio::net::mock();
|
|
let client = net.client();
|
|
|
|
let url = "https://www.example.com#test";
|
|
|
|
net.on()
|
|
.get(url)
|
|
.respond(StatusCode::OK)
|
|
.body("post OK")
|
|
.expect("mock");
|
|
|
|
//when
|
|
let response = Net::from(net).send(client.get(url)).await.expect("reponse");
|
|
|
|
//then
|
|
assert_eq!(response.status(), http::StatusCode::OK);
|
|
assert_eq!(response.bytes().await.expect("response body"), "post OK");
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_get_with_query_parameters() {
|
|
//given
|
|
let mock_net = kxio::net::mock();
|
|
let url = "https://www.example.com/path";
|
|
|
|
mock_net
|
|
.on()
|
|
.get(url)
|
|
.query("key-1", "value-1")
|
|
.respond(StatusCode::OK)
|
|
.body("with query parameters 1/1")
|
|
.expect("mock");
|
|
mock_net
|
|
.on()
|
|
.get(url)
|
|
.query("key-1", "value-2")
|
|
.respond(StatusCode::OK)
|
|
.body("with query parameters 1/2")
|
|
.expect("mock");
|
|
mock_net
|
|
.on()
|
|
.get(url)
|
|
.query("key-2", "value-2")
|
|
.respond(StatusCode::OK)
|
|
.body("with query parameters 2/2")
|
|
.expect("mock");
|
|
mock_net
|
|
.on()
|
|
.get(url)
|
|
.respond(StatusCode::OK)
|
|
.body("sans query parameters")
|
|
.expect("mock");
|
|
let net = Net::from(mock_net);
|
|
|
|
//when
|
|
// The order of 12 nad 11 should be in that order to ensure we test the discrimination of the
|
|
// query value when the keys are the same
|
|
let response_with_12 = net
|
|
.get(url)
|
|
.query("key-1", "value-2")
|
|
.send()
|
|
.await
|
|
.expect("response with qp 1/2");
|
|
let response_with_11 = net
|
|
.get(url)
|
|
.query("key-1", "value-1")
|
|
.send()
|
|
.await
|
|
.expect("response with qp 1/1");
|
|
let response_with_22 = net
|
|
.get(url)
|
|
.query("key-2", "value-2")
|
|
.send()
|
|
.await
|
|
.expect("response with qp 2/2");
|
|
let response_sans_qp = net.get(url).send().await.expect("response sans qp");
|
|
|
|
//then
|
|
assert_eq!(
|
|
response_with_11.bytes().await.expect("with qp 1/1 body"),
|
|
"with query parameters 1/1"
|
|
);
|
|
assert_eq!(
|
|
response_with_12.bytes().await.expect("with qp 1/2 body"),
|
|
"with query parameters 1/2"
|
|
);
|
|
assert_eq!(
|
|
response_with_22.bytes().await.expect("with qp 2/2 body"),
|
|
"with query parameters 2/2"
|
|
);
|
|
assert_eq!(
|
|
response_sans_qp.bytes().await.expect("sans qp body"),
|
|
"sans query parameters"
|
|
);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_get_with_duplicate_query_keys() {
|
|
//given
|
|
let mock_net = kxio::net::mock();
|
|
let url = "https://www.example.com/path";
|
|
|
|
mock_net
|
|
.on()
|
|
.get(url)
|
|
.query("key", "value-1")
|
|
.query("key", "value-2")
|
|
.respond(StatusCode::OK)
|
|
.body("key:value-1,value-2")
|
|
.expect("mock");
|
|
mock_net
|
|
.on()
|
|
.get(url)
|
|
.query("key", "value-3")
|
|
.query("key", "value-4")
|
|
.respond(StatusCode::OK)
|
|
.body("key:value-3,value-4")
|
|
.expect("mock");
|
|
let net = Net::from(mock_net);
|
|
|
|
//when
|
|
let response_a = net
|
|
.get(url)
|
|
.query("key", "value-2")
|
|
.query("key", "value-1")
|
|
.send()
|
|
.await
|
|
.expect("response a");
|
|
let response_b = net
|
|
.get(url)
|
|
.query("key", "value-3")
|
|
.query("key", "value-4")
|
|
.send()
|
|
.await
|
|
.expect("response b");
|
|
|
|
//then
|
|
assert_eq!(
|
|
response_a.bytes().await.expect("response a bytes"),
|
|
"key:value-1,value-2"
|
|
);
|
|
assert_eq!(
|
|
response_b.bytes().await.expect("response b bytes"),
|
|
"key:value-3,value-4"
|
|
);
|
|
}
|