From c2b04bdafb917198ab63ce125130495a75536fbd Mon Sep 17 00:00:00 2001 From: Enrico Risa Date: Mon, 16 Nov 2020 11:05:43 +0100 Subject: [PATCH] Added support for raw_body in response (#21) --- src/request/mod.rs | 16 ++++++++++------ src/response.rs | 12 ++++++++---- tests/async_bridge/rest.rs | 16 ++++++++++++++++ tests/blocking/rest.rs | 12 ++++++++++++ tests/common/mod.rs | 21 ++++++++++++++++++++- 5 files changed, 66 insertions(+), 11 deletions(-) diff --git a/src/request/mod.rs b/src/request/mod.rs index d7d6223..1abf008 100644 --- a/src/request/mod.rs +++ b/src/request/mod.rs @@ -141,10 +141,13 @@ pub trait DeliverableRequest<'a>: Sized + 'a { return Err(PrimaBridgeError::WrongStatusCode(url, status_code)); } let response_headers = response.headers().clone(); - let response_body = response.text().map_err(|e| PrimaBridgeError::HttpError { - source: e, - url: url.clone(), - })?; + let response_body = response + .bytes() + .map_err(|e| PrimaBridgeError::HttpError { + source: e, + url: url.clone(), + })? + .to_vec(); match self.get_request_type() { RequestType::Rest => Ok(Response::rest( @@ -203,12 +206,13 @@ pub trait DeliverableRequest<'a>: Sized + 'a { let response_headers = response.headers().clone(); let response_body = response - .text() + .bytes() .map_err(|e| PrimaBridgeError::HttpError { source: e, url: url.clone(), }) - .await?; + .await? + .to_vec(); match self.get_request_type() { RequestType::Rest => Ok(Response::rest( diff --git a/src/response.rs b/src/response.rs index fffd0b2..7078773 100644 --- a/src/response.rs +++ b/src/response.rs @@ -17,7 +17,7 @@ enum RequestType { #[derive(Debug)] pub struct Response { url: Url, - response_body: String, + response_body: Vec, status_code: StatusCode, response_headers: HeaderMap, request_id: Uuid, @@ -28,7 +28,7 @@ impl Response { #[doc(hidden)] pub fn rest( url: Url, - response_body: String, + response_body: Vec, status_code: StatusCode, response_headers: HeaderMap, request_id: Uuid, @@ -46,7 +46,7 @@ impl Response { #[doc(hidden)] pub fn graphql( url: Url, - response_body: String, + response_body: Vec, status_code: StatusCode, response_headers: HeaderMap, request_id: Uuid, @@ -76,7 +76,7 @@ impl Response { where for<'de> T: Deserialize<'de> + Debug, { - let json_value = serde_json::from_str(self.response_body.as_str()).map_err(|e| { + let json_value = serde_json::from_slice(&self.response_body[..]).map_err(|e| { PrimaBridgeError::ResponseBodyNotDeserializable { status_code: self.status_code, source: e, @@ -89,6 +89,10 @@ impl Response { Ok(extract_inner_json(self.url, selectors, json_value)?) } + pub fn raw_body(&self) -> &Vec { + &self.response_body + } + /// returns `true` if the response is successful pub fn is_ok(&self) -> bool { self.status_code.is_success() diff --git a/tests/async_bridge/rest.rs b/tests/async_bridge/rest.rs index 75622a6..ce65e8e 100644 --- a/tests/async_bridge/rest.rs +++ b/tests/async_bridge/rest.rs @@ -124,3 +124,19 @@ async fn request_with_custom_headers() -> Result<(), Box> { assert!(result.is_ok()); Ok(()) } + +#[tokio::test] +async fn request_with_binary_body_response() -> Result<(), Box> { + let body = b"abcde"; + + let (_m, bridge) = create_bridge_with_binary_body_matcher(body); + + let result = RestRequest::new(&bridge) + .raw_body(body.to_vec()) + .send() + .await?; + assert!(result.is_ok()); + + assert_eq!(body, &result.raw_body()[..]); + Ok(()) +} diff --git a/tests/blocking/rest.rs b/tests/blocking/rest.rs index 2ec15e3..115a443 100644 --- a/tests/blocking/rest.rs +++ b/tests/blocking/rest.rs @@ -284,3 +284,15 @@ fn request_with_query_string_by_calling_once() -> Result<(), Box> { assert!(result.is_ok()); Ok(()) } + +#[test] +fn request_with_binary_raw_body() -> Result<(), Box> { + let body = b"abcde"; + let (_m, bridge) = create_bridge_with_binary_body_matcher(body); + let result = RestRequest::new(&bridge).raw_body(body.to_vec()).send()?; + assert!(result.is_ok()); + + assert_eq!(body, &result.raw_body()[..]); + + Ok(()) +} diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 9bc2a92..ef0ccc7 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -1,4 +1,4 @@ -use mockito::{mock, Matcher, Mock}; +use mockito::{mock, BinaryBody, Matcher, Mock}; use prima_bridge::prelude::*; use reqwest::Url; @@ -126,3 +126,22 @@ pub fn create_bridge_with_json_body_matcher(json: serde_json::Value) -> (Mock, B (mock, bridge) } + +pub fn create_bridge_with_binary_body_matcher(body: &[u8]) -> (Mock, Bridge) { + let mock = mock("GET", "/") + .match_header( + "x-request-id", + Matcher::Regex( + r"\b[0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12}\b".to_string(), + ), + ) + .match_body(Matcher::Binary(BinaryBody::from_bytes(body.to_vec()))) + .with_status(200) + .with_body(body) + .create(); + + let url = Url::parse(mockito::server_url().as_str()).unwrap(); + let bridge = Bridge::new(url); + + (mock, bridge) +}