feat(nextcloud): add command 'nextcloud board create-label'
Some checks failed
Test / build (map[name:nightly]) (push) Successful in 2m7s
Test / build (map[name:stable]) (push) Successful in 2m11s
Release Please / Release-plz (push) Failing after 27s

This commit is contained in:
Paul Campbell 2024-12-20 08:18:37 +00:00
parent ad662cf422
commit e8c03ee925
6 changed files with 184 additions and 4 deletions

View file

@ -2,7 +2,7 @@
use clap::Parser; use clap::Parser;
use crate::execute::Execute; use crate::execute::Execute;
use crate::nextcloud::model::NextcloudBoardId; use crate::nextcloud::model::{NextcloudBoardId, NextcloudLabelColour, NextcloudLabelTitle};
use crate::{p, FullCtx}; use crate::{p, FullCtx};
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
@ -17,6 +17,13 @@ pub enum NextcloudBoardCommand {
dump: bool, dump: bool,
board_id: i64, board_id: i64,
}, },
CreateLabel {
#[clap(long, action = clap::ArgAction::SetTrue)]
dump: bool,
board_id: i64,
title: String,
colour: String,
},
} }
impl Execute for NextcloudBoardCommand { impl Execute for NextcloudBoardCommand {
@ -61,6 +68,35 @@ impl Execute for NextcloudBoardCommand {
} }
Ok(()) Ok(())
} }
Self::CreateLabel {
dump,
board_id,
title,
colour,
} => {
let api_result = ctx
.deck_client()
.create_label(
NextcloudBoardId::new(*board_id),
&NextcloudLabelTitle::new(title),
&NextcloudLabelColour::new(colour),
)
.await;
if *dump {
p!(ctx.prt, "{}", api_result.text);
} else {
let label = api_result.result?;
p!(
ctx.prt,
"{}:{}:{}:{}",
board_id,
label.id,
label.title,
label.color
);
}
Ok(())
}
} }
} }
} }

View file

@ -8,7 +8,10 @@ use reqwest::multipart;
use serde::de::DeserializeOwned; use serde::de::DeserializeOwned;
use serde_json::json; use serde_json::json;
use crate::nextcloud::model::{NextcloudCardDescription, NextcloudCardTitle, NextcloudStackTitle}; use crate::nextcloud::model::{
Label, NextcloudCardDescription, NextcloudCardTitle, NextcloudLabelColour, NextcloudLabelTitle,
NextcloudStackTitle,
};
use crate::{ use crate::{
api_result::APIResult, api_result::APIResult,
f, f,
@ -181,6 +184,24 @@ impl<'ctx> DeckClient<'ctx> {
.await .await
} }
pub(crate) async fn create_label(
&self,
board_id: NextcloudBoardId,
name: &NextcloudLabelTitle,
colour: &NextcloudLabelColour,
) -> APIResult<Label> {
self.request_with_body(
f!("boards/{board_id}/labels"),
json!({
"title": name,
"color": colour,
})
.to_string(),
|net, url| net.post(url),
)
.await
}
pub(crate) async fn get_card( pub(crate) async fn get_card(
&self, &self,
board_id: NextcloudBoardId, board_id: NextcloudBoardId,

View file

@ -64,6 +64,22 @@ newtype!(
Ord, Ord,
"ID of a Nextcloud Label" "ID of a Nextcloud Label"
); );
newtype!(
NextcloudLabelTitle,
String,
Display,
PartialOrd,
Ord,
"Title of a Nextcloud Label"
);
newtype!(
NextcloudLabelColour,
String,
Display,
PartialOrd,
Ord,
"Colour of a Nextcloud Label"
);
newtype!( newtype!(
NextcloudOrder, NextcloudOrder,
i64, i64,
@ -171,8 +187,8 @@ pub(crate) struct Card {
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
pub(crate) struct Label { pub(crate) struct Label {
pub(crate) id: NextcloudLabelId, pub(crate) id: NextcloudLabelId,
pub(crate) title: String, pub(crate) title: NextcloudLabelTitle,
pub(crate) color: String, pub(crate) color: NextcloudLabelColour,
} }
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]

View file

@ -0,0 +1,97 @@
//
use super::*;
#[rstest::fixture]
fn board_id() -> NextcloudBoardId {
NextcloudBoardId::new(2)
}
#[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}/labels",
))
.body(
json!({
"title": "my green label",
"color": "31CC7C",
})
.to_string(),
)
.respond(StatusCode::OK)
.body(include_str!(
"../../../tests/responses/nextcloud-board-create-label.json"
))
.expect("mock request");
FullCtx {
fs: fs.as_real(),
net: mock_net.into(),
prt: given::a_printer(),
cfg: AppConfig {
trello: given::a_trello_config(),
nextcloud: nextcloud_config,
},
}
}
#[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::CreateLabel {
dump: true,
board_id: board_id.into(),
title: "my green label".to_string(),
colour: "31CC7C".to_string(),
},
))
.execute(&ctx)
.await
.expect("execute");
//then
let output = prt.output();
assert_peq!(
output.trim(),
include_str!("../../../tests/responses/nextcloud-board-create-label.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::CreateLabel {
dump: false,
board_id: board_id.into(),
title: "my green label".to_string(),
colour: "31CC7C".to_string(),
},
))
.execute(&ctx)
.await
.expect("execute");
//then
let output = prt.output();
assert_peq!(output.trim(), "2:54:my green label:31CC7C");
}

View file

@ -1,5 +1,6 @@
// //
use super::*; use super::*;
mod create_label;
mod get; mod get;
mod labels; mod labels;

View file

@ -0,0 +1,9 @@
{
"id": 54,
"title": "my green label",
"color": "31CC7C",
"boardId": 1,
"cardId": null,
"lastModified": null,
"ETag": "d41d8cd98f00b204e9800998ecf8427e"
}