1use actix_http::{h1, header::TryIntoHeaderPair, Payload, ResponseHead, StatusCode, Version};
4use bytes::Bytes;
5
6#[cfg(feature = "cookies")]
7use crate::cookie::{Cookie, CookieJar};
8use crate::ClientResponse;
9
10pub struct TestResponse {
12 head: ResponseHead,
13 #[cfg(feature = "cookies")]
14 cookies: CookieJar,
15 payload: Option<Payload>,
16}
17
18impl Default for TestResponse {
19 fn default() -> TestResponse {
20 TestResponse {
21 head: ResponseHead::new(StatusCode::OK),
22 #[cfg(feature = "cookies")]
23 cookies: CookieJar::new(),
24 payload: None,
25 }
26 }
27}
28
29impl TestResponse {
30 pub fn with_header(header: impl TryIntoHeaderPair) -> Self {
32 Self::default().insert_header(header)
33 }
34
35 pub fn version(mut self, ver: Version) -> Self {
37 self.head.version = ver;
38 self
39 }
40
41 pub fn insert_header(mut self, header: impl TryIntoHeaderPair) -> Self {
43 if let Ok((key, value)) = header.try_into_pair() {
44 self.head.headers.insert(key, value);
45 return self;
46 }
47 panic!("Can not set header");
48 }
49
50 pub fn append_header(mut self, header: impl TryIntoHeaderPair) -> Self {
52 if let Ok((key, value)) = header.try_into_pair() {
53 self.head.headers.append(key, value);
54 return self;
55 }
56 panic!("Can not create header");
57 }
58
59 #[cfg(feature = "cookies")]
61 pub fn cookie(mut self, cookie: Cookie<'_>) -> Self {
62 self.cookies.add(cookie.into_owned());
63 self
64 }
65
66 pub fn set_payload<B: Into<Bytes>>(mut self, data: B) -> Self {
68 self.payload = Some(Payload::from(data.into()));
69 self
70 }
71
72 pub fn finish(self) -> ClientResponse {
74 #[allow(unused_mut)]
76 let mut head = self.head;
77
78 #[cfg(feature = "cookies")]
79 for cookie in self.cookies.delta() {
80 use actix_http::header::{self, HeaderValue};
81
82 head.headers.insert(
83 header::SET_COOKIE,
84 HeaderValue::from_str(&cookie.encoded().to_string()).unwrap(),
85 );
86 }
87
88 if let Some(pl) = self.payload {
89 ClientResponse::new(head, pl)
90 } else {
91 let (_, payload) = h1::Payload::create(true);
92 ClientResponse::new(head, payload.into())
93 }
94 }
95}
96
97#[cfg(test)]
98mod tests {
99 use std::time::SystemTime;
100
101 use actix_http::header::HttpDate;
102
103 use super::*;
104 use crate::http::header;
105
106 #[test]
107 fn test_basics() {
108 let res = TestResponse::default()
109 .version(Version::HTTP_2)
110 .insert_header((header::DATE, HttpDate::from(SystemTime::now())))
111 .cookie(cookie::Cookie::build("name", "value").finish())
112 .finish();
113 assert!(res.headers().contains_key(header::SET_COOKIE));
114 assert!(res.headers().contains_key(header::DATE));
115 assert_eq!(res.version(), Version::HTTP_2);
116 }
117}