From d90400d73191cf23c4fc12c7331f5289c16eeed2 Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Wed, 11 Dec 2024 20:46:10 +0000 Subject: [PATCH] feat(nextcloud): add commnad 'nextcloud deck get' --- README.md | 2 +- src/nextcloud/board.rs | 35 -------- src/nextcloud/deck.rs | 33 +++++++ src/nextcloud/mod.rs | 24 ++--- src/nextcloud/tests.rs | 98 +++++++++++++++++++-- src/tests/responses/nextcloud-deck-get.json | 86 ++++++++++++++++++ 6 files changed, 222 insertions(+), 56 deletions(-) delete mode 100644 src/nextcloud/board.rs create mode 100644 src/nextcloud/deck.rs create mode 100644 src/tests/responses/nextcloud-deck-get.json diff --git a/README.md b/README.md index 9a03ccf..5babc9b 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ As part of building the import server, the following commands exercise each oper - [x] trello card get - includes list of attachments - [x] trello attachment get - includes download url - [x] trello attachment save - saves to disk -- [ ] nextcloud deck get (was board list) +- [x] nextcloud deck get - includes list of boards - [ ] nextcloud board get (was stack list) - [ ] nextcloud stack get (was card list) - [x] nextcloud card create diff --git a/src/nextcloud/board.rs b/src/nextcloud/board.rs deleted file mode 100644 index 4a234b2..0000000 --- a/src/nextcloud/board.rs +++ /dev/null @@ -1,35 +0,0 @@ -// -use clap::Parser; - -use crate::execute::Execute; -use crate::{p, FullCtx}; - -#[derive(Parser, Debug)] -pub(crate) enum NextcloudBoardCommand { - List { - #[clap(long, action = clap::ArgAction::SetTrue)] - dump: bool, - }, -} - -impl Execute for NextcloudBoardCommand { - async fn execute(self, ctx: FullCtx) -> color_eyre::Result<()> { - match self { - Self::List { dump } => list(&ctx, dump).await, - } - } -} - -pub(crate) async fn list(ctx: &FullCtx, dump: bool) -> color_eyre::Result<()> { - let api_result = ctx.deck_client().get_boards().await; - if dump { - p!(ctx.prt, "{}", api_result.text); - } else { - let mut boards = api_result.result?; - boards.sort_by_key(|stack| stack.title.clone()); - boards - .iter() - .for_each(|stack| p!(ctx.prt, "{}:{}", stack.id, stack.title)); - } - Ok(()) -} diff --git a/src/nextcloud/deck.rs b/src/nextcloud/deck.rs new file mode 100644 index 0000000..32cb3eb --- /dev/null +++ b/src/nextcloud/deck.rs @@ -0,0 +1,33 @@ +// +use clap::Parser; + +use crate::execute::Execute; +use crate::{p, FullCtx}; + +#[derive(Parser, Debug)] +pub(crate) enum NextcloudDeckCommand { + Get { + #[clap(long, action = clap::ArgAction::SetTrue)] + dump: bool, + }, +} + +impl Execute for NextcloudDeckCommand { + async fn execute(self, ctx: FullCtx) -> color_eyre::Result<()> { + match self { + Self::Get { dump } => { + let api_result = ctx.deck_client().get_boards().await; + if dump { + p!(ctx.prt, "{}", api_result.text); + } else { + let mut boards = api_result.result?; + boards.sort_by_key(|stack| stack.title.clone()); + boards + .iter() + .for_each(|stack| p!(ctx.prt, "{}:{}", stack.id, stack.title)); + } + Ok(()) + } + } + } +} diff --git a/src/nextcloud/mod.rs b/src/nextcloud/mod.rs index 9084818..2eadbaa 100644 --- a/src/nextcloud/mod.rs +++ b/src/nextcloud/mod.rs @@ -1,17 +1,19 @@ -use crate::execute::Execute; -use crate::nextcloud::board::NextcloudBoardCommand; -use crate::nextcloud::card::NextcloudCardCommand; -use crate::nextcloud::model::{ - NextcloudBoardId, NextcloudHostname, NextcloudPassword, NextcloudUsername, +// +use crate::{ + execute::Execute, + nextcloud::{ + card::NextcloudCardCommand, + deck::NextcloudDeckCommand, + model::{NextcloudBoardId, NextcloudHostname, NextcloudPassword, NextcloudUsername}, + stack::NextcloudStackCommand, + }, + FullCtx, }; -use crate::nextcloud::stack::NextcloudStackCommand; -use crate::FullCtx; use clap::Parser; -// -mod board; pub(crate) mod card; pub(crate) mod client; +pub(crate) mod deck; pub(crate) mod model; mod stack; @@ -21,7 +23,7 @@ mod tests; #[derive(Parser, Debug)] pub(crate) enum NextcloudCommand { #[clap(subcommand)] - Board(NextcloudBoardCommand), + Deck(NextcloudDeckCommand), #[clap(subcommand)] Stack(NextcloudStackCommand), #[clap(subcommand)] @@ -30,7 +32,7 @@ pub(crate) enum NextcloudCommand { impl Execute for NextcloudCommand { async fn execute(self, ctx: FullCtx) -> color_eyre::Result<()> { match self { - NextcloudCommand::Board(cmd) => cmd.execute(ctx).await, + NextcloudCommand::Deck(cmd) => cmd.execute(ctx).await, NextcloudCommand::Stack(cmd) => cmd.execute(ctx).await, NextcloudCommand::Card(cmd) => cmd.execute(ctx).await, } diff --git a/src/nextcloud/tests.rs b/src/nextcloud/tests.rs index 8942b4d..8ebb153 100644 --- a/src/nextcloud/tests.rs +++ b/src/nextcloud/tests.rs @@ -5,7 +5,6 @@ use serde_json::json; use crate::{ execute::Execute, nextcloud::{ - board::NextcloudBoardCommand, card::{AddLabel, Create}, model::{ Card, Label, NextcloudBoardId, NextcloudCardId, NextcloudCardTitle, NextcloudETag, @@ -110,11 +109,15 @@ mod config { mod commands { use super::*; - mod board { + mod deck { use super::*; + use crate::execute::Execute; + use crate::nextcloud::deck::NextcloudDeckCommand; + use crate::nextcloud::NextcloudCommand; + use crate::Command; #[tokio::test] - async fn list_dump() { + async fn get_dump() { //given let mock_net = kxio::net::mock(); @@ -123,7 +126,7 @@ mod commands { .get("https://host-name/index.php/apps/deck/api/v1.0/boards") .basic_auth("username", Some("password")) .respond(StatusCode::OK) - .body(include_str!("../tests/responses/nextcloud-board-list.json")) + .body(include_str!("../tests/responses/nextcloud-deck-get.json")) .expect("mock request"); let fs = given::a_filesystem(); @@ -132,22 +135,23 @@ mod commands { let prt = prt.as_test().unwrap(); //when - Command::Nextcloud(NextcloudCommand::Board(NextcloudBoardCommand::List { + Command::Nextcloud(NextcloudCommand::Deck(NextcloudDeckCommand::Get { dump: true, })) .execute(ctx) .await .expect("execute"); + //then let output = prt.output(); assert_eq!( output.trim(), - include_str!("../tests/responses/nextcloud-board-list.json").trim() + include_str!("../tests/responses/nextcloud-deck-get.json").trim() ); } #[tokio::test] - async fn list_no_dump() { + async fn get_no_dump() { //given let mock_net = kxio::net::mock(); @@ -156,7 +160,7 @@ mod commands { .get("https://host-name/index.php/apps/deck/api/v1.0/boards") .basic_auth("username", Some("password")) .respond(StatusCode::OK) - .body(include_str!("../tests/responses/nextcloud-board-list.json")) + .body(include_str!("../tests/responses/nextcloud-deck-get.json")) .expect("mock request"); let fs = given::a_filesystem(); @@ -165,13 +169,14 @@ mod commands { let prt = prt.as_test().unwrap(); //when - Command::Nextcloud(NextcloudCommand::Board(NextcloudBoardCommand::List { + Command::Nextcloud(NextcloudCommand::Deck(NextcloudDeckCommand::Get { dump: false, })) .execute(ctx) .await .expect("execute"); + //then let output = prt.output(); assert_eq!( output.trim(), @@ -185,6 +190,81 @@ mod commands { } } + // mod board { + // use super::*; + // + // #[tokio::test] + // async fn list_dump() { + // //given + // let mock_net = kxio::net::mock(); + // + // mock_net + // .on() + // .get("https://host-name/index.php/apps/deck/api/v1.0/boards") + // .basic_auth("username", Some("password")) + // .respond(StatusCode::OK) + // .body(include_str!("../tests/responses/nextcloud-board-list.json")) + // .expect("mock request"); + // + // let fs = given::a_filesystem(); + // let ctx = given::a_full_context(mock_net, fs); + // let prt = ctx.prt.clone(); + // let prt = prt.as_test().unwrap(); + // + // //when + // Command::Nextcloud(NextcloudCommand::Board(NextcloudBoardCommand::List { + // dump: true, + // })) + // .execute(ctx) + // .await + // .expect("execute"); + // + // let output = prt.output(); + // assert_eq!( + // output.trim(), + // include_str!("../tests/responses/nextcloud-board-list.json").trim() + // ); + // } + // + // #[tokio::test] + // async fn list_no_dump() { + // //given + // let mock_net = kxio::net::mock(); + // + // mock_net + // .on() + // .get("https://host-name/index.php/apps/deck/api/v1.0/boards") + // .basic_auth("username", Some("password")) + // .respond(StatusCode::OK) + // .body(include_str!("../tests/responses/nextcloud-board-list.json")) + // .expect("mock request"); + // + // let fs = given::a_filesystem(); + // let ctx = given::a_full_context(mock_net, fs); + // let prt = ctx.prt.clone(); + // let prt = prt.as_test().unwrap(); + // + // //when + // Command::Nextcloud(NextcloudCommand::Board(NextcloudBoardCommand::List { + // dump: false, + // })) + // .execute(ctx) + // .await + // .expect("execute"); + // + // let output = prt.output(); + // assert_eq!( + // output.trim(), + // [ + // "4:4 Published: Cossmass Infinities", + // "5:Fulfilment: Cossmass Infinities", + // "1:Personal Board" + // ] + // .join("\n") + // ); + // } + // } + mod stack { use super::*; diff --git a/src/tests/responses/nextcloud-deck-get.json b/src/tests/responses/nextcloud-deck-get.json new file mode 100644 index 0000000..cf5faff --- /dev/null +++ b/src/tests/responses/nextcloud-deck-get.json @@ -0,0 +1,86 @@ +[ + { + "id": 1, + "title": "Personal Board", + "owner": { + "primaryKey": "pcampbell", + "uid": "pcampbell", + "displayname": "Paul Campbell", + "type": 0 + }, + "color": "0087C5", + "archived": false, + "labels": [], + "acl": [], + "permissions": { + "PERMISSION_READ": true, + "PERMISSION_EDIT": true, + "PERMISSION_MANAGE": true, + "PERMISSION_SHARE": true + }, + "users": [], + "shared": 0, + "stacks": [], + "activeSessions": [], + "deletedAt": 0, + "lastModified": 1733695323, + "settings": [], + "ETag": "9de45fc7d68507f1eaef462e90e6414c" + }, + { + "id": 4, + "title": "4 Published: Cossmass Infinities", + "owner": { + "primaryKey": "pcampbell", + "uid": "pcampbell", + "displayname": "Paul Campbell", + "type": 0 + }, + "color": "ff0000", + "archived": true, + "labels": [], + "acl": [], + "permissions": { + "PERMISSION_READ": true, + "PERMISSION_EDIT": true, + "PERMISSION_MANAGE": true, + "PERMISSION_SHARE": true + }, + "users": [], + "shared": 0, + "stacks": [], + "activeSessions": [], + "deletedAt": 0, + "lastModified": 1699798570, + "settings": [], + "ETag": "5e0fe035f3b95672da3cba633086be37" + }, + { + "id": 5, + "title": "Fulfilment: Cossmass Infinities", + "owner": { + "primaryKey": "pcampbell", + "uid": "pcampbell", + "displayname": "Paul Campbell", + "type": 0 + }, + "color": "ff0000", + "archived": true, + "labels": [], + "acl": [], + "permissions": { + "PERMISSION_READ": true, + "PERMISSION_EDIT": true, + "PERMISSION_MANAGE": true, + "PERMISSION_SHARE": true + }, + "users": [], + "shared": 0, + "stacks": [], + "activeSessions": [], + "deletedAt": 0, + "lastModified": 1699798567, + "settings": [], + "ETag": "90e2f9d53c5f6ec83088425d4486e54d" + } +]