use dsh_api::application_types::{ApplicationValues, EnvVarInjection};
use dsh_api::secret::{secret_env_vars_from_application, secret_env_vars_from_applications, secrets_from_application, secrets_from_applications};
use dsh_api::types::{Application, ApplicationSecret, ApplicationVolumes, PortMapping};
use dsh_api::volume::{volumes_from_application, volumes_from_applications};
use std::collections::HashMap;
use std::fmt::Display;
#[test]
fn test_secrets_from_application() {
let application = application(None);
let application_secrets = secrets_from_application(&application);
assert_eq!(application_secrets.len(), 2);
assert_eq!(
application_secrets.first().unwrap(),
&EnvVarInjection::new("secret1", vec!["SECRET_KEY11", "SECRET_KEY12"])
);
assert_eq!(application_secrets.get(1).unwrap(), &EnvVarInjection::new("secret2", vec!["SECRET_KEY2"]));
}
#[test]
fn test_secrets_from_applications() {
let mut application1 = application(Some("A1".to_string()));
add_secret(&mut application1, "joined_secret", "A1_JOINED_SECRET_KEY1");
add_secret(&mut application1, "joined_secret", "A1_JOINED_SECRET_KEY2");
let mut application2 = application(Some("A2".to_string()));
add_secret(&mut application2, "joined_secret", "A2_JOINED_SECRET_KEY");
let applications = HashMap::from([("A1".to_string(), application1), ("A2".to_string(), application2)]);
let application_secrets = secrets_from_applications(&applications);
assert_eq!(application_secrets.len(), 2);
let ApplicationValues { id: id1, values: values1, .. } = application_secrets.first().unwrap();
assert_eq!(*id1, "A1");
assert_eq!(values1.len(), 3);
assert_eq!(
values1.first().unwrap(),
&EnvVarInjection::new("a1_secret1", vec!["A1_SECRET_KEY11", "A1_SECRET_KEY12"])
);
assert_eq!(values1.get(1).unwrap(), &EnvVarInjection::new("a1_secret2", vec!["A1_SECRET_KEY2"]));
assert_eq!(
values1.get(2).unwrap(),
&EnvVarInjection::new("joined_secret", vec!["A1_JOINED_SECRET_KEY1", "A1_JOINED_SECRET_KEY2"])
);
let ApplicationValues { id: id2, values: values2, .. } = application_secrets.get(1).unwrap();
assert_eq!(*id2, "A2");
assert_eq!(values2.len(), 3);
assert_eq!(
values2.first().unwrap(),
&EnvVarInjection::new("a2_secret1", vec!["A2_SECRET_KEY11", "A2_SECRET_KEY12"])
);
assert_eq!(values2.get(1).unwrap(), &EnvVarInjection::new("a2_secret2", vec!["A2_SECRET_KEY2"]));
assert_eq!(values2.get(2).unwrap(), &EnvVarInjection::new("joined_secret", vec!["A2_JOINED_SECRET_KEY"]));
}
#[test]
fn test_secret_env_vars_from_application() {
let application = application(None);
let secrets_env_vars = secret_env_vars_from_application("secret1", &application);
assert_eq!(secrets_env_vars, vec!["SECRET_KEY11", "SECRET_KEY12"]);
}
#[test]
fn test_secret_env_vars_from_applications() {
let mut application1 = application(Some("A1".to_string()));
add_secret(&mut application1, "joined_secret", "A1_JOINED_SECRET_KEY1");
add_secret(&mut application1, "joined_secret", "A1_JOINED_SECRET_KEY2");
let mut application2 = application(Some("A2".to_string()));
add_secret(&mut application2, "joined_secret", "A2_JOINED_SECRET_KEY");
let applications = HashMap::from([("A1".to_string(), application1), ("A2".to_string(), application2)]);
let applications_a1_secret1 = secret_env_vars_from_applications("a1_secret1", &applications);
assert_eq!(applications_a1_secret1.len(), 1);
let first = applications_a1_secret1.first().unwrap();
assert_eq!(first.id, "A1");
assert_eq!(first.values, vec!["A1_SECRET_KEY11", "A1_SECRET_KEY12"]);
let applications_a1_secret2 = secret_env_vars_from_applications("a1_secret2", &applications);
assert_eq!(applications_a1_secret2.len(), 1);
let first = applications_a1_secret2.first().unwrap();
assert_eq!(first.id, "A1");
assert_eq!(first.values, vec!["A1_SECRET_KEY2"]);
let applications_a2_secret1 = secret_env_vars_from_applications("a2_secret1", &applications);
assert_eq!(applications_a2_secret1.len(), 1);
let first = applications_a2_secret1.first().unwrap();
assert_eq!(first.id, "A2");
assert_eq!(first.values, vec!["A2_SECRET_KEY11", "A2_SECRET_KEY12"]);
let applications_a2_secret2 = secret_env_vars_from_applications("a2_secret2", &applications);
assert_eq!(applications_a2_secret2.len(), 1);
let first = applications_a2_secret2.first().unwrap();
assert_eq!(first.id, "A2");
assert_eq!(first.values, vec!["A2_SECRET_KEY2"]);
let applications_joined_secret = secret_env_vars_from_applications("joined_secret", &applications);
assert_eq!(applications_joined_secret.len(), 2);
let first = applications_joined_secret.first().unwrap();
assert_eq!(first.id, "A1");
assert_eq!(first.values, vec!["A1_JOINED_SECRET_KEY1", "A1_JOINED_SECRET_KEY2"]);
let second = applications_joined_secret.get(1).unwrap();
assert_eq!(second.id, "A2");
assert_eq!(second.values, vec!["A2_JOINED_SECRET_KEY"]);
}
#[test]
fn test_volumes_from_application() {
let application = application(None);
let application_volumes: Vec<(&str, &str)> = volumes_from_application(&application);
assert_eq!(application_volumes.len(), 2);
let first = application_volumes.first().unwrap();
assert_eq!(first.0, "volume1");
assert_eq!(first.1, "/path1".to_string());
let second = application_volumes.get(1).unwrap();
assert_eq!(second.0, "volume2");
assert_eq!(second.1, "/path2");
}
#[test]
fn test_volumes_from_applications() {
let application1 = application(Some("A1".to_string()));
let application2 = application(Some("A2".to_string()));
let applications = HashMap::from([("A1".to_string(), application1), ("A2".to_string(), application2)]);
let application_volumes: Vec<ApplicationValues<(&str, &str)>> = volumes_from_applications(&applications);
assert_eq!(application_volumes.len(), 2);
let first = application_volumes.first().unwrap();
assert_eq!(first.id, "A1");
assert_eq!(first.values.first().unwrap().0, "a1_volume1");
assert_eq!(first.values.first().unwrap().1, "/a1_path1");
assert_eq!(first.values.get(1).unwrap().0, "a1_volume2");
assert_eq!(first.values.get(1).unwrap().1, "/a1_path2");
let second = application_volumes.get(1).unwrap();
assert_eq!(second.id, "A2");
assert_eq!(second.values.first().unwrap().0, "a2_volume1");
assert_eq!(second.values.first().unwrap().1, "/a2_path1");
assert_eq!(second.values.get(1).unwrap().0, "a2_volume2");
assert_eq!(second.values.get(1).unwrap().1, "/a2_path2");
}
fn application(id: Option<String>) -> Application {
let prefix = match id {
Some(id) => format!("{}_", id),
None => "".to_string(),
};
let pfl = |s: &str| format!("{}{}", prefix.to_lowercase(), s);
let pfu = |s: &str| format!("{}{}", prefix.to_uppercase(), s);
Application {
cpus: 0.0,
env: HashMap::from([
(pfu("BUCKETNAME"), format!("{{ bucket_name('{}bucketname') }}", prefix.to_lowercase())),
(pfu("HOSTNAME"), format!("{{ database_host('{}database1') }}", prefix.to_lowercase())),
(pfu("DATABASE"), format!("{{ database_id('{}database1') }}", prefix.to_lowercase())),
(pfu("USERNAME"), format!("{{ database_user('{}database1') }})", prefix.to_lowercase())),
(pfu("KEY1"), pfu("VALUE1")),
(pfu("KEY2"), pfu("VALUE2")),
]),
exposed_ports: HashMap::from([("8000".to_string(), port_mapping(pfl("vhost1"), None::<String>)), ("8001".to_string(), port_mapping(pfl("vhost2"), Some("public")))]),
health_check: None,
image: "".to_string(),
instances: 0,
mem: 0,
metrics: None,
needs_token: false,
node_features: None,
readable_streams: vec![],
secrets: vec![
secret(pfl("secret1"), pfu("SECRET_KEY12")),
secret(pfl("secret2"), pfu("SECRET_KEY2")),
secret(pfl("secret1"), pfu("SECRET_KEY11")),
],
single_instance: false,
spread_group: None,
topics: vec![pfl("topic1"), pfl("topic2"), pfl("topic3")],
user: "".to_string(),
volumes: HashMap::from([(format!("/{}", pfl("path1")), volume(pfl("volume1"))), (format!("/{}", pfl("path2")), volume(pfl("volume2")))]),
writable_streams: vec![],
}
}
fn port_mapping<S, T>(vhost: S, zone: Option<T>) -> PortMapping
where
S: Display,
T: Display,
{
PortMapping {
vhost: match zone {
Some(zone) => Some(format!("{{ vhost('{}','{}') }}", vhost, zone)),
None => Some(format!("{{ vhost('{}') }}", vhost)),
},
..PortMapping::default()
}
}
fn secret<S, T>(secret_name: S, env_key: T) -> ApplicationSecret
where
S: Into<String>,
T: ToString,
{
ApplicationSecret::new(secret_name, &[env_key])
}
fn volume<T>(volume_id: T) -> ApplicationVolumes
where
T: Display,
{
ApplicationVolumes::new(format!("{{ volume('{}') }}", volume_id))
}
fn add_secret<S, T>(application: &mut Application, id: S, key: T)
where
S: Into<String>,
T: ToString,
{
application.secrets.push(ApplicationSecret::new(id, &[key]));
}