mocklogger/
submit1.rs

1// Author: D.S. Ljungmark <spider@skuggor.se>, Modio AB
2// SPDX-License-Identifier: AGPL-3.0-or-later
3mod builder;
4use crate::logger::LogErr;
5use crate::timefail::Timefail;
6use crate::types::Metadata;
7pub use builder::Builder;
8use modio_logger_db::Datastore;
9use tracing::{debug, error, info, instrument};
10use zbus::interface;
11
12pub struct Submit1 {
13    customer: bool,
14    ds: Datastore,
15    _timefail: Timefail,
16}
17
18impl Submit1 {
19    pub async fn new(timefail: Timefail, ds: Datastore, customer: bool) -> Result<Self, LogErr> {
20        if timefail.is_timefail() {
21            info!("Failing all pending change requests due to TIMEFAIL");
22            ds.transaction_fail_pending().await?;
23        }
24        Ok(Self {
25            ds,
26            _timefail: timefail,
27            customer,
28        })
29    }
30
31    #[must_use]
32    pub const fn builder() -> Builder {
33        Builder::new()
34    }
35}
36
37#[interface(name = "se.modio.logger.Submit1")]
38impl Submit1 {
39    /// Returns a vector of all metadata objects.
40    #[instrument(skip_all)]
41    pub(crate) async fn get_all_metadata(&mut self) -> Result<Vec<Metadata>, LogErr> {
42        use std::convert::Into;
43        let data = if self.customer {
44            debug!("Retrieving all customer metadata");
45            self.ds
46                .get_all_metadata()
47                .await
48                .inspect_err(|e| error!("Failed to get all customer metadata: err={:?}", e))?
49        } else {
50            debug!("Retrieving all internal metadata");
51            self.ds
52                .get_all_internal_metadata()
53                .await
54                .inspect_err(|e| error!("Failed to get all internal metadata: err={:?}", e))?
55        };
56        let arr: Vec<Metadata> = data.into_iter().map(Into::into).collect();
57        debug!("Returning {} metadata items", arr.len());
58        Ok(arr)
59    }
60}
61
62#[cfg(test)]
63mod test {
64    use crate::submit1::Submit1;
65    use modio_logger_db::Datastore;
66    use std::error::Error;
67    use test_log::test;
68    use timeout_macro::timeouttest;
69
70    #[test(timeouttest)]
71    async fn test_submit1_interface() -> Result<(), Box<dyn Error>> {
72        use zbus::object_server::Interface;
73        let submit1 = Submit1::builder().development(true).build().await?;
74        let mut result = String::new();
75        submit1.introspect_to_writer(&mut result, 0);
76        assert_eq!(
77            result,
78            r#"<interface name="se.modio.logger.Submit1">
79  <!--
80   Returns a vector of all metadata objects.
81   -->
82  <method name="GetAllMetadata">
83    <arg type="aa{sv}" direction="out"/>
84  </method>
85</interface>
86"#
87        );
88        Ok(())
89    }
90
91    #[test(timeouttest)]
92    async fn metadata_filters_for_modio() -> Result<(), Box<dyn Error>> {
93        let ds = Datastore::temporary().await;
94        ds.metadata_set_name("modio.key.key", "Internal only")
95            .await?;
96        ds.metadata_set_name("key.key.key.one", "Some Test Name")
97            .await?;
98        ds.metadata_set_name("key.key.key.two", "Some Test Name")
99            .await?;
100        ds.metadata_set_name("key.key.key.three", "Some Test Name")
101            .await?;
102
103        let mut submit1 = Submit1::builder()
104            .development(true)
105            .datastore(ds)
106            .customer(false)
107            .build()
108            .await?;
109
110        let res = submit1.get_all_metadata().await?;
111        // Should have 1 key
112        assert_eq!(res.len(), 1);
113        assert!(res[0].n.starts_with("modio."));
114        Ok(())
115    }
116
117    #[test(timeouttest)]
118    async fn metadata_filters_on_customer() -> Result<(), Box<dyn Error>> {
119        let ds = Datastore::temporary().await;
120        ds.metadata_set_name("modio.key.key", "Internal only")
121            .await?;
122        ds.metadata_set_name("key.key.key.one", "Some Test Name")
123            .await?;
124        ds.metadata_set_name("key.key.key.two", "Some Test Name")
125            .await?;
126        ds.metadata_set_name("key.key.key.three", "Some Test Name")
127            .await?;
128
129        let mut submit1 = Submit1::builder()
130            .development(true)
131            .datastore(ds)
132            .customer(true)
133            .build()
134            .await?;
135
136        let res = submit1.get_all_metadata().await?;
137        // should have "key.key...." but not "modio...."
138        assert_eq!(res.len(), 3);
139        assert!(res[0].n.starts_with("key.key.key"));
140        Ok(())
141    }
142}