From 3befecd645e329b6fd18a7c310d9bb531fc4df45 Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Fri, 20 Dec 2024 06:50:51 +0000 Subject: [PATCH] fix(trello): parse labels on cards --- src/tests/responses/trello-stack-get.json | 302 ++++++++++++++++++++++ src/trello/model/card.rs | 9 +- src/trello/model/label.rs | 13 +- src/trello/tests/stack/get.rs | 10 +- 4 files changed, 323 insertions(+), 11 deletions(-) create mode 100644 src/tests/responses/trello-stack-get.json diff --git a/src/tests/responses/trello-stack-get.json b/src/tests/responses/trello-stack-get.json new file mode 100644 index 0000000..071975f --- /dev/null +++ b/src/tests/responses/trello-stack-get.json @@ -0,0 +1,302 @@ +[ + { + "id": "674e03794ef7340ece3ebb5f", + "badges": { + "attachmentsByType": { + "trello": { + "board": 0, + "card": 0 + } + }, + "externalSource": null, + "location": false, + "votes": 0, + "viewingMemberVoted": false, + "subscribed": false, + "attachments": 1, + "fogbugz": "", + "checkItems": 0, + "checkItemsChecked": 0, + "checkItemsEarliestDue": null, + "comments": 0, + "description": true, + "due": "2025-01-07T00:00:00.000Z", + "dueComplete": false, + "lastUpdatedByAi": false, + "start": null + }, + "checkItemStates": [], + "closed": false, + "dueComplete": false, + "dateLastActivity": "2024-12-02T19:02:17.596Z", + "desc": "**In _A Conventional Boy_, the fate of the world will depend on a roll of the dice... twenty-sided dice, that is.**\n\nIn 1984, Derek Reilly was just another teenage nerd growing up in middle England. But his love of D&D caused him to fall afoul of the Laundry, a government agency tasked with suppressing supernatural threats. It turns out that sometimes ninth level wizard spells drawn on the back of your maths textbook can look suspiciously like _actual_ magic...\n\nDecades later, Derek is a long-term inmate at Camp Sunshine, a centre for deprogramming captured cultists. But Derek finally has reason to escape, and an escape plan to out into action: he wants to attend his first gaming convention. While Derek's D&D games were fictional, a game at the con really _is_ a dread ritual designed to summon a great evil into our world, and it's up to Derek and his players to stop them.\n\nThe fate of the world may depend on the contents of Derek's dice bag.\n\n**The Laundry Files series follows an agency of British spies who deal with supernatural threats; they also have to deal with chronic underfunding, government ministers, rival agencies and worst of all, each other. Think _Slow Horses_ crossed with the monsters from _Stranger Things,_ this series is funny, nerdy, and a cult classic.**\n\n\\*\\**Publishing just ahead of the final Laundry Files novel (_The Regicide Report_, summer 2025), this collection includes the never before published Laundry Files novel _A Conventional Boy_ - inspired by the 1980s Satanic Panic - and two other short stories in this joyous celebration of all things Laundry Files.\\*\\**\n\nIn this collection:\n\\*A CONVENTIONAL BOY (53.3k words)\n\\*DOWN ON THE FARM (12.7k words)\n\\*OVERTIME (8.7k words)\nalso includes exclusive afterword from Charles Stross\n\n©2025 Charles Stross (P)2025 Hachette Audio UK", + "descData": { + "emoji": {} + }, + "due": "2025-01-07T00:00:00.000Z", + "dueReminder": -1, + "email": null, + "idBoard": "5d9a1af1f3e8b612d60a896b", + "idChecklists": [], + "idList": "6567867b479459ba5dd5ac73", + "idMembers": [], + "idMembersVoted": [], + "idShort": 1301, + "idAttachmentCover": "674e037d459de55dd7c4e3b1", + "labels": [ + { + "id": "5d9a1af18bdee58e0dd8ae6b", + "idBoard": "5d9a1af1f3e8b612d60a896b", + "idOrganization": "60ae02462b2b134135ee7152", + "name": "Audiobook", + "nodeId": "ari:cloud:trello::label/workspace/60ae02462b2b134135ee7152/5d9a1af18bdee58e0dd8ae6b", + "color": "orange", + "uses": 312 + } + ], + "idLabels": [ + "5d9a1af18bdee58e0dd8ae6b" + ], + "manualCoverAttachment": false, + "name": "Charles Stross: Laundry Files: 13. A Conventional Boy", + "pinned": false, + "pos": 32768, + "shortLink": "ZamQwcCt", + "shortUrl": "https://trello.com/c/ZamQwcCt", + "start": null, + "subscribed": false, + "url": "https://trello.com/c/ZamQwcCt/1301-charles-stross-laundry-files-13-a-conventional-boy", + "cover": { + "idAttachment": "674e037d459de55dd7c4e3b1", + "color": null, + "idUploadedBackground": null, + "size": "normal", + "brightness": "dark", + "idPlugin": null + }, + "isTemplate": false, + "cardRole": null + }, + { + "id": "674e095fdcccbd01a02bfacc", + "badges": { + "attachmentsByType": { + "trello": { + "board": 0, + "card": 0 + } + }, + "externalSource": null, + "location": false, + "votes": 0, + "viewingMemberVoted": false, + "subscribed": false, + "attachments": 1, + "fogbugz": "", + "checkItems": 0, + "checkItemsChecked": 0, + "checkItemsEarliestDue": null, + "comments": 0, + "description": true, + "due": "2025-02-27T00:00:00.000Z", + "dueComplete": false, + "lastUpdatedByAi": false, + "start": null + }, + "checkItemStates": [], + "closed": false, + "dueComplete": false, + "dateLastActivity": "2024-12-02T19:25:12.393Z", + "desc": "**They looked into darkness. The darkness looked back . . .**\n\n**An utterly gripping story of survival on a hostile planet from Adrian Tchaikovsky, author of the Arthur C. Clarke Award-winning _Children of Time_.**\n\nA commercial expedition to a distant star system discovers a pitch-black moon alive with radio activity. Its high-gravity, high-pressure, zero-oxygen environment is deadly to human life, but ripe for exploitation. They named it Shroud.\n\nUnder no circumstances can a human survive Shroud’s inhospitable surface – but a catastrophic accident forces Juna Ceelander and Mai Ste Etienne to make an emergency landing in a barely adequate escape vehicle. Alone, and fighting for survival, the two women embark on a gruelling journey across land, sea and air in search of salvation.\n\nBut as they travel, Juna and Mai begin to understand Shroud’s unnerving alien species. It also begins to understand them. If they escape Shroud, they’ll somehow have to explain the impossible and translate the incredible. That is, if they make it back at all . . .\n\n©2025 Adrian Tchaikovsky (P)2025 Macmillan Publishers International Limited", + "descData": { + "emoji": {} + }, + "due": "2025-02-27T00:00:00.000Z", + "dueReminder": -1, + "email": null, + "idBoard": "5d9a1af1f3e8b612d60a896b", + "idChecklists": [], + "idList": "6567867b479459ba5dd5ac73", + "idMembers": [], + "idMembersVoted": [], + "idShort": 1307, + "idAttachmentCover": "674e09699984b18e83992135", + "labels": [ + { + "id": "5d9a1af18bdee58e0dd8ae6b", + "idBoard": "5d9a1af1f3e8b612d60a896b", + "idOrganization": "60ae02462b2b134135ee7152", + "name": "Audiobook", + "nodeId": "ari:cloud:trello::label/workspace/60ae02462b2b134135ee7152/5d9a1af18bdee58e0dd8ae6b", + "color": "orange", + "uses": 312 + } + ], + "idLabels": [ + "5d9a1af18bdee58e0dd8ae6b" + ], + "manualCoverAttachment": false, + "name": "Adrian Tchaikovsky: Shroud", + "pinned": false, + "pos": 36864, + "shortLink": "Xi44Mf9Q", + "shortUrl": "https://trello.com/c/Xi44Mf9Q", + "start": null, + "subscribed": false, + "url": "https://trello.com/c/Xi44Mf9Q/1307-adrian-tchaikovsky-shroud", + "cover": { + "idAttachment": "674e09699984b18e83992135", + "color": null, + "idUploadedBackground": null, + "size": "normal", + "brightness": "dark", + "idPlugin": null + }, + "isTemplate": false, + "cardRole": null + }, + { + "id": "674e047dfe4e6f56f367780b", + "badges": { + "attachmentsByType": { + "trello": { + "board": 0, + "card": 0 + } + }, + "externalSource": null, + "location": false, + "votes": 0, + "viewingMemberVoted": false, + "subscribed": false, + "attachments": 1, + "fogbugz": "", + "checkItems": 0, + "checkItemsChecked": 0, + "checkItemsEarliestDue": null, + "comments": 0, + "description": true, + "due": "2025-07-02T23:00:00.000Z", + "dueComplete": false, + "lastUpdatedByAi": false, + "start": null + }, + "checkItemStates": [], + "closed": false, + "dueComplete": false, + "dateLastActivity": "2024-12-02T19:04:35.092Z", + "desc": "**THE BRAND NEW NOVEL IN THE NUMBER ONE BESTSELLING RIVERS OF LONDON SERIES**\n\n_**'This isn't London. The rules are different up here...'**_\n\nAll Detective Constable Peter Grant wanted was a nice holiday up in Scotland.\nHe'll need one once this is over...\n\nSea: check.\nSand: some.\nSun: sort of - but that's not the only thing in the sky...\n\n- \\* \\* \\* \\*\n\n'Ben Aaronovitch has created a wonderful world full of mystery, magic and fantastic characters. I love being there more than the real London'\n**NICK FROST**\n\n©2025 Ben Aaronovitch (P)2025 Orion Publishing Group Limited", + "descData": { + "emoji": {} + }, + "due": "2025-07-02T23:00:00.000Z", + "dueReminder": -1, + "email": null, + "idBoard": "5d9a1af1f3e8b612d60a896b", + "idChecklists": [], + "idList": "6567867b479459ba5dd5ac73", + "idMembers": [], + "idMembersVoted": [], + "idShort": 1303, + "idAttachmentCover": "674e04812d99115359fe29a7", + "labels": [], + "idLabels": [], + "manualCoverAttachment": false, + "name": "Ben Aaronovitch: Rivers of London: 10. Stone and Sky", + "pinned": false, + "pos": 40960, + "shortLink": "inz7DjTF", + "shortUrl": "https://trello.com/c/inz7DjTF", + "start": null, + "subscribed": false, + "url": "https://trello.com/c/inz7DjTF/1303-ben-aaronovitch-rivers-of-london-10-stone-and-sky", + "cover": { + "idAttachment": "674e04812d99115359fe29a7", + "color": null, + "idUploadedBackground": null, + "size": "normal", + "brightness": "dark", + "idPlugin": null + }, + "isTemplate": false, + "cardRole": null + }, + { + "id": "674e03cfafb24813f10587f7", + "badges": { + "attachmentsByType": { + "trello": { + "board": 0, + "card": 0 + } + }, + "externalSource": null, + "location": false, + "votes": 0, + "viewingMemberVoted": false, + "subscribed": false, + "attachments": 1, + "fogbugz": "", + "checkItems": 0, + "checkItemsChecked": 0, + "checkItemsEarliestDue": null, + "comments": 0, + "description": true, + "due": "2025-10-08T23:00:00.000Z", + "dueComplete": false, + "lastUpdatedByAi": false, + "start": null + }, + "checkItemStates": [], + "closed": false, + "dueComplete": false, + "dateLastActivity": "2024-12-02T19:01:41.815Z", + "desc": "'Jodi Taylor is quite simply the Queen of Time' C. K. MCDONNELL\n\n**The nail-bitingly tense, rib-crackingly funny new TIME POLICE mission from the million-copy bestselling author of THE CHRONICLES OF ST MARY'S.**\n\nThe Time Police are accustomed to jumping to the past. This time, however, the past has come to them.\n\nWhat connects a dead dinosaur with Romulus the founder of Rome, a shocking cover-up at TPHQ and a plot to murder the Princes in the Tower?\n\nThe Time Police are determined to find out, helped - and occasionally hindered - by a wayward member of St Mary's and a recently reunited Team 236. Each in their own unique way, obviously.\n\nAs if all that wasn't enough - something somewhere in the Timeline is wrong. Very, very wrong. What is the Time Map trying to tell them?\n\nCan the Time Police find the answers before Time runs out?\n\n**BOOK 6 IN THE TIME POLICE SERIES**\n\n**FOR FANS OF TERRY PRATCHETT, RICHARD OSMAN AND DOCTOR WHO**\n\n©2025 Jodi Taylor (P)2025 Headline Publishing Group Limited", + "descData": { + "emoji": {} + }, + "due": "2025-10-08T23:00:00.000Z", + "dueReminder": -1, + "email": null, + "idBoard": "5d9a1af1f3e8b612d60a896b", + "idChecklists": [], + "idList": "6567867b479459ba5dd5ac73", + "idMembers": [], + "idMembersVoted": [], + "idShort": 1302, + "idAttachmentCover": "674e03d2427e684b49e00dc6", + "labels": [ + { + "id": "5d9a1af18bdee58e0dd8ae6b", + "idBoard": "5d9a1af1f3e8b612d60a896b", + "idOrganization": "60ae02462b2b134135ee7152", + "name": "Audiobook", + "nodeId": "ari:cloud:trello::label/workspace/60ae02462b2b134135ee7152/5d9a1af18bdee58e0dd8ae6b", + "color": "orange", + "uses": 312 + } + ], + "idLabels": [ + "5d9a1af18bdee58e0dd8ae6b" + ], + "manualCoverAttachment": false, + "name": "jodi Taylor: Time Police: 6. Out of Time", + "pinned": false, + "pos": 49152, + "shortLink": "T74aHuIi", + "shortUrl": "https://trello.com/c/T74aHuIi", + "start": null, + "subscribed": false, + "url": "https://trello.com/c/T74aHuIi/1302-jodi-taylor-time-police-6-out-of-time", + "cover": { + "idAttachment": "674e03d2427e684b49e00dc6", + "color": null, + "idUploadedBackground": null, + "size": "normal", + "brightness": "dark", + "idPlugin": null + }, + "isTemplate": false, + "cardRole": null + } +] diff --git a/src/trello/model/card.rs b/src/trello/model/card.rs index 0901a07..6ef5384 100644 --- a/src/trello/model/card.rs +++ b/src/trello/model/card.rs @@ -2,13 +2,12 @@ use derive_more::derive::Display; use serde::Deserialize; -use crate::newtype; - use super::{ attachment::{TrelloAttachment, TrelloAttachmentId}, - label::TrelloLabelId, list::TrelloListId, }; +use crate::newtype; +use crate::trello::model::label::TrelloLabel; newtype!(TrelloCardId, String, Display, "Card ID"); newtype!(TrelloCardName, String, Display, "Card Name"); @@ -32,7 +31,7 @@ pub(crate) struct TrelloShortCard { pub(crate) due: Option, // format date #[serde(rename = "idAttachmentCover")] pub(crate) id_attachment_cover: Option, - pub(crate) labels: Vec, + pub(crate) labels: Vec, pub(crate) pos: TrelloCardPosition, } @@ -44,7 +43,7 @@ pub(crate) struct TrelloLongCard { pub(crate) due: Option, // format date #[serde(rename = "idAttachmentCover")] pub(crate) id_attachment_cover: Option, - pub(crate) labels: Vec, + pub(crate) labels: Vec, pub(crate) pos: TrelloCardPosition, pub(crate) attachments: Vec, } diff --git a/src/trello/model/label.rs b/src/trello/model/label.rs index b589223..927ed3a 100644 --- a/src/trello/model/label.rs +++ b/src/trello/model/label.rs @@ -1,6 +1,15 @@ // -use derive_more::derive::Display; - use crate::newtype; +use derive_more::derive::Display; +use serde::Deserialize; newtype!(TrelloLabelId, String, Display, "Label ID"); +newtype!(TrelloLabelName, String, Display, "Label Name"); +newtype!(TrelloLabelColor, String, Display, "Label Colour"); + +#[derive(Debug, PartialEq, Eq, Deserialize)] +pub(crate) struct TrelloLabel { + pub id: TrelloLabelId, + pub name: TrelloLabelName, + pub color: TrelloLabelColor, +} diff --git a/src/trello/tests/stack/get.rs b/src/trello/tests/stack/get.rs index 31bcbba..f35ea90 100644 --- a/src/trello/tests/stack/get.rs +++ b/src/trello/tests/stack/get.rs @@ -31,7 +31,7 @@ fn ctx() -> FullCtx { .respond(StatusCode::OK) .header("content-type", "application/json") .body(include_str!( - "../../../tests/responses/trello-list-get.json" + "../../../tests/responses/trello-stack-get.json" )) .expect("mock request"); @@ -66,7 +66,7 @@ async fn dump(ctx: FullCtx, list_id: TrelloListId) { let output = prt.output(); assert_eq!( output.trim(), - include_str!("../../../tests/responses/trello-list-get.json").trim() + include_str!("../../../tests/responses/trello-stack-get.json").trim() ); } @@ -91,8 +91,10 @@ async fn no_dump(ctx: FullCtx, list_id: TrelloListId) { assert_peq!( output.trim(), [ - "65ad94865aed24f70ecdcebb:Backlog", - "65ad94865aed24f70ecdced1:[Example task]" + "674e03794ef7340ece3ebb5f:Charles Stross: Laundry Files: 13. A Conventional Boy", + "674e095fdcccbd01a02bfacc:Adrian Tchaikovsky: Shroud", + "674e047dfe4e6f56f367780b:Ben Aaronovitch: Rivers of London: 10. Stone and Sky", + "674e03cfafb24813f10587f7:jodi Taylor: Time Police: 6. Out of Time", ] .join("\n") );