malcontent-dns-parental-con.../tests/common/dbus.rs

84 lines
2.3 KiB
Rust

// SPDX-FileCopyrightText: 2022 Matteo Settenvini <matteo.settenvini@montecristosoftware.eu>
// SPDX-License-Identifier: GPL-3.0-or-later
include!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/src/policy_checker/dbus.rs"
));
use {std::collections::HashMap, zbus::dbus_interface};
#[derive(Debug)]
pub struct MalcontentDBusMock {
responses: HashMap<Uid, Vec<Restrictions>>,
invocations_left: usize,
}
#[dbus_interface(name = "com.endlessm.ParentalControls.Dns")]
impl MalcontentDBusMock {
fn get_restrictions(&mut self, user_id: u32) -> Restrictions {
let answers = self
.responses
.get_mut(&Uid::from_raw(user_id))
.expect(&format!(
"MockError: No mocked invocations available for user with id {}",
user_id
));
let restrictions = answers.pop().expect(&format!(
"MockError: DBus mock is saturated for user with id {}",
user_id
));
self.invocations_left -= 1;
restrictions
}
}
impl MalcontentDBusMock {
pub fn new(mut responses: HashMap<Uid, Vec<Restrictions>>) -> Self {
let responses_size: usize = responses
.values()
.map(|v| {
std::cmp::max(
v.len(),
1, /* 'No restrictions' still counts as one message */
)
})
.sum();
for r in responses.values_mut() {
r.reverse(); // we pop responses from the back, so...
}
let ret = Self {
responses,
invocations_left: responses_size,
};
ret
}
}
impl Drop for MalcontentDBusMock {
fn drop(&mut self) {
assert_eq!(
self.invocations_left, 0,
"MockError: During teardown, {} invocations are still left on the mock object",
self.invocations_left
);
}
}
pub async fn mock_dbus(responses: HashMap<Uid, Vec<Restrictions>>) -> Result<zbus::Connection> {
let mock = MalcontentDBusMock::new(responses);
let connection = zbus::ConnectionBuilder::session()?
.serve_at("/com/endlessm/ParentalControls/Dns", mock)?
.build()
.await?;
std::env::set_var(
"TEST_DBUS_SERVICE_NAME",
connection.unique_name().unwrap().as_str(),
);
Ok(connection)
}