cloudevents/binding/poem/
extractor.rs

1use crate::binding::http::to_event;
2use crate::Event;
3
4use poem_lib::error::ResponseError;
5use poem_lib::http::StatusCode;
6use poem_lib::{FromRequest, Request, RequestBody, Result};
7
8impl ResponseError for crate::message::Error {
9    fn status(&self) -> StatusCode {
10        StatusCode::BAD_REQUEST
11    }
12}
13
14impl<'a> FromRequest<'a> for Event {
15    async fn from_request(req: &'a Request, body: &mut RequestBody) -> Result<Self> {
16        Ok(to_event(req.headers(), body.take()?.into_vec().await?)?)
17    }
18}
19
20#[cfg(test)]
21mod tests {
22    use super::*;
23    use crate::test::fixtures;
24    use poem_lib::http::Method;
25
26    #[tokio::test]
27    async fn test_request() {
28        let expected = fixtures::v10::minimal_string_extension();
29
30        let req = Request::builder()
31            .method(Method::POST)
32            .header("ce-specversion", "1.0")
33            .header("ce-id", "0001")
34            .header("ce-type", "test_event.test_application")
35            .header("ce-source", "http://localhost/")
36            .header("ce-someint", "10")
37            .finish();
38        let (req, mut body) = req.split();
39        let result = Event::from_request(&req, &mut body).await.unwrap();
40
41        assert_eq!(expected, result);
42    }
43
44    #[tokio::test]
45    async fn test_bad_request() {
46        let req = Request::builder()
47            .method(Method::POST)
48            .header("ce-specversion", "BAD SPECIFICATION")
49            .header("ce-id", "0001")
50            .header("ce-type", "example.test")
51            .header("ce-source", "http://localhost/")
52            .header("ce-someint", "10")
53            .header("ce-time", fixtures::time().to_rfc3339())
54            .finish();
55
56        let (req, mut body) = req.split();
57        let resp = Event::from_request(&req, &mut body).await.err().unwrap();
58        assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
59        assert_eq!(resp.to_string(), "Invalid specversion BAD SPECIFICATION");
60    }
61
62    #[tokio::test]
63    async fn test_request_with_full_data() {
64        let expected = fixtures::v10::full_binary_json_data_string_extension();
65
66        let req = Request::builder()
67            .method(Method::POST)
68            .header("ce-specversion", "1.0")
69            .header("ce-id", "0001")
70            .header("ce-type", "test_event.test_application")
71            .header("ce-source", "http://localhost/")
72            .header("ce-subject", "cloudevents-sdk")
73            .header("content-type", "application/json")
74            .header("ce-string_ex", "val")
75            .header("ce-int_ex", "10")
76            .header("ce-bool_ex", "true")
77            .header("ce-time", fixtures::time().to_rfc3339())
78            .body(fixtures::json_data_binary());
79        let (req, mut body) = req.split();
80        let result = Event::from_request(&req, &mut body).await.unwrap();
81
82        assert_eq!(expected, result);
83    }
84}