tork_core/testing/
response.rs1use bytes::Bytes;
4use http::{HeaderMap, StatusCode};
5use serde::de::DeserializeOwned;
6
7use crate::error::{Error, Result};
8
9pub struct TestResponse {
14 pub(crate) status: StatusCode,
15 pub(crate) headers: HeaderMap,
16 pub(crate) body: Bytes,
17}
18
19impl TestResponse {
20 pub fn status(&self) -> u16 {
22 self.status.as_u16()
23 }
24
25 pub fn status_code(&self) -> StatusCode {
27 self.status
28 }
29
30 pub fn headers(&self) -> &HeaderMap {
32 &self.headers
33 }
34
35 pub fn bytes(&self) -> Bytes {
37 self.body.clone()
38 }
39
40 pub fn text(&self) -> Result<String> {
42 String::from_utf8(self.body.to_vec())
43 .map_err(|_| Error::internal("response body is not valid UTF-8"))
44 }
45
46 pub async fn json<T: DeserializeOwned>(&self) -> Result<T> {
48 serde_json::from_slice(&self.body)
49 .map_err(|error| Error::internal(format!("response body is not valid JSON: {error}")))
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56 use bytes::Bytes;
57 use http::HeaderValue;
58 use serde::Deserialize;
59
60 fn response(body: &[u8]) -> TestResponse {
61 let mut headers = HeaderMap::new();
62 headers.insert("x-test", HeaderValue::from_static("ok"));
63 TestResponse {
64 status: StatusCode::CREATED,
65 headers,
66 body: Bytes::copy_from_slice(body),
67 }
68 }
69
70 #[derive(Debug, Deserialize, PartialEq)]
71 struct Payload {
72 ok: bool,
73 }
74
75 #[tokio::test]
76 async fn exposes_status_headers_bytes_and_json() {
77 let response = response(br#"{"ok":true}"#);
78
79 assert_eq!(response.status(), 201);
80 assert_eq!(response.status_code(), StatusCode::CREATED);
81 assert_eq!(response.headers()["x-test"], "ok");
82 assert_eq!(response.bytes(), Bytes::from_static(br#"{"ok":true}"#));
83 assert_eq!(response.text().unwrap(), r#"{"ok":true}"#);
84 assert_eq!(
85 response.json::<Payload>().await.unwrap(),
86 Payload { ok: true }
87 );
88 }
89
90 #[test]
91 fn text_rejects_invalid_utf8() {
92 let response = response(&[0xff, 0xfe]);
93
94 let error = response.text().unwrap_err();
95 assert_eq!(error.message(), "response body is not valid UTF-8");
96 }
97
98 #[tokio::test]
99 async fn json_rejects_invalid_payload() {
100 let response = response(br#"{"ok":"wrong"}"#);
101
102 let error = response.json::<Payload>().await.unwrap_err();
103 assert!(error
104 .message()
105 .starts_with("response body is not valid JSON:"));
106 }
107}