diff --git a/src/nextcloud/client.rs b/src/nextcloud/client.rs index a3f97cd..04ab51d 100644 --- a/src/nextcloud/client.rs +++ b/src/nextcloud/client.rs @@ -8,6 +8,7 @@ use reqwest::multipart; use serde::de::DeserializeOwned; use serde_json::json; +use crate::nextcloud::model::NextcloudStackTitle; use crate::{ api_result::APIResult, f, @@ -140,6 +141,23 @@ impl<'ctx> DeckClient<'ctx> { .await } + pub(crate) async fn create_stack( + &self, + board_id: NextcloudBoardId, + stack_title: &NextcloudStackTitle, + ) -> APIResult { + self.request_with_body( + f!("boards/{board_id}/stacks"), + json!({ + "title": stack_title, + "order": 999, + }) + .to_string(), + |net, url| net.post(url), + ) + .await + } + pub(crate) async fn create_card( &self, board_id: NextcloudBoardId, diff --git a/src/nextcloud/stack.rs b/src/nextcloud/stack.rs index 95b8c1f..72e15f7 100644 --- a/src/nextcloud/stack.rs +++ b/src/nextcloud/stack.rs @@ -12,6 +12,12 @@ pub enum NextcloudStackCommand { board_id: i64, stack_id: i64, }, + Create { + #[clap(long, action = clap::ArgAction::SetTrue)] + dump: bool, + board_id: i64, + stack_title: String, + }, } impl Execute for NextcloudStackCommand { @@ -37,6 +43,23 @@ impl Execute for NextcloudStackCommand { } Ok(()) } + Self::Create { + dump, + board_id, + stack_title, + } => { + let api_result = ctx + .deck_client() + .create_stack((*board_id).into(), &stack_title.clone().into()) + .await; + if *dump { + p!(ctx.prt, "{}", api_result.text); + } else { + let stack = api_result.result?; + p!(ctx.prt, "{}:{}:{}", board_id, stack.id, stack_title); + } + Ok(()) + } } } } diff --git a/src/nextcloud/tests/stack/create.rs b/src/nextcloud/tests/stack/create.rs new file mode 100644 index 0000000..e1a6230 --- /dev/null +++ b/src/nextcloud/tests/stack/create.rs @@ -0,0 +1,88 @@ +use crate::execute::Execute; +use crate::nextcloud::card::NextcloudCardCommand; +use crate::nextcloud::stack::NextcloudStackCommand; +use crate::nextcloud::NextcloudCommand; +use crate::Command; +// +use super::*; + +#[rstest::fixture] +fn board_id() -> NextcloudBoardId { + NextcloudBoardId::new(1) +} + +#[rstest::fixture] +fn stack_title() -> NextcloudStackTitle { + NextcloudStackTitle::new("Lunch") +} + +#[rstest::fixture] +fn ctx() -> FullCtx { + let fs = given::a_filesystem(); + + let nextcloud_config = given::a_nextcloud_config(); + let hostname = nextcloud_config.hostname; + let board_id = board_id(); + + let mock_net = given::a_network(); + mock_net + .on() + .post(crate::f!( + "{hostname}/index.php/apps/deck/api/v1.0/boards/{board_id}/stacks", + )) + .body(json!({"title":"Lunch","order":999}).to_string()) + .respond(StatusCode::OK) + .body(include_str!( + "../../../tests/responses/nextcloud-stack-create.json" + )) + .expect("mock request"); + + given::a_full_context(fs, mock_net) +} + +#[rstest::rstest] +#[test_log::test(tokio::test)] +async fn dump(ctx: FullCtx, board_id: NextcloudBoardId, stack_title: NextcloudStackTitle) { + //given + let prt = ctx.prt.clone(); + let prt = prt.as_test().unwrap(); + + //when + Command::Nextcloud(NextcloudCommand::Stack(NextcloudStackCommand::Create { + dump: true, + board_id: board_id.into(), + stack_title: stack_title.into(), + })) + .execute(&ctx) + .await + .expect("execute"); + + //then + let output = prt.output(); + assert_peq!( + output.trim(), + include_str!("../../../tests/responses/nextcloud-stack-create.json").trim() + ); +} + +#[rstest::rstest] +#[test_log::test(tokio::test)] +async fn no_dump(ctx: FullCtx, board_id: NextcloudBoardId, stack_title: NextcloudStackTitle) { + //given + let prt = ctx.prt.clone(); + let prt = prt.as_test().unwrap(); + + //when + Command::Nextcloud(NextcloudCommand::Stack(NextcloudStackCommand::Create { + dump: false, + board_id: board_id.into(), + stack_title: stack_title.into(), + })) + .execute(&ctx) + .await + .expect("execute"); + + //then + let output = prt.output(); + assert_peq!(output.trim(), ["1:30:Lunch"].join("\n")); +} diff --git a/src/nextcloud/tests/stack/mod.rs b/src/nextcloud/tests/stack/mod.rs index 2563f63..35088c2 100644 --- a/src/nextcloud/tests/stack/mod.rs +++ b/src/nextcloud/tests/stack/mod.rs @@ -1,4 +1,5 @@ // use super::*; +mod create; mod get; diff --git a/src/tests/responses/nextcloud-stack-create.json b/src/tests/responses/nextcloud-stack-create.json new file mode 100644 index 0000000..1d2216c --- /dev/null +++ b/src/tests/responses/nextcloud-stack-create.json @@ -0,0 +1,9 @@ +{ + "id": 30, + "title": "Incoming", + "boardId": 1, + "deletedAt": 0, + "lastModified": 0, + "order": 999, + "ETag": "cfcd208495d565ef66e7dff9f98764da" +}