rpocket/service/
log.rs

1use serde::{Deserialize, Serialize};
2
3use crate::{error::RPocketError, service};
4
5/// LogGetRequestsStatsResponse is the response for the get requests stats.
6#[derive(Debug, Clone, Default, Serialize, Deserialize)]
7pub struct LogGetRequestsStatsResponse {
8    pub total: i64,
9    pub date: String,
10}
11
12/// LogGetRequestsStatsConfig is the config for the get requests stats.
13#[derive(Debug, Clone, Default, Serialize, Deserialize)]
14pub struct LogGetRequestsStatsConfig {
15    pub query_params: Vec<(String, String)>,
16}
17
18/// LogService is the service for logs.
19pub struct LogService<'a, C> {
20    client: &'a mut C,
21    request_base_path: String,
22}
23
24impl<'a, C> LogService<'a, C>
25where
26    C: crate::rpocket::PocketBaseClient + Sized,
27{
28    /// create a new LogService.
29    pub fn new(client: &'a mut C) -> Self {
30        LogService {
31            client,
32            request_base_path: "api/logs/requests".to_string(),
33        }
34    }
35
36    /// returns crud service.
37    pub fn crud(&'a mut self) -> service::crud::CRUDService<'a, C> {
38        self.client.crud(&self.request_base_path)
39    }
40
41    /// get the requests stats of the server.
42    pub async fn get_requests_stats<T>(
43        &mut self,
44        config: &LogGetRequestsStatsConfig,
45    ) -> Result<Vec<T>, RPocketError>
46    where
47        T: serde::de::DeserializeOwned,
48    {
49        let url = self
50            .client
51            .base_url()
52            .join(format!("{}/stats", self.request_base_path).as_str())?;
53
54        let request_builder = self
55            .client
56            .request_builder(reqwest::Method::GET, url.as_str())
57            .header(reqwest::header::CONTENT_TYPE.as_str(), "application/json")
58            .query(&config.query_params);
59
60        let response = self.client.http().send(request_builder).await?;
61
62        Ok(response.json::<Vec<T>>().await?)
63    }
64}
65
66#[cfg(test)]
67mod test {
68    use crate::PocketBase;
69
70    use super::*;
71
72    #[test]
73    fn test_log_crud() {
74        let mut base = PocketBase::new("http://test.com", "en");
75        let log_service = LogService::new(&mut base);
76
77        assert!(log_service.request_base_path == "api/logs/requests");
78    }
79
80    #[tokio::test]
81    async fn test_log_get_requests_stats() {
82        let mut server = mockito::Server::new();
83        let url = server.url();
84
85        let mock = server
86            .mock("GET", "/api/logs/requests/stats")
87            .with_status(200)
88            .with_header("Accept-Language", "en")
89            .match_header(reqwest::header::CONTENT_TYPE.as_str(), "application/json")
90            .with_body(
91                r#"[
92  {
93    "total": 4,
94    "date": "2022-06-01 19:00:00.000"
95  },
96  {
97    "total": 1,
98    "date": "2022-06-02 12:00:00.000"
99  },
100  {
101    "total": 8,
102    "date": "2022-06-02 13:00:00.000"
103  }
104                ]"#,
105            )
106            .create_async()
107            .await;
108
109        let mut base = PocketBase::new(url.as_str(), "en");
110        let mut log_service = LogService::new(&mut base);
111        let config = LogGetRequestsStatsConfig {
112            ..Default::default()
113        };
114
115        let response = log_service
116            .get_requests_stats::<LogGetRequestsStatsResponse>(&config)
117            .await;
118
119        mock.assert_async().await;
120        let response = response.unwrap();
121
122        assert!(response.len() == 3);
123        assert!(response[0].total == 4);
124        assert!(response[0].date == "2022-06-01 19:00:00.000");
125    }
126}