Skip to content

Commit

Permalink
test Productstore::load
Browse files Browse the repository at this point in the history
  • Loading branch information
mvidner committed Sep 5, 2024
1 parent 534edc0 commit 82696eb
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 3 deletions.
1 change: 1 addition & 0 deletions rust/agama-lib/src/base_http_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use crate::{auth::AuthToken, error::ServiceError};
/// client.get("/questions").await
/// }
/// ```
#[derive(Clone)]
pub struct BaseHTTPClient {
client: reqwest::Client,
pub base_url: String,
Expand Down
2 changes: 1 addition & 1 deletion rust/agama-lib/src/product/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use serde::{Deserialize, Serialize};

/// Software settings for installation
#[derive(Debug, Default, Serialize, Deserialize)]
#[derive(Debug, Default, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct ProductSettings {
/// ID of the product to install (e.g., "ALP", "Tumbleweed", etc.)
Expand Down
77 changes: 75 additions & 2 deletions rust/agama-lib/src/product/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,23 @@ impl ProductStore {
})
}

fn non_empty_string(s: String) -> Option<String> {
if s.is_empty() {
None
} else {
Some(s)
}
}

pub async fn load(&self) -> Result<ProductSettings, ServiceError> {
let product = self.product_client.product().await?;
let registration_code = self.product_client.registration_code().await?;
let email = self.product_client.email().await?;

Ok(ProductSettings {
id: Some(product),
registration_code: Some(registration_code),
registration_email: Some(email),
registration_code: Self::non_empty_string(registration_code),
registration_email: Self::non_empty_string(email),
})
}

Expand Down Expand Up @@ -61,3 +69,68 @@ impl ProductStore {
Ok(())
}
}

#[cfg(test)]
mod test {
use super::*;
use crate::base_http_client::BaseHTTPClient;
use httpmock::prelude::*;
use std::error::Error;
use tokio::test; // without this, "error: async functions cannot be used for tests"

fn product_store(mock_server_url: String) -> ProductStore {
let mut bhc = BaseHTTPClient::default();
bhc.base_url = mock_server_url;
let p_client = ProductHTTPClient::new_with_base(bhc.clone());
let m_client = ManagerHTTPClient::new_with_base(bhc);
ProductStore {
product_client: p_client,
manager_client: m_client,
}
}

#[test]
async fn test_getting_product() -> Result<(), Box<dyn Error>> {
let server = MockServer::start();
let software_mock = server.mock(|when, then| {
when.method(GET).path("/api/software/config");
then.status(200)
.header("content-type", "application/json")
.body(
r#"{
"patterns": {"xfce":true},
"product": "Tumbleweed"
}"#,
);
});
let registration_mock = server.mock(|when, then| {
when.method(GET).path("/api/software/registration");
then.status(200)
.header("content-type", "application/json")
.body(
r#"{
"key": "",
"email": "",
"requirement": "NotRequired"
}"#,
);
});
let url = server.url("/api");

let store = product_store(url);
let settings = store.load().await?;

let expected = ProductSettings {
id: Some("Tumbleweed".to_owned()),
registration_code: None,
registration_email: None,
};
// main assertion
assert_eq!(settings, expected);

// Ensure the specified mock was called exactly one time (or fail with a detailed error description).
software_mock.assert();
registration_mock.assert_hits(2);
Ok(())
}
}

0 comments on commit 82696eb

Please sign in to comment.