use super::*;
pub struct ComposeDraft<'a> {
pub compose: &'a str,
pub name: Option<&'a str>,
pub workspace_id: Option<&'a str>,
pub project_id: Option<&'a str>,
pub repository: Option<&'a str>,
pub branch: Option<&'a str>,
pub deploy: bool,
}
impl ApiClient {
pub async fn import_compose(&self, draft: &ComposeDraft<'_>) -> Result<Answer<ComposeImport>> {
self.post_answer(
"/api/infra/projects/import-compose",
&compose_body(draft, self.environment()),
)
.await
}
pub async fn stacks(&self) -> Result<Answer<StacksPage>> {
self.get_answer("/api/infra/stacks").await
}
pub async fn add_stack(
&self,
project_id: &str,
key: &str,
deploy: bool,
) -> Result<Answer<PlacedStack>> {
self.post_answer(
&format!(
"/api/infra/projects/{project_id}/stacks/{}{}",
utf8_percent_encode(key, NON_ALPHANUMERIC),
self.environment_query('?')
),
&serde_json::json!({ "deploy": deploy }),
)
.await
}
pub async fn create_from_stack(
&self,
key: &str,
name: Option<&str>,
workspace_id: Option<&str>,
deploy: bool,
) -> Result<Answer<PlacedStack>> {
let mut body = serde_json::Map::new();
body.insert("deploy".into(), deploy.into());
if let Some(name) = name {
body.insert("name".into(), name.into());
}
if let Some(workspace_id) = workspace_id {
body.insert("workspaceId".into(), workspace_id.into());
}
self.post_answer(
&format!(
"/api/infra/stacks/{}/projects",
utf8_percent_encode(key, NON_ALPHANUMERIC)
),
&serde_json::Value::Object(body),
)
.await
}
pub async fn duplicate_service(
&self,
service_environment_id: &str,
name: &str,
deploy: bool,
) -> Result<Answer<CopiedServicePage>> {
let mut body = serde_json::Map::new();
body.insert("name".into(), name.into());
if !deploy {
body.insert("deployNow".into(), false.into());
}
self.post_answer(
&format!("/api/infra/services/{service_environment_id}/duplicate"),
&serde_json::Value::Object(body),
)
.await
}
}
fn compose_body(draft: &ComposeDraft<'_>, environment: Option<&str>) -> serde_json::Value {
let mut body = serde_json::Map::new();
body.insert("compose".into(), draft.compose.into());
body.insert("deploy".into(), draft.deploy.into());
if let Some(name) = draft.name {
body.insert("name".into(), name.into());
}
if let Some(workspace_id) = draft.workspace_id {
body.insert("workspaceId".into(), workspace_id.into());
}
if let Some(project_id) = draft.project_id {
body.insert("projectId".into(), project_id.into());
if let Some(environment) = environment {
body.insert("environment".into(), environment.into());
}
}
if let Some(repository) = draft.repository {
body.insert("repository".into(), repository.into());
body.insert("branch".into(), draft.branch.unwrap_or("main").into());
}
serde_json::Value::Object(body)
}
#[cfg(test)]
mod tests {
use super::*;
fn draft<'a>(project_id: Option<&'a str>, repository: Option<&'a str>) -> ComposeDraft<'a> {
ComposeDraft {
compose: "services: {}",
name: None,
workspace_id: None,
project_id,
repository,
branch: None,
deploy: false,
}
}
#[test]
fn it_should_send_the_environment_only_with_a_project_to_add_to() {
assert!(compose_body(&draft(None, None), Some("staging"))
.get("environment")
.is_none());
}
#[test]
fn it_should_send_the_environment_of_the_project_to_add_to() {
assert_eq!(
compose_body(&draft(Some("prj_1"), None), Some("staging"))["environment"],
"staging"
);
}
#[test]
fn it_should_build_from_main_unless_a_branch_is_given() {
assert_eq!(
compose_body(&draft(None, Some("pepito/tienda")), None)["branch"],
"main"
);
}
}