feat(nextcloud): add command 'nextcloud board labels'
This commit is contained in:
parent
336a5945a4
commit
2625ce44c0
6 changed files with 230 additions and 8 deletions
|
@ -7,6 +7,11 @@ use crate::{p, FullCtx};
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
pub enum NextcloudBoardCommand {
|
pub enum NextcloudBoardCommand {
|
||||||
|
Labels {
|
||||||
|
#[clap(long, action = clap::ArgAction::SetTrue)]
|
||||||
|
dump: bool,
|
||||||
|
board_id: i64,
|
||||||
|
},
|
||||||
Get {
|
Get {
|
||||||
#[clap(long, action = clap::ArgAction::SetTrue)]
|
#[clap(long, action = clap::ArgAction::SetTrue)]
|
||||||
dump: bool,
|
dump: bool,
|
||||||
|
@ -17,6 +22,29 @@ pub enum NextcloudBoardCommand {
|
||||||
impl Execute for NextcloudBoardCommand {
|
impl Execute for NextcloudBoardCommand {
|
||||||
async fn execute(&self, ctx: &FullCtx) -> color_eyre::Result<()> {
|
async fn execute(&self, ctx: &FullCtx) -> color_eyre::Result<()> {
|
||||||
match self {
|
match self {
|
||||||
|
Self::Labels { dump, board_id } => {
|
||||||
|
let api_result = ctx
|
||||||
|
.deck_client()
|
||||||
|
.get_board(NextcloudBoardId::new(*board_id))
|
||||||
|
.await;
|
||||||
|
if *dump {
|
||||||
|
p!(ctx.prt, "{}", api_result.text);
|
||||||
|
} else {
|
||||||
|
let mut labels = api_result.result?.labels;
|
||||||
|
labels.sort_by(|a, b| a.title.cmp(&b.title));
|
||||||
|
labels.into_iter().for_each(|label| {
|
||||||
|
p!(
|
||||||
|
ctx.prt,
|
||||||
|
"{}:{}:{}:{}",
|
||||||
|
board_id,
|
||||||
|
label.id,
|
||||||
|
label.color,
|
||||||
|
label.title
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
Self::Get { dump, board_id } => {
|
Self::Get { dump, board_id } => {
|
||||||
let api_result = ctx
|
let api_result = ctx
|
||||||
.deck_client()
|
.deck_client()
|
||||||
|
|
|
@ -119,6 +119,11 @@ impl<'ctx> DeckClient<'ctx> {
|
||||||
self.request("boards", |net, url| net.get(url)).await
|
self.request("boards", |net, url| net.get(url)).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn get_board(&self, board_id: NextcloudBoardId) -> APIResult<Board> {
|
||||||
|
self.request(f!("boards/{board_id}"), |net, url| net.get(url))
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) async fn get_stacks(&self, board_id: NextcloudBoardId) -> APIResult<Vec<Stack>> {
|
pub(crate) async fn get_stacks(&self, board_id: NextcloudBoardId) -> APIResult<Vec<Stack>> {
|
||||||
self.request(f!("boards/{board_id}/stacks"), |net, url| net.get(url))
|
self.request(f!("boards/{board_id}/stacks"), |net, url| net.get(url))
|
||||||
.await
|
.await
|
||||||
|
|
85
src/nextcloud/tests/board/labels.rs
Normal file
85
src/nextcloud/tests/board/labels.rs
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
//
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[rstest::fixture]
|
||||||
|
fn board_id() -> NextcloudBoardId {
|
||||||
|
NextcloudBoardId::new(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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()
|
||||||
|
.get(crate::f!(
|
||||||
|
"{hostname}/index.php/apps/deck/api/v1.0/boards/{board_id}",
|
||||||
|
))
|
||||||
|
.respond(StatusCode::OK)
|
||||||
|
.body(include_str!(
|
||||||
|
"../../../tests/responses/nextcloud-board-labels.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) {
|
||||||
|
//given
|
||||||
|
let prt = ctx.prt.clone();
|
||||||
|
let prt = prt.as_test().unwrap();
|
||||||
|
|
||||||
|
//when
|
||||||
|
Command::Nextcloud(NextcloudCommand::Board(NextcloudBoardCommand::Labels {
|
||||||
|
dump: true,
|
||||||
|
board_id: board_id.into(),
|
||||||
|
}))
|
||||||
|
.execute(&ctx)
|
||||||
|
.await
|
||||||
|
.expect("execute");
|
||||||
|
|
||||||
|
//then
|
||||||
|
let output = prt.output();
|
||||||
|
assert_eq!(
|
||||||
|
output.trim(),
|
||||||
|
include_str!("../../../tests/responses/nextcloud-board-labels.json").trim()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rstest::rstest]
|
||||||
|
#[test_log::test(tokio::test)]
|
||||||
|
async fn no_dump(ctx: FullCtx, board_id: NextcloudBoardId) {
|
||||||
|
//given
|
||||||
|
let prt = ctx.prt.clone();
|
||||||
|
let prt = prt.as_test().unwrap();
|
||||||
|
|
||||||
|
//when
|
||||||
|
Command::Nextcloud(NextcloudCommand::Board(NextcloudBoardCommand::Labels {
|
||||||
|
dump: false,
|
||||||
|
board_id: board_id.into(),
|
||||||
|
}))
|
||||||
|
.execute(&ctx)
|
||||||
|
.await
|
||||||
|
.expect("execute");
|
||||||
|
|
||||||
|
//then
|
||||||
|
let output = prt.output();
|
||||||
|
assert_eq!(
|
||||||
|
output.trim(),
|
||||||
|
[
|
||||||
|
"1:3:FF7A66:Action needed",
|
||||||
|
"1:1:31CC7C:Finished",
|
||||||
|
"1:4:F1DB50:Later",
|
||||||
|
"1:2:317CCC:To review"
|
||||||
|
]
|
||||||
|
.join("\n")
|
||||||
|
);
|
||||||
|
}
|
|
@ -2,3 +2,4 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
mod get;
|
mod get;
|
||||||
|
mod labels;
|
||||||
|
|
|
@ -8,24 +8,23 @@ use kxio::{
|
||||||
use pretty_assertions::assert_eq as assert_peq;
|
use pretty_assertions::assert_eq as assert_peq;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
use crate::execute::Execute;
|
|
||||||
use crate::nextcloud::card::NextcloudCardCommand;
|
|
||||||
use crate::nextcloud::deck::NextcloudDeckCommand;
|
|
||||||
use crate::nextcloud::NextcloudCommand;
|
|
||||||
use crate::Command;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
execute::Execute,
|
||||||
nextcloud::{
|
nextcloud::{
|
||||||
|
board::NextcloudBoardCommand,
|
||||||
|
card::NextcloudCardCommand,
|
||||||
|
deck::NextcloudDeckCommand,
|
||||||
model::{
|
model::{
|
||||||
Card, Label, NextcloudBoardId, NextcloudCardId, NextcloudCardTitle, NextcloudETag,
|
Card, Label, NextcloudBoardId, NextcloudCardId, NextcloudCardTitle, NextcloudETag,
|
||||||
NextcloudHostname, NextcloudLabelId, NextcloudOrder, NextcloudPassword,
|
NextcloudHostname, NextcloudLabelId, NextcloudOrder, NextcloudPassword,
|
||||||
NextcloudStackId, NextcloudStackTitle, NextcloudUsername, Stack,
|
NextcloudStackId, NextcloudStackTitle, NextcloudUsername, Stack,
|
||||||
},
|
},
|
||||||
NextcloudConfig,
|
stack::NextcloudStackCommand,
|
||||||
|
NextcloudCommand, NextcloudConfig,
|
||||||
},
|
},
|
||||||
s,
|
s,
|
||||||
tests::given,
|
tests::given,
|
||||||
trello::TrelloConfig,
|
AppConfig, Command, FullCtx,
|
||||||
AppConfig, FullCtx,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
mod board;
|
mod board;
|
||||||
|
|
104
src/tests/responses/nextcloud-board-labels.json
Normal file
104
src/tests/responses/nextcloud-board-labels.json
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"title": "Personal Board",
|
||||||
|
"owner": {
|
||||||
|
"primaryKey": "pcampbell",
|
||||||
|
"uid": "pcampbell",
|
||||||
|
"displayname": "Paul Campbell",
|
||||||
|
"type": 0
|
||||||
|
},
|
||||||
|
"color": "0087C5",
|
||||||
|
"archived": false,
|
||||||
|
"labels": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"title": "Finished",
|
||||||
|
"color": "31CC7C",
|
||||||
|
"boardId": 1,
|
||||||
|
"cardId": null,
|
||||||
|
"lastModified": 1670965629,
|
||||||
|
"ETag": "983f87848dc9c18d0aee63e7ee0fc83f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"title": "To review",
|
||||||
|
"color": "317CCC",
|
||||||
|
"boardId": 1,
|
||||||
|
"cardId": null,
|
||||||
|
"lastModified": 1670965629,
|
||||||
|
"ETag": "983f87848dc9c18d0aee63e7ee0fc83f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"title": "Action needed",
|
||||||
|
"color": "FF7A66",
|
||||||
|
"boardId": 1,
|
||||||
|
"cardId": null,
|
||||||
|
"lastModified": 1670965629,
|
||||||
|
"ETag": "983f87848dc9c18d0aee63e7ee0fc83f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 4,
|
||||||
|
"title": "Later",
|
||||||
|
"color": "F1DB50",
|
||||||
|
"boardId": 1,
|
||||||
|
"cardId": null,
|
||||||
|
"lastModified": 1670965629,
|
||||||
|
"ETag": "983f87848dc9c18d0aee63e7ee0fc83f"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"acl": [],
|
||||||
|
"permissions": {
|
||||||
|
"PERMISSION_READ": true,
|
||||||
|
"PERMISSION_EDIT": true,
|
||||||
|
"PERMISSION_MANAGE": true,
|
||||||
|
"PERMISSION_SHARE": true
|
||||||
|
},
|
||||||
|
"users": [
|
||||||
|
{
|
||||||
|
"primaryKey": "pcampbell",
|
||||||
|
"uid": "pcampbell",
|
||||||
|
"displayname": "Paul Campbell",
|
||||||
|
"type": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stacks": [
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"title": "Done",
|
||||||
|
"boardId": 1,
|
||||||
|
"deletedAt": 0,
|
||||||
|
"lastModified": 1733515991,
|
||||||
|
"order": 2,
|
||||||
|
"ETag": "dda386b3b247d7b4bd8917e19d38c01b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"title": "To do",
|
||||||
|
"boardId": 1,
|
||||||
|
"deletedAt": 0,
|
||||||
|
"lastModified": 1734639912,
|
||||||
|
"order": 0,
|
||||||
|
"ETag": "72a19db972245af551058eb5506adf68"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"title": "Doing",
|
||||||
|
"boardId": 1,
|
||||||
|
"deletedAt": 0,
|
||||||
|
"lastModified": 1733695323,
|
||||||
|
"order": 1,
|
||||||
|
"ETag": "9de45fc7d68507f1eaef462e90e6414c"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"activeSessions": [
|
||||||
|
"pcampbell"
|
||||||
|
],
|
||||||
|
"deletedAt": 0,
|
||||||
|
"lastModified": 1734639912,
|
||||||
|
"settings": {
|
||||||
|
"notify-due": "assigned",
|
||||||
|
"calendar": true
|
||||||
|
},
|
||||||
|
"ETag": "72a19db972245af551058eb5506adf68"
|
||||||
|
}
|
Loading…
Reference in a new issue