awc/
test.rs

1//! Test helpers for actix http client to use during testing.
2
3use 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
10/// Test `ClientResponse` builder
11pub 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    /// Create TestResponse and set header
31    pub fn with_header(header: impl TryIntoHeaderPair) -> Self {
32        Self::default().insert_header(header)
33    }
34
35    /// Set HTTP version of this response
36    pub fn version(mut self, ver: Version) -> Self {
37        self.head.version = ver;
38        self
39    }
40
41    /// Insert a header
42    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    /// Append a header
51    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    /// Set cookie for this response
60    #[cfg(feature = "cookies")]
61    pub fn cookie(mut self, cookie: Cookie<'_>) -> Self {
62        self.cookies.add(cookie.into_owned());
63        self
64    }
65
66    /// Set response's payload
67    pub fn set_payload<B: Into<Bytes>>(mut self, data: B) -> Self {
68        let (_, mut payload) = h1::Payload::create(true);
69        payload.unread_data(data.into());
70        self.payload = Some(payload.into());
71        self
72    }
73
74    /// Complete response creation and generate `ClientResponse` instance
75    pub fn finish(self) -> ClientResponse {
76        // allow unused mut when cookies feature is disabled
77        #[allow(unused_mut)]
78        let mut head = self.head;
79
80        #[cfg(feature = "cookies")]
81        for cookie in self.cookies.delta() {
82            use actix_http::header::{self, HeaderValue};
83
84            head.headers.insert(
85                header::SET_COOKIE,
86                HeaderValue::from_str(&cookie.encoded().to_string()).unwrap(),
87            );
88        }
89
90        if let Some(pl) = self.payload {
91            ClientResponse::new(head, pl)
92        } else {
93            let (_, payload) = h1::Payload::create(true);
94            ClientResponse::new(head, payload.into())
95        }
96    }
97}
98
99#[cfg(test)]
100mod tests {
101    use std::time::SystemTime;
102
103    use actix_http::header::HttpDate;
104
105    use super::*;
106    use crate::{cookie, http::header};
107
108    #[test]
109    fn test_basics() {
110        let res = TestResponse::default()
111            .version(Version::HTTP_2)
112            .insert_header((header::DATE, HttpDate::from(SystemTime::now())))
113            .cookie(cookie::Cookie::build("name", "value").finish())
114            .finish();
115        assert!(res.headers().contains_key(header::SET_COOKIE));
116        assert!(res.headers().contains_key(header::DATE));
117        assert_eq!(res.version(), Version::HTTP_2);
118    }
119}