use anyhow::Result;
use clap::Parser;
use crate::atlassian::confluence_api::ConfluenceApi;
use crate::cli::atlassian::helpers::create_client;
#[derive(Parser)]
pub struct CopyCommand {
pub id: String,
#[arg(long)]
pub parent: String,
#[arg(long)]
pub title: String,
}
impl CopyCommand {
pub async fn execute(self) -> Result<()> {
let (client, _instance_url) = create_client()?;
let api = ConfluenceApi::new(client);
let new_id = api.copy_page(&self.id, &self.parent, &self.title).await?;
println!(
"Copied page {} to new page {} ({:?}).",
self.id, new_id, self.title
);
Ok(())
}
}
#[cfg(test)]
#[allow(clippy::unwrap_used, clippy::expect_used)]
mod tests {
use super::*;
#[test]
fn copy_command_struct_fields() {
let cmd = CopyCommand {
id: "12345".to_string(),
parent: "456".to_string(),
title: "Copy".to_string(),
};
assert_eq!(cmd.id, "12345");
assert_eq!(cmd.parent, "456");
assert_eq!(cmd.title, "Copy");
}
#[tokio::test(flavor = "current_thread")]
#[allow(clippy::await_holding_lock)]
async fn copy_command_execute_dispatch() {
let _lock = crate::atlassian::auth::test_util::AUTH_ENV_MUTEX
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
let server = wiremock::MockServer::start().await;
wiremock::Mock::given(wiremock::matchers::method("POST"))
.and(wiremock::matchers::path(
"/wiki/rest/api/content/12345/copy",
))
.respond_with(
wiremock::ResponseTemplate::new(200)
.set_body_json(serde_json::json!({"id": "99999"})),
)
.mount(&server)
.await;
std::env::set_var("ATLASSIAN_INSTANCE_URL", server.uri());
std::env::set_var("ATLASSIAN_EMAIL", "test@example.com");
std::env::set_var("ATLASSIAN_API_TOKEN", "fake-token");
std::env::remove_var("OMNI_DEV_ATLASSIAN_INSTANCE");
let cmd = CopyCommand {
id: "12345".to_string(),
parent: "456".to_string(),
title: "Copy".to_string(),
};
let result = cmd.execute().await;
std::env::remove_var("ATLASSIAN_INSTANCE_URL");
std::env::remove_var("ATLASSIAN_EMAIL");
std::env::remove_var("ATLASSIAN_API_TOKEN");
assert!(result.is_ok(), "got: {result:?}");
}
}