feat(net)!: new api: .on().{get,post, etc}(url), replacing .on(method).get(url)
The `http::Method` parameter is not needed as we now use named methods that the methods on the underlying `reqwest` client. The `url` parameter can be a `String` or `&str` rather than a parsed, and error handled `url::Url`.
This commit is contained in:
parent
782307a856
commit
f759884517
4 changed files with 175 additions and 76 deletions
|
@ -104,8 +104,6 @@ fn delete_file(file_path: &Path, fs: &kxio::fs::FileSystem) -> kxio::Result<()>
|
|||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use kxio::net::{Method, Url};
|
||||
|
||||
// This test demonstrates how to use the `kxio` to test your program.
|
||||
#[tokio::test]
|
||||
async fn should_save_remote_body() {
|
||||
|
@ -119,10 +117,7 @@ mod tests {
|
|||
|
||||
// declare what response should be made for a given request
|
||||
let response = mock_net.response().body("contents").expect("response body");
|
||||
mock_net
|
||||
.on(Method::GET)
|
||||
.url(Url::parse(url).expect("parse url"))
|
||||
.respond(response);
|
||||
mock_net.on().get(url).respond(response);
|
||||
|
||||
// Create a temporary directory that will be deleted with `fs` goes out of scope
|
||||
let fs = kxio::fs::temp().expect("temp fs");
|
||||
|
|
|
@ -79,16 +79,14 @@
|
|||
//!
|
||||
//! ```rust
|
||||
//! use kxio::net;
|
||||
//! use kxio::net::{Method, Url};
|
||||
//!
|
||||
//! # #[tokio::main]
|
||||
//! # async fn main() -> net::Result<()> {
|
||||
//! # let mock_net = net::mock();
|
||||
//! mock_net.on(Method::GET)
|
||||
//! .url(Url::parse("https://example.com")?)
|
||||
//! mock_net.on()
|
||||
//! .get("https://example.com")
|
||||
//! .respond(mock_net.response().status(200).body("")?);
|
||||
//! mock_net.on(Method::GET)
|
||||
//! .url(Url::parse("https://example.com/foo")?)
|
||||
//! mock_net.on()
|
||||
//! .get("https://example.com/foo")
|
||||
//! .respond(mock_net.response().status(500).body("Mocked response")?);
|
||||
//! # mock_net.reset();
|
||||
//! # Ok(())
|
||||
|
@ -151,13 +149,11 @@ pub use result::{Error, Result};
|
|||
|
||||
pub use system::{MockNet, Net};
|
||||
|
||||
pub use http::Method;
|
||||
pub use http::HeaderMap;
|
||||
pub use reqwest::Client;
|
||||
pub use reqwest::Request;
|
||||
pub use reqwest::RequestBuilder;
|
||||
pub use reqwest::Response;
|
||||
pub use url::Url;
|
||||
|
||||
/// Creates a new `Net`.
|
||||
pub const fn new() -> Net {
|
||||
|
|
|
@ -2,10 +2,13 @@
|
|||
|
||||
use std::{cell::RefCell, ops::Deref, rc::Rc, sync::Arc};
|
||||
|
||||
use derive_more::derive::{Display, From};
|
||||
use http::Method;
|
||||
use reqwest::{Body, Client};
|
||||
use tokio::sync::Mutex;
|
||||
use url::Url;
|
||||
|
||||
use crate::net::{Method, Request, RequestBuilder, Response, Url};
|
||||
use crate::net::{Request, RequestBuilder, Response};
|
||||
|
||||
use super::{Error, Result};
|
||||
|
||||
|
@ -129,15 +132,14 @@ impl MockNet {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use kxio::net::{Method, Url};
|
||||
/// # use kxio::net::Result;
|
||||
/// # #[tokio::main]
|
||||
/// # async fn run() -> Result<()> {
|
||||
/// let mock_net = kxio::net::mock();
|
||||
/// let client = mock_net.client();
|
||||
/// // define an expected requet, and the response that should be returned
|
||||
/// mock_net.on(Method::GET)
|
||||
/// .url(Url::parse("https://hyper.rs")?)
|
||||
/// mock_net.on()
|
||||
/// .get("https://hyper.rs")
|
||||
/// .respond(mock_net.response().status(200).body("Ok")?);
|
||||
/// let net: kxio::net::Net = mock_net.into();
|
||||
/// // use 'net' in your program, by passing it as a reference
|
||||
|
@ -172,19 +174,18 @@ impl MockNet {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use kxio::net::{Method, Url};
|
||||
/// # use kxio::net::Result;
|
||||
/// # fn run() -> Result<()> {
|
||||
/// let mock_net = kxio::net::mock();
|
||||
/// let client = mock_net.client();
|
||||
/// mock_net.on(Method::GET)
|
||||
/// .url(Url::parse("https://hyper.rs")?)
|
||||
/// mock_net.on()
|
||||
/// .get("https://hyper.rs")
|
||||
/// .respond(mock_net.response().status(200).body("Ok")?);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn on(&self, method: impl Into<Method>) -> WhenRequest {
|
||||
WhenRequest::new(self, method)
|
||||
pub fn on(&self) -> WhenRequest {
|
||||
WhenRequest::new(self)
|
||||
}
|
||||
|
||||
fn _when(&self, plan: Plan) {
|
||||
|
@ -249,15 +250,47 @@ pub enum MatchRequest {
|
|||
Body(String),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Display, From)]
|
||||
enum MockError {
|
||||
UrlParse(#[from] url::ParseError),
|
||||
}
|
||||
impl std::error::Error for MockError {}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct WhenRequest<'net> {
|
||||
net: &'net MockNet,
|
||||
match_on: Vec<MatchRequest>,
|
||||
errors: Vec<MockError>,
|
||||
}
|
||||
|
||||
impl<'net> WhenRequest<'net> {
|
||||
pub fn url(mut self, url: impl Into<Url>) -> Self {
|
||||
self.match_on.push(MatchRequest::Url(url.into()));
|
||||
pub fn get(self, url: impl Into<String>) -> Self {
|
||||
self._url(Method::GET, url)
|
||||
}
|
||||
pub fn post(self, url: impl Into<String>) -> Self {
|
||||
self._url(Method::POST, url)
|
||||
}
|
||||
pub fn put(self, url: impl Into<String>) -> Self {
|
||||
self._url(Method::PUT, url)
|
||||
}
|
||||
pub fn delete(self, url: impl Into<String>) -> Self {
|
||||
self._url(Method::DELETE, url)
|
||||
}
|
||||
pub fn head(self, url: impl Into<String>) -> Self {
|
||||
self._url(Method::HEAD, url)
|
||||
}
|
||||
pub fn patch(self, url: impl Into<String>) -> Self {
|
||||
self._url(Method::PATCH, url)
|
||||
}
|
||||
|
||||
fn _url(mut self, method: http::Method, url: impl Into<String>) -> Self {
|
||||
self.match_on.push(MatchRequest::Method(method));
|
||||
match Url::parse(&url.into()) {
|
||||
Ok(url) => {
|
||||
self.match_on.push(MatchRequest::Url(url));
|
||||
}
|
||||
Err(err) => self.errors.push(err.into()),
|
||||
}
|
||||
self
|
||||
}
|
||||
pub fn header(mut self, name: impl Into<String>, value: impl Into<String>) -> Self {
|
||||
|
@ -281,10 +314,11 @@ impl<'net> WhenRequest<'net> {
|
|||
});
|
||||
}
|
||||
|
||||
fn new(net: &'net MockNet, method: impl Into<Method>) -> Self {
|
||||
fn new(net: &'net MockNet) -> Self {
|
||||
Self {
|
||||
net,
|
||||
match_on: vec![MatchRequest::Method(method.into())],
|
||||
match_on: vec![],
|
||||
errors: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
172
tests/net.rs
172
tests/net.rs
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
use kxio::net::{Error, Method, MockNet, Net, Url};
|
||||
use kxio::net::{Error, MockNet, Net};
|
||||
|
||||
use assert2::let_assert;
|
||||
|
||||
|
@ -17,8 +17,8 @@ async fn test_get_url() {
|
|||
.expect("body");
|
||||
|
||||
mock_net
|
||||
.on(Method::GET)
|
||||
.url(Url::parse(url).expect("parse url"))
|
||||
.on()
|
||||
.get("https://www.example.com")
|
||||
.respond(my_response);
|
||||
|
||||
//when
|
||||
|
@ -32,6 +32,118 @@ async fn test_get_url() {
|
|||
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(net.response().status(200).body("post OK").expect("body"));
|
||||
|
||||
//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(net.response().status(200).body("put OK").expect("body"));
|
||||
|
||||
//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(net.response().status(200).body("delete OK").expect("body"));
|
||||
|
||||
//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(net.response().status(200).body("head OK").expect("body"));
|
||||
|
||||
//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(net.response().status(200).body("patch OK").expect("body"));
|
||||
|
||||
//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_wrong_url() {
|
||||
//given
|
||||
|
@ -45,10 +157,7 @@ async fn test_get_wrong_url() {
|
|||
.body("Get OK")
|
||||
.expect("body");
|
||||
|
||||
mock_net
|
||||
.on(Method::GET)
|
||||
.url(Url::parse(url).expect("parse url"))
|
||||
.respond(my_response);
|
||||
mock_net.on().get(url).respond(my_response);
|
||||
|
||||
let net = Net::from(mock_net);
|
||||
|
||||
|
@ -66,30 +175,6 @@ async fn test_get_wrong_url() {
|
|||
mock_net.reset();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_post_url() {
|
||||
//given
|
||||
let net = kxio::net::mock();
|
||||
let client = net.client();
|
||||
|
||||
let url = "https://www.example.com";
|
||||
let my_response = net.response().status(200).body("Post OK").expect("body");
|
||||
|
||||
net.on(Method::POST)
|
||||
.url(Url::parse(url).expect("parse url"))
|
||||
.respond(my_response);
|
||||
|
||||
//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_post_by_method() {
|
||||
//given
|
||||
|
@ -98,8 +183,8 @@ async fn test_post_by_method() {
|
|||
|
||||
let my_response = net.response().status(200).body("").expect("response body");
|
||||
|
||||
net.on(Method::POST)
|
||||
// NOTE: No URL specified - so shou∂ match any URL
|
||||
net.on()
|
||||
// NOTE: No URL specified - so should match any URL
|
||||
.respond(my_response);
|
||||
|
||||
//when
|
||||
|
@ -125,7 +210,7 @@ async fn test_post_by_body() {
|
|||
.body("response body")
|
||||
.expect("body");
|
||||
|
||||
net.on(Method::POST)
|
||||
net.on()
|
||||
// No URL - so any POST with a matching body
|
||||
.body("match on body")
|
||||
.respond(my_response);
|
||||
|
@ -156,9 +241,7 @@ async fn test_post_by_header() {
|
|||
.body("response body")
|
||||
.expect("body");
|
||||
|
||||
net.on(Method::POST)
|
||||
.header("test", "match")
|
||||
.respond(my_response);
|
||||
net.on().header("test", "match").respond(my_response);
|
||||
|
||||
//when
|
||||
let response = Net::from(net)
|
||||
|
@ -191,10 +274,7 @@ async fn test_post_by_header_wrong_value() {
|
|||
.body("response body")
|
||||
.expect("body");
|
||||
|
||||
mock_net
|
||||
.on(Method::POST)
|
||||
.header("test", "match")
|
||||
.respond(my_response);
|
||||
mock_net.on().header("test", "match").respond(my_response);
|
||||
let net = Net::from(mock_net);
|
||||
|
||||
//when
|
||||
|
@ -226,10 +306,7 @@ async fn test_unused_post_as_net() {
|
|||
.body("Post OK")
|
||||
.expect("body");
|
||||
|
||||
mock_net
|
||||
.on(Method::POST)
|
||||
.url(Url::parse(url).expect("prase url"))
|
||||
.respond(my_response);
|
||||
mock_net.on().post(url).respond(my_response);
|
||||
|
||||
let _net = Net::from(mock_net);
|
||||
|
||||
|
@ -254,10 +331,7 @@ async fn test_unused_post_as_mocknet() {
|
|||
.body("Post OK")
|
||||
.expect("body");
|
||||
|
||||
mock_net
|
||||
.on(Method::POST)
|
||||
.url(Url::parse(url).expect("parse url"))
|
||||
.respond(my_response);
|
||||
mock_net.on().post(url).respond(my_response);
|
||||
|
||||
//when
|
||||
// don't send the planned request
|
||||
|
|
Loading…
Reference in a new issue