tests(net): add more tests

This commit is contained in:
Paul Campbell 2024-11-07 09:49:38 +00:00
parent fdb6c32fc7
commit aad2531c9f
2 changed files with 167 additions and 14 deletions

View file

@ -46,7 +46,7 @@ impl Net<Unmocked> {
impl<T: NetType> Net<T> { impl<T: NetType> Net<T> {
pub fn client(&self) -> reqwest::Client { pub fn client(&self) -> reqwest::Client {
reqwest::Client::new() Default::default()
} }
} }
impl Net<Mocked> { impl Net<Mocked> {
@ -75,7 +75,7 @@ impl Net<Mocked> {
&& (if plan.match_on.contains(&MatchOn::Body) { && (if plan.match_on.contains(&MatchOn::Body) {
match (plan.request.body(), request.body()) { match (plan.request.body(), request.body()) {
(None, None) => true, (None, None) => true,
(Some(plan), Some(request)) => plan.as_bytes() == request.as_bytes(), (Some(plan), Some(req)) => plan.as_bytes().eq(&req.as_bytes()),
_ => false, _ => false,
} }
} else { } else {
@ -93,8 +93,10 @@ impl Net<Mocked> {
None => Err(Error::UnexpectedMockRequest(request)), None => Err(Error::UnexpectedMockRequest(request)),
} }
} }
/// Creates a [ResponseBuilder] to be extended and returned by a mocked network request.
pub fn response(&self) -> http::response::Builder { pub fn response(&self) -> http::response::Builder {
http::Response::builder() Default::default()
} }
pub fn on(&mut self, request: reqwest::Request) -> OnRequest { pub fn on(&mut self, request: reqwest::Request) -> OnRequest {
@ -117,6 +119,10 @@ impl Net<Mocked> {
match_on, match_on,
}) })
} }
pub fn reset(&mut self) {
self.plans = vec![];
}
} }
impl<T: NetType> Drop for Net<T> { impl<T: NetType> Drop for Net<T> {
fn drop(&mut self) { fn drop(&mut self) {
@ -131,7 +137,11 @@ pub struct OnRequest<'net> {
} }
impl<'net> OnRequest<'net> { impl<'net> OnRequest<'net> {
pub fn match_on(self, match_on: Vec<MatchOn>) -> Self { pub fn match_on(self, match_on: Vec<MatchOn>) -> Self {
Self{net:self.net, request:self.request, match_on} Self {
net: self.net,
request: self.request,
match_on,
}
} }
pub fn respond(self, response: reqwest::Response) { pub fn respond(self, response: reqwest::Response) {
self.net._on(self.request, response, self.match_on) self.net._on(self.request, response, self.match_on)

View file

@ -1,10 +1,9 @@
use assert2::let_assert;
// //
use kxio::net::{Error, MatchOn}; use kxio::net::{Error, MatchOn};
type TestResult = Result<(), Error>;
#[tokio::test] #[tokio::test]
async fn test_get() -> TestResult { async fn test_get_url() {
//given //given
let mut net = kxio::net::mock(); let mut net = kxio::net::mock();
let client = net.client(); let client = net.client();
@ -20,17 +19,41 @@ async fn test_get() -> TestResult {
net.on(request).respond(my_response.into()); net.on(request).respond(my_response.into());
//when //when
let response = net.send(client.get(url)).await?; let response = net.send(client.get(url)).await.expect("response");
//then //then
assert_eq!(response.status(), http::StatusCode::OK); assert_eq!(response.status(), http::StatusCode::OK);
assert_eq!(response.bytes().await.expect("response body"), "Get OK"); assert_eq!(response.bytes().await.expect("response body"), "Get OK");
Ok(())
} }
#[tokio::test] #[tokio::test]
async fn test_post() { async fn test_get_wrong_url() {
//given
let mut net = kxio::net::mock();
let client = net.client();
let url = "https://www.example.com";
let request = client.get(url).build().expect("build request");
let my_response = net
.response()
.status(200)
.body("Get OK")
.expect("request body");
net.on(request).respond(my_response.into());
//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
net.reset();
}
#[tokio::test]
async fn test_post_url() {
//given //given
let mut net = kxio::net::mock(); let mut net = kxio::net::mock();
let client = net.client(); let client = net.client();
@ -53,6 +76,39 @@ async fn test_post() {
assert_eq!(response.bytes().await.expect("response body"), "Post OK"); assert_eq!(response.bytes().await.expect("response body"), "Post OK");
} }
#[tokio::test]
async fn test_post_by_method() {
//given
let mut net = kxio::net::mock();
let client = net.client();
let url = "https://www.example.com";
let request = client.post(url).build().expect("build request");
let my_response = net
.response()
.status(200)
.body("Post OK")
.expect("request body");
net.on(request)
.match_on(vec![
MatchOn::Method,
// MatchOn::Url
])
.respond(my_response.into());
//when
// This request is a different url - but should still match
let response = 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"), "Post OK");
}
#[tokio::test] #[tokio::test]
async fn test_post_by_url() { async fn test_post_by_url() {
//given //given
@ -69,8 +125,8 @@ async fn test_post_by_url() {
net.on(request) net.on(request)
.match_on(vec![ .match_on(vec![
// MatchOn::Method, // MatchOn::Method,
MatchOn::Url MatchOn::Url,
]) ])
.respond(my_response.into()); .respond(my_response.into());
@ -83,6 +139,94 @@ async fn test_post_by_url() {
assert_eq!(response.bytes().await.expect("response body"), "Post OK"); assert_eq!(response.bytes().await.expect("response body"), "Post OK");
} }
#[tokio::test]
async fn test_post_by_body() {
//given
let mut net = kxio::net::mock();
let client = net.client();
let url = "https://www.example.com";
let request = client
.post(url)
.body("match on body")
.build()
.expect("build request");
let my_response = net
.response()
.status(200)
.body("response body")
.expect("request body");
net.on(request)
.match_on(vec![
// MatchOn::Method,
// MatchOn::Url
MatchOn::Body,
])
.respond(my_response.into());
//when
// This request is a GET, not POST - but should still match
let response = net
.send(client.get("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_headers() {
//given
let mut net = kxio::net::mock();
let client = net.client();
let url = "https://www.example.com";
let request = client
.post(url)
.body("foo")
.header("test", "match")
.build()
.expect("build request");
let my_response = net
.response()
.status(200)
.body("response body")
.expect("request body");
net.on(request)
.match_on(vec![
// MatchOn::Method,
// MatchOn::Url
MatchOn::Headers,
])
.respond(my_response.into());
//when
// This request is a GET, not POST - but should still match
let response = net
.send(
client
.get("https://some.other.url")
.body("match on 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] #[tokio::test]
#[should_panic] #[should_panic]
async fn test_unused_post() { async fn test_unused_post() {
@ -104,7 +248,6 @@ async fn test_unused_post() {
// don't send the planned request // don't send the planned request
// let _response = net.send(client.post(url)).await.expect("send"); // let _response = net.send(client.post(url)).await.expect("send");
//then //then
// Drop implementation for net should panic // Drop implementation for net should panic
} }