use std::str::FromStr;
use std::sync::{Arc, Mutex};
use bytes::Bytes;
use http::header::{HeaderName, HeaderValue, CONTENT_TYPE};
use http_body_util::{BodyExt, Empty, Full};
use hyper::{Method, Request, Response, StatusCode, Uri};
use serde::Serialize;
use serde_json::Value;
use hyperlite::{BoxBody, ResponseBody};
#[allow(dead_code)]
pub fn json_body(value: impl Serialize) -> BoxBody {
let bytes = serde_json::to_vec(&value).expect("failed to serialize JSON for test body");
Full::from(Bytes::from(bytes))
.map_err(|err| match err {})
.boxed()
}
#[allow(dead_code)]
pub fn empty_body() -> BoxBody {
Empty::<Bytes>::new().map_err(|err| match err {}).boxed()
}
#[allow(dead_code)]
pub fn bytes_body(bytes: Bytes) -> BoxBody {
Full::from(bytes).map_err(|err| match err {}).boxed()
}
#[allow(dead_code)]
pub fn build_request(method: Method, uri: &str, body: BoxBody) -> Request<BoxBody> {
Request::builder()
.method(method)
.uri(Uri::from_str(uri).expect("invalid URI in test"))
.body(body)
.expect("failed to build test request")
}
#[allow(dead_code)]
pub fn build_json_request(method: Method, uri: &str, json: impl Serialize) -> Request<BoxBody> {
let mut request = build_request(method, uri, json_body(json));
request
.headers_mut()
.insert(CONTENT_TYPE, HeaderValue::from_static("application/json"));
request
}
#[allow(dead_code)]
pub fn build_request_with_headers(
method: Method,
uri: &str,
body: BoxBody,
headers: Vec<(HeaderName, HeaderValue)>,
) -> Request<BoxBody> {
let mut request = build_request(method, uri, body);
for (name, value) in headers {
request.headers_mut().insert(name, value);
}
request
}
#[allow(dead_code)]
pub async fn read_body_json(response: Response<ResponseBody>) -> Value {
let bytes = response
.into_body()
.collect()
.await
.expect("failed to read response body")
.to_bytes();
serde_json::from_slice(&bytes).expect("response body is not valid JSON")
}
#[allow(dead_code)]
pub async fn read_body_bytes(response: Response<ResponseBody>) -> Bytes {
response
.into_body()
.collect()
.await
.expect("failed to read response body")
.to_bytes()
}
#[allow(dead_code)]
pub fn assert_json_envelope(json: &Value, success: bool) {
assert_eq!(json["success"], success);
assert!(json.get("meta").is_some(), "meta field missing");
assert!(json["meta"].is_object(), "meta field should be object");
}
#[allow(dead_code)]
#[derive(Clone, Default)]
pub struct TestState {
counter: Arc<Mutex<u64>>,
}
#[allow(dead_code)]
impl TestState {
pub fn new() -> Self {
Self::default()
}
pub fn increment(&self) -> u64 {
let mut guard = self.counter.lock().expect("counter poisoned");
*guard += 1;
*guard
}
pub fn get(&self) -> u64 {
*self.counter.lock().expect("counter poisoned")
}
}
#[allow(dead_code)]
pub fn assert_status(response: &Response<ResponseBody>, expected: StatusCode) {
assert_eq!(response.status(), expected);
}
#[allow(dead_code)]
pub fn assert_header(response: &Response<ResponseBody>, name: &str, expected: &str) {
let header = response
.headers()
.get(name)
.unwrap_or_else(|| panic!("missing header: {}", name));
let header_value = header.to_str().unwrap();
assert_eq!(header_value, expected);
}
#[allow(dead_code)]
pub fn assert_content_type_json(response: &Response<ResponseBody>) {
let header = response
.headers()
.get(CONTENT_TYPE)
.expect("missing Content-Type header");
assert_eq!(header, "application/json");
}