tests: add tests for importing
Some checks failed
Test / build (map[name:nightly]) (push) Failing after 7s
Test / build (map[name:stable]) (push) Failing after 7s

This commit is contained in:
Paul Campbell 2024-12-23 09:44:02 +00:00
parent 64467cf107
commit 7926a63d8d
28 changed files with 908 additions and 77 deletions

View file

@ -24,6 +24,9 @@ mod stack;
mod stacks;
mod supervisor;
#[cfg(test)]
mod tests;
pub(crate) async fn run(ctx: &FullCtx) -> color_eyre::Result<()> {
// get list of trello boards
let trello_client = ctx.trello_client();

413
src/import/tests/mod.rs Normal file
View file

@ -0,0 +1,413 @@
//
use http::StatusCode;
use kameo::actor::spawn_in_thread;
use kxio::{fs::TempFileSystem, net::MockNet};
use rstest::fixture;
use serde_json::json;
use tokio::time::Instant;
use crate::{
config::AppConfig,
import::{
labels::LabelsActor, rate_limit::RateLimitActor, stacks::ImportStacksActor,
supervisor::Supervisor,
},
nextcloud::{
model::{NextcloudBoardId, NextcloudStackId},
NextcloudConfig,
},
rate_limit::RateLimit,
s, spawn_in_thread,
trello::{
model::{
card::TrelloShortCard,
list::{TrelloList, TrelloListPosition},
},
TrelloConfig,
},
FullCtx,
};
#[fixture]
fn ctx_fs() -> (FullCtx, TempFileSystem) {
let fs = kxio::fs::temp().expect("temp fs");
let mock_net = kxio::net::mock();
(
FullCtx {
fs: fs.as_real(),
temp_fs: fs.clone(),
net: mock_net.into(),
prt: kxio::print::standard(),
cfg: AppConfig {
trello: TrelloConfig {
api_key: crate::s!("trello-api-key").into(),
api_secret: crate::s!("trello-api-secret").into(),
},
nextcloud: NextcloudConfig {
hostname: crate::s!("https://nextcloud-hostname").into(),
username: crate::s!("nextcloud-username").into(),
password: crate::s!("nextcloud-password").into(),
},
},
},
fs,
)
}
#[fixture]
fn trello_card_without_description_or_label() -> TrelloShortCard {
TrelloShortCard {
id: s!("trello-id").into(),
name: s!("trello-name").into(),
desc: s!("").into(),
labels: vec![],
pos: 333.into(),
}
}
#[fixture]
fn board_id() -> NextcloudBoardId {
444.into()
}
#[fixture]
fn stack_id() -> NextcloudStackId {
555.into()
}
#[fixture]
fn limiter() -> RateLimit {
RateLimit::new("test", 100, 0.0, Instant::now())
}
#[fixture]
fn trello_stack() -> TrelloList {
TrelloList {
id: s!("trello-list-id").into(),
name: s!("new-list-name").into(),
pos: TrelloListPosition(3),
}
}
#[rstest::rstest]
#[test_log::test(tokio::test(flavor = "multi_thread", worker_threads = 1))]
async fn test_create_card_with_description_label_and_attachment(
ctx_fs: (FullCtx, TempFileSystem),
trello_stack: TrelloList,
board_id: NextcloudBoardId,
limiter: RateLimit,
) {
let (mut ctx, _temp_fs) = ctx_fs;
//given
{
let mock_net = MockNet::try_from(ctx.net.clone()).await.expect("mock net");
// LabelsActor
given_nextcloud_get_labels_for_board(&mock_net);
given_nextcloud_create_label(&mock_net);
// ImportStacksActor
given_nextcloud_get_stacks_for_board(&mock_net);
given_nextcloud_create_stack(&mock_net);
given_nextcloud_get_stacks_for_board_with_new_stack(&mock_net);
given_trello_get_stack(&mock_net);
// ImportCardActor
given_nextcloud_create_card_with_description(&mock_net);
given_trello_get_card_for_attachments_list(&mock_net);
// ImportLabelActor
given_nextcloud_add_label_to_card(&mock_net);
// ImportAttachmentActor
given_trello_get_details_of_attachment(&mock_net);
given_trello_save_attachment(&mock_net);
given_nextcloud_upload_attachment(&mock_net);
ctx.net = mock_net.into();
}
let supervisor = spawn_in_thread(Supervisor);
// given_nextcloud_get_labels_for_board
let labels_actor_ref = spawn_in_thread!(supervisor, LabelsActor::new(ctx.clone(), board_id));
let limiter = spawn_in_thread!(supervisor, RateLimitActor::new(limiter));
let trello_stack_name = trello_stack.name.clone();
let trello_stacks: Vec<TrelloList> = vec![trello_stack];
//when
// given_nextcloud_create_card_with_description
// given_trello_get_card_for_attachments_list
// spawns: label actor
// given_nextcloud_create_label
// given_nextcloud_add_label_to_card
// spawns: attachment actor
// given_trello_get_details_of_attachment
// given_trello_save_attachment
// given_nextcloud_upload_attachment
let _stacks = spawn_in_thread!(
supervisor,
ImportStacksActor::new(
ctx.clone(),
trello_stacks,
vec![trello_stack_name.into()],
board_id,
labels_actor_ref,
limiter,
)
);
//then
tokio::select! {
_ = tokio::time::sleep(std::time::Duration::from_secs(1)) => {panic!("timeout")},
_ = supervisor.wait_for_stop() => {}
}
ctx.net.assert_no_unused_plans();
}
#[rstest::rstest]
#[test_log::test(tokio::test(flavor = "multi_thread", worker_threads = 1))]
async fn test_create_card_without_description_label_or_attachment(
ctx_fs: (FullCtx, TempFileSystem),
trello_stack: TrelloList,
board_id: NextcloudBoardId,
limiter: RateLimit,
) {
let (mut ctx, _temp_fs) = ctx_fs;
//given
{
let mock_net = MockNet::try_from(ctx.net.clone()).await.expect("mock net");
// LabelsActor
given_nextcloud_get_labels_for_board(&mock_net);
// ImportStacksActor
given_nextcloud_get_stacks_for_board(&mock_net);
given_nextcloud_create_stack(&mock_net);
given_nextcloud_get_stacks_for_board_with_new_stack(&mock_net);
given_trello_get_stack_with_card_with_no_description_or_label(&mock_net);
// ImportCardActor
given_nextcloud_create_card_without_description(&mock_net);
given_trello_get_card_for_empty_attachments_list(&mock_net);
ctx.net = mock_net.into();
}
let supervisor = spawn_in_thread(Supervisor);
// requires: get_board (i.e. given_get_labels_for_board_from_nextcloud)
// // nextcloud get labels for board: GET boards/{board_id}
let labels_actor_ref = spawn_in_thread!(supervisor, LabelsActor::new(ctx.clone(), board_id));
let limiter = spawn_in_thread!(supervisor, RateLimitActor::new(limiter));
let trello_stack_name = trello_stack.name.clone();
let trello_stacks: Vec<TrelloList> = vec![trello_stack];
//when
let _stacks = spawn_in_thread!(
supervisor,
ImportStacksActor::new(
ctx.clone(),
trello_stacks,
vec![trello_stack_name.into()],
board_id,
labels_actor_ref,
limiter,
)
);
//then
tokio::select! {
_ = tokio::time::sleep(std::time::Duration::from_secs(1)) => {panic!("timeout")},
_ = supervisor.wait_for_stop() => {}
}
ctx.net.assert_no_unused_plans();
}
fn given_nextcloud_upload_attachment(mock_net: &MockNet) {
// upload attachment to Nextcloud
mock_net
.on()
.post("https://nextcloud-hostname/index.php/apps/deck/api/v1.0/boards/444/stacks/555/cards/331/attachments")
.respond(StatusCode::OK)
.body(include_bytes!("../../tests/responses/nextcloud-attachment-add.json").as_slice())
.expect("mock request create attachment");
}
fn given_nextcloud_add_label_to_card(mock_net: &MockNet) {
mock_net
.on()
.put("https://nextcloud-hostname/index.php/apps/deck/api/v1.0/boards/444/stacks/555/cards/331/assignLabel")
.body(json!({
"labelId": 54
}).to_string())
.respond(StatusCode::OK)
.mock()
.expect("mock request create attachment");
}
fn given_trello_get_card_for_attachments_list(mock_net: &MockNet) {
mock_net
.on()
.get("https://api.trello.com/1/cards/65ad94865aed24f70ecdcebb")
.query("attachments", "true")
.header("content-type", "application/json")
.header("accept", "application/json")
.respond(StatusCode::OK)
.body(include_bytes!("../../tests/responses/trello-card-get.json").as_slice())
.expect("mock request create attachment");
}
fn given_trello_get_card_for_empty_attachments_list(mock_net: &MockNet) {
mock_net
.on()
.get("https://api.trello.com/1/cards/65ad94865aed24f70ecdcebb")
.query("attachments", "true")
.header("content-type", "application/json")
.header("accept", "application/json")
.respond(StatusCode::OK)
.body(
include_bytes!("../../tests/responses/trello-card-get-no-description.json").as_slice(),
)
.expect("mock request create attachment");
}
fn given_trello_save_attachment(mock_net: &MockNet) {
// save attachment from Trello
mock_net.on()
.get("https://trello.com/1/cards/65ad94865aed24f70ecdcebb/attachments/65ad94875aed24f70ecdd037/download/Backlog.png")
.respond(StatusCode::OK)
.body(include_bytes!("../../tests/responses/trello-attachment-save.png").as_slice())
.expect("mock save attachment");
}
fn given_trello_get_details_of_attachment(mock_net: &MockNet) {
// get details of attachment from Trello
mock_net
.on()
.get("https://api.trello.com/1/cards/65ad94865aed24f70ecdcebb/attachments/65ad94875aed24f70ecdd037")
.respond(StatusCode::OK)
.body(include_bytes!("../../tests/responses/trello-attachment-get.json").as_slice())
.expect("mock request attachment");
}
fn given_nextcloud_get_labels_for_board(mock_net: &MockNet) {
// get labels for the board from nextcloud
mock_net
.on()
.get("https://nextcloud-hostname/index.php/apps/deck/api/v1.0/boards/444")
.respond(StatusCode::OK)
.body(include_bytes!("../../tests/responses/nextcloud-board-labels.json").as_slice())
.expect("mock request board");
}
fn given_nextcloud_create_card_with_description(mock_net: &MockNet) {
// create card in Nextcloud
mock_net
.on()
.post("https://nextcloud-hostname/index.php/apps/deck/api/v1.0/boards/444/stacks/555/cards")
.body(
json!({
"description": "A list of the things we think we want to do, maybe not quite ready for work, but high likelihood of being worked on.\n\nThis is the staging area where specs should get fleshed out.\n\nNo limit on the list size, but we should reconsider if it gets long.",
"title": "Backlog",
}) // TODO: include card 'order' from trello 'pos'
.to_string(),
)
.respond(StatusCode::OK)
.body(include_bytes!("../../tests/responses/nextcloud-card-create.json").as_slice())
.expect("mock request create card");
}
fn given_nextcloud_create_card_without_description(mock_net: &MockNet) {
// create card in Nextcloud
mock_net
.on()
.post("https://nextcloud-hostname/index.php/apps/deck/api/v1.0/boards/444/stacks/555/cards")
.body(
json!({
// "description": "trello-desc",
"title": "Backlog",
}) // TODO: include card 'order' from trello 'pos'
.to_string(),
)
.respond(StatusCode::OK)
.body(include_bytes!("../../tests/responses/nextcloud-card-create.json").as_slice())
.expect("mock request create card");
}
fn given_nextcloud_create_label(mock_net: &MockNet) {
// create card in Nextcloud
mock_net
.on()
.post("https://nextcloud-hostname/index.php/apps/deck/api/v1.0/boards/444/labels")
.body(
json!({
"title": "Green",
"color": "00ff00", // from green
})
.to_string(),
)
.respond(StatusCode::OK)
.body(include_bytes!("../../tests/responses/nextcloud-board-create-label.json").as_slice())
.expect("mock request create label");
}
fn given_nextcloud_get_stacks_for_board(mock_net: &MockNet) {
mock_net
.on()
.get("https://nextcloud-hostname/index.php/apps/deck/api/v1.0/boards/444/stacks")
.respond(StatusCode::OK)
.body(include_bytes!("../../tests/responses/nextcloud-board-get.json").as_slice())
.expect("mock request get stacks");
}
fn given_nextcloud_get_stacks_for_board_with_new_stack(mock_net: &MockNet) {
mock_net
.on()
.get("https://nextcloud-hostname/index.php/apps/deck/api/v1.0/boards/444/stacks")
.respond(StatusCode::OK)
.body(
include_bytes!("../../tests/responses/nextcloud-board-get-with-new-stack.json")
.as_slice(),
)
.expect("mock request get stacks");
}
fn given_nextcloud_create_stack(mock_net: &MockNet) {
//
mock_net
.on()
.post("https://nextcloud-hostname/index.php/apps/deck/api/v1.0/boards/444/stacks")
.respond(StatusCode::OK)
.body(include_bytes!("../../tests/responses/nextcloud-stack-create.json").as_slice())
.expect("mock request create stack");
}
fn given_trello_get_stack(mock_net: &MockNet) {
mock_net
.on()
.get("https://api.trello.com/1/lists/trello-list-id/cards")
.respond(StatusCode::OK)
.body(include_bytes!("../../tests/responses/trello-list-get.json").as_slice())
.expect("mock get stack");
}
fn given_trello_get_stack_with_card_with_no_description_or_label(mock_net: &MockNet) {
mock_net
.on()
.get("https://api.trello.com/1/lists/trello-list-id/cards")
.respond(StatusCode::OK)
.body(
include_bytes!("../../tests/responses/trello-list-get-no-desc-or-label.json")
.as_slice(),
)
.expect("mock get stack");
}

View file

@ -45,10 +45,7 @@ fn ctx_path() -> (FullCtx, PathBuf, TempFileSystem) {
"{hostname}/index.php/apps/deck/api/v1.0/boards/{board_id}/stacks/{stack_id}/cards/{card_id}/attachments",
))
.respond(StatusCode::OK)
.body(serde_json::to_string(&Attachment {
id: 102,
attachment_type: "file".to_string(),
}).expect("json attachment"))
.body(include_bytes!("../../../tests/responses/nextcloud-attachment-add.json").as_slice())
.expect("mock request");
(

View file

@ -1 +1,5 @@
{"id":102,"type":"file"}
{
"foo": "nextcloud-attachment-add.json",
"id": 102,
"type": "file"
}

View file

@ -1,4 +1,5 @@
{
"foo": "nextcloud-board-create-label.json",
"id": 54,
"title": "my green label",
"color": "31CC7C",

View file

@ -0,0 +1,301 @@
[
{
"foo": "nextcloud-board-get-with-new-stack.json",
"id": 555,
"title": "new-list-name",
"boardId": 1,
"deletedAt": 0,
"lastModified": 1733515991,
"cards": [],
"order": 4,
"ETag": "fda386b3b247d7b4bd8917e19d38c01b"
},
{
"id": 3,
"title": "Done",
"boardId": 1,
"deletedAt": 0,
"lastModified": 1733515991,
"cards": [
{
"id": 322,
"title": "Lunch: Soup & Toast",
"description": "",
"stackId": 3,
"type": "plain",
"lastModified": 1733515991,
"lastEditor": null,
"createdAt": 1733043472,
"labels": [
{
"id": 4,
"title": "Later",
"color": "F1DB50",
"boardId": 1,
"cardId": 322,
"lastModified": 1670965629,
"ETag": "983f87848dc9c18d0aee63e7ee0fc83f"
}
],
"assignedUsers": [
{
"id": 25,
"participant": {
"primaryKey": "pcampbell",
"uid": "pcampbell",
"displayname": "Paul Campbell",
"type": 0
},
"cardId": 322,
"type": 0
}
],
"attachments": null,
"attachmentCount": 0,
"owner": {
"primaryKey": "pcampbell",
"uid": "pcampbell",
"displayname": "Paul Campbell",
"type": 0
},
"order": 0,
"archived": false,
"done": null,
"duedate": null,
"deletedAt": 0,
"commentsUnread": 0,
"commentsCount": 0,
"ETag": "dda386b3b247d7b4bd8917e19d38c01b",
"overdue": 0
}
],
"order": 2,
"ETag": "dda386b3b247d7b4bd8917e19d38c01b"
},
{
"id": 2,
"title": "Doing",
"boardId": 1,
"deletedAt": 0,
"lastModified": 1733695323,
"cards": [
{
"id": 319,
"title": "That",
"description": "",
"stackId": 2,
"type": "plain",
"lastModified": 1733335979,
"lastEditor": null,
"createdAt": 1732610551,
"labels": [],
"assignedUsers": [],
"attachments": null,
"attachmentCount": 1,
"owner": {
"primaryKey": "pcampbell",
"uid": "pcampbell",
"displayname": "Paul Campbell",
"type": 0
},
"order": 0,
"archived": false,
"done": null,
"duedate": null,
"deletedAt": 0,
"commentsUnread": 0,
"commentsCount": 0,
"ETag": "79aeb703494e67736cc66b35053d258d",
"overdue": 0
},
{
"id": 323,
"title": "Second lunch: Poached Egg & Toasted Muffin",
"description": "",
"stackId": 2,
"type": "plain",
"lastModified": 1733695323,
"lastEditor": null,
"createdAt": 1733043481,
"labels": [],
"assignedUsers": [
{
"id": 26,
"participant": {
"primaryKey": "pcampbell",
"uid": "pcampbell",
"displayname": "Paul Campbell",
"type": 0
},
"cardId": 323,
"type": 0
}
],
"attachments": null,
"attachmentCount": 0,
"owner": {
"primaryKey": "pcampbell",
"uid": "pcampbell",
"displayname": "Paul Campbell",
"type": 0
},
"order": 1,
"archived": false,
"done": null,
"duedate": null,
"deletedAt": 0,
"commentsUnread": 0,
"commentsCount": 0,
"ETag": "9de45fc7d68507f1eaef462e90e6414c",
"overdue": 0
}
],
"order": 1,
"ETag": "9de45fc7d68507f1eaef462e90e6414c"
},
{
"id": 1,
"title": "To do",
"boardId": 1,
"deletedAt": 0,
"lastModified": 1734115321,
"cards": [
{
"id": 318,
"title": "This",
"description": "",
"stackId": 1,
"type": "plain",
"lastModified": 1733049748,
"lastEditor": null,
"createdAt": 1732610548,
"labels": [],
"assignedUsers": [],
"attachments": null,
"attachmentCount": 1,
"owner": {
"primaryKey": "pcampbell",
"uid": "pcampbell",
"displayname": "Paul Campbell",
"type": 0
},
"order": 0,
"archived": false,
"done": null,
"duedate": null,
"deletedAt": 0,
"commentsUnread": 0,
"commentsCount": 0,
"ETag": "e5007451d88799e3e3d3581cbcb30210",
"overdue": 0
},
{
"id": 321,
"title": "Breakfast: Cereal",
"description": "",
"stackId": 1,
"type": "plain",
"lastModified": 1734115321,
"lastEditor": null,
"createdAt": 1733043461,
"labels": [
{
"id": 1,
"title": "Finished",
"color": "31CC7C",
"boardId": 1,
"cardId": 321,
"lastModified": 1670965629,
"ETag": "983f87848dc9c18d0aee63e7ee0fc83f"
},
{
"id": 1,
"title": "Finished",
"color": "31CC7C",
"boardId": 1,
"cardId": 321,
"lastModified": 1670965629,
"ETag": "983f87848dc9c18d0aee63e7ee0fc83f"
},
{
"id": 1,
"title": "Finished",
"color": "31CC7C",
"boardId": 1,
"cardId": 321,
"lastModified": 1670965629,
"ETag": "983f87848dc9c18d0aee63e7ee0fc83f"
},
{
"id": 2,
"title": "To review",
"color": "317CCC",
"boardId": 1,
"cardId": 321,
"lastModified": 1670965629,
"ETag": "983f87848dc9c18d0aee63e7ee0fc83f"
},
{
"id": 2,
"title": "To review",
"color": "317CCC",
"boardId": 1,
"cardId": 321,
"lastModified": 1670965629,
"ETag": "983f87848dc9c18d0aee63e7ee0fc83f"
},
{
"id": 3,
"title": "Action needed",
"color": "FF7A66",
"boardId": 1,
"cardId": 321,
"lastModified": 1670965629,
"ETag": "983f87848dc9c18d0aee63e7ee0fc83f"
},
{
"id": 4,
"title": "Later",
"color": "F1DB50",
"boardId": 1,
"cardId": 321,
"lastModified": 1670965629,
"ETag": "983f87848dc9c18d0aee63e7ee0fc83f"
}
],
"assignedUsers": [
{
"id": 24,
"participant": {
"primaryKey": "pcampbell",
"uid": "pcampbell",
"displayname": "Paul Campbell",
"type": 0
},
"cardId": 321,
"type": 0
}
],
"attachments": null,
"attachmentCount": 0,
"owner": {
"primaryKey": "pcampbell",
"uid": "pcampbell",
"displayname": "Paul Campbell",
"type": 0
},
"order": 1,
"archived": false,
"done": null,
"duedate": null,
"deletedAt": 0,
"commentsUnread": 0,
"commentsCount": 0,
"ETag": "9acdd42135c0347968891d2a073b87be",
"overdue": 0
}
],
"order": 0,
"ETag": "9acdd42135c0347968891d2a073b87be"
}
]

View file

@ -1,5 +1,6 @@
[
{
"foo": "nextcloud-board-get.json",
"id": 3,
"title": "Done",
"boardId": 1,

View file

@ -1,4 +1,5 @@
{
"foo": "nextcloud-board-labels.json",
"id": 1,
"title": "Personal Board",
"owner": {

View file

@ -1,5 +1,6 @@
[
{
"foo": "nextcloud-board-list.json",
"id": 1,
"title": "Personal Board",
"owner": {

View file

@ -1,5 +1,6 @@
[
{
"foo": "nextcloud-boards.json",
"id": 1,
"title": "Personal Board",
"owner": {

View file

@ -1,4 +1,5 @@
{
"foo": "nextcloud-card-create.json",
"id": 331,
"title": "my new card",
"description": "my new description",

View file

@ -1,4 +1,5 @@
{
"foo": "nextcloud-card-get.json",
"id": 321,
"title": "Breakfast: Cereal",
"description": "",

View file

@ -1,5 +1,6 @@
[
{
"foo": "nextcloud-deck-get.json",
"id": 1,
"title": "Personal Board",
"owner": {

View file

@ -1,4 +1,5 @@
{
"foo": "nextcloud-stack-create.json",
"id": 30,
"title": "Incoming",
"boardId": 1,

View file

@ -1,4 +1,5 @@
{
"foo": "nextcloud-stack-get.json",
"id": 3,
"title": "Done",
"boardId": 1,

View file

@ -1,5 +1,6 @@
[
{
"foo": "nextcloud-stack-list-2.json",
"id": 1,
"title": "To do",
"boardId": 1,

View file

@ -1,5 +1,6 @@
[
{
"foo": "nextcloud-stack-list.json",
"id": 3,
"title": "Done",
"boardId": 1,

View file

@ -1,4 +1,5 @@
{
"foo": "trello-attachment-get.json",
"id": "65ad94875aed24f70ecdd037",
"bytes": 184198,
"date": "2019-01-02T22:47:17.325Z",

View file

@ -1,4 +1,5 @@
{
"foo": "trello-board-get.json",
"id": "65ad94865aed24f70ecdce4b",
"name": "Tasyn Kanban",
"desc": "Use this simple Kanban template to keep the engineering team on the same page and moving through work fluidly. \n\n1. Break down the roadmap by adding tasks as cards to the **Backlog** list. \n\n2. Move the cards one-by-one through **Design** as they becomes more fleshed out. *Pro tip:* You can enable Power-ups for your favorite design tools like [Figma](https://trello.com/power-ups/59b2e7611e6ece0b35eac16a/figma) or [Invision](https://trello.com/power-ups/596f2cb2d279152540b2bb31), in order to easily link and view designs without switching context.\n\n3. When a card is fully specced out and designs are attached, move it to **To Do** for engineers to pick up. \n\n4. Engineers move cards to **Doing** and assign themselves to the cards, so the whole team stays informed of who is working on what.\n\n5. Cards then move through **Code Review** when they're ready for a second set of eyes. The team can set a **List Limit** (with the List Limit Power-up) on the number of cards in Code Review, as a visual indicator for when the team needs to prioritize reviews rather than picking up new work. \n\n6. Once cards move through **Testing** and eventually ship to production, move them to **Done** and celebrate!\n",

View file

@ -1,5 +1,6 @@
[
{
"foo": "trello-boards-list.json",
"id": "5db72d5517a6135e166fd862",
"nodeId": "ari:cloud:trello::board/workspace/60ae020570a89b46695aae66/5db72d5517a6135e166fd862",
"name": "0 Business: Cossmass Infinities",

View file

@ -1,5 +1,6 @@
[
{
"foo": "trello-boards.json",
"id": "5abbe4b7ddc1b351ef961414",
"name": "Trello Platform Changes",
"desc": "Track changes to Trello's Platform on this board.",

View file

@ -0,0 +1,67 @@
{
"foo": "trello-card-get-no-description.json",
"id": "65ad94865aed24f70ecdced1",
"badges": {
"attachmentsByType": {
"trello": {
"board": 0,
"card": 0
}
},
"externalSource": null,
"location": false,
"votes": 0,
"viewingMemberVoted": false,
"subscribed": false,
"fogbugz": "",
"checkItems": 0,
"checkItemsChecked": 0,
"checkItemsEarliestDue": null,
"comments": 0,
"attachments": 0,
"description": false,
"due": null,
"dueComplete": false,
"start": null,
"lastUpdatedByAi": false
},
"checkItemStates": [],
"closed": false,
"dueComplete": false,
"dateLastActivity": "2024-12-25T08:40:22.054Z",
"desc": "",
"descData": null,
"due": null,
"dueReminder": null,
"email": null,
"idBoard": "65ad94865aed24f70ecdce4b",
"idChecklists": [],
"idList": "65ad94865aed24f70ecdce4c",
"idMembers": [],
"idMembersVoted": [],
"idShort": 12,
"idAttachmentCover": null,
"labels": [],
"idLabels": [],
"manualCoverAttachment": false,
"name": "Task - no description, labels or attachments",
"pinned": false,
"pos": 81920,
"shortLink": "kqHXwwev",
"shortUrl": "https://trello.com/c/kqHXwwev",
"start": null,
"subscribed": false,
"url": "https://trello.com/c/kqHXwwev/12-task-no-description-labels-or-attachments",
"cover": {
"idAttachment": null,
"color": null,
"idUploadedBackground": null,
"size": "normal",
"brightness": "light",
"idPlugin": null
},
"isTemplate": false,
"cardRole": null,
"mirrorSourceId": null,
"attachments": []
}

View file

@ -1,4 +1,5 @@
{
"foo": "trello-card-get.json",
"id": "65ad94865aed24f70ecdcebb",
"badges": {
"attachmentsByType": {
@ -12,7 +13,6 @@
"votes": 0,
"viewingMemberVoted": false,
"subscribed": false,
"lastUpdatedByAi": false,
"fogbugz": "",
"checkItems": 0,
"checkItemsChecked": 0,
@ -22,12 +22,13 @@
"description": true,
"due": null,
"dueComplete": false,
"start": null
"start": null,
"lastUpdatedByAi": false
},
"checkItemStates": [],
"closed": false,
"dueComplete": false,
"dateLastActivity": "2024-01-21T22:02:47.582Z",
"dateLastActivity": "2024-12-25T08:40:39.500Z",
"desc": "A list of the things we think we want to do, maybe not quite ready for work, but high likelihood of being worked on.\n\nThis is the staging area where specs should get fleshed out.\n\nNo limit on the list size, but we should reconsider if it gets long.",
"descData": null,
"due": null,
@ -40,17 +41,29 @@
"idMembersVoted": [],
"idShort": 1,
"idAttachmentCover": "65ad94875aed24f70ecdd037",
"labels": [],
"idLabels": [],
"labels": [
{
"id": "65ad94865aed24f70ecdcee2",
"idBoard": "65ad94865aed24f70ecdce4b",
"idOrganization": "60ae034415aa230ab2ef596d",
"name": "Green",
"nodeId": "ari:cloud:trello::label/workspace/60ae034415aa230ab2ef596d/65ad94865aed24f70ecdcee2",
"color": "green",
"uses": 1
}
],
"idLabels": [
"65ad94865aed24f70ecdcee2"
],
"manualCoverAttachment": false,
"name": "Backlog",
"name": "Task - with description, label and attachment",
"pinned": false,
"pos": 16384,
"shortLink": "Z7CTyW2I",
"shortUrl": "https://trello.com/c/Z7CTyW2I",
"start": null,
"subscribed": false,
"url": "https://trello.com/c/Z7CTyW2I/1-backlog",
"url": "https://trello.com/c/Z7CTyW2I/1-task-with-description-label-and-attachment",
"cover": {
"idAttachment": "65ad94875aed24f70ecdd037",
"color": null,

View file

@ -0,0 +1,67 @@
[
{
"foo": "trello-list-get-no-desc-or-label.json",
"id": "65ad94865aed24f70ecdcebb",
"badges": {
"attachmentsByType": {
"trello": {
"board": 0,
"card": 0
}
},
"externalSource": null,
"location": false,
"votes": 0,
"viewingMemberVoted": false,
"subscribed": false,
"fogbugz": "",
"checkItems": 0,
"checkItemsChecked": 0,
"checkItemsEarliestDue": null,
"comments": 0,
"attachments": 1,
"description": true,
"due": null,
"dueComplete": false,
"start": null,
"lastUpdatedByAi": false
},
"checkItemStates": [],
"closed": false,
"dueComplete": false,
"dateLastActivity": "2024-01-21T22:02:47.582Z",
"desc": "",
"descData": null,
"due": null,
"dueReminder": null,
"email": null,
"idBoard": "65ad94865aed24f70ecdce4b",
"idChecklists": [],
"idList": "65ad94865aed24f70ecdce4c",
"idMembers": [],
"idMembersVoted": [],
"idShort": 1,
"idAttachmentCover": "65ad94875aed24f70ecdd037",
"labels": [],
"idLabels": [],
"manualCoverAttachment": false,
"name": "Backlog",
"pinned": false,
"pos": 16384,
"shortLink": "Z7CTyW2I",
"shortUrl": "https://trello.com/c/Z7CTyW2I",
"start": null,
"subscribed": false,
"url": "https://trello.com/c/Z7CTyW2I/1-backlog",
"cover": {
"idAttachment": "65ad94875aed24f70ecdd037",
"color": null,
"idUploadedBackground": null,
"size": "normal",
"brightness": "light",
"idPlugin": null
},
"isTemplate": false,
"cardRole": null
}
]

View file

@ -1,5 +1,6 @@
[
{
"foo": "trello-list-get.json",
"id": "65ad94865aed24f70ecdcebb",
"badges": {
"attachmentsByType": {
@ -41,7 +42,17 @@
"idMembersVoted": [],
"idShort": 1,
"idAttachmentCover": "65ad94875aed24f70ecdd037",
"labels": [],
"labels": [
{
"id": "65ad94865aed24f70ecdcee2",
"idBoard": "65ad94865aed24f70ecdce4b",
"idOrganization": "60ae034415aa230ab2ef596d",
"name": "Green",
"nodeId": "ari:cloud:trello::label/workspace/60ae034415aa230ab2ef596d/65ad94865aed24f70ecdcee2",
"color": "green",
"uses": 1
}
],
"idLabels": [],
"manualCoverAttachment": false,
"name": "Backlog",
@ -62,69 +73,5 @@
},
"isTemplate": false,
"cardRole": null
},
{
"id": "65ad94865aed24f70ecdced1",
"badges": {
"attachmentsByType": {
"trello": {
"board": 0,
"card": 0
}
},
"externalSource": null,
"location": false,
"votes": 0,
"viewingMemberVoted": false,
"subscribed": false,
"fogbugz": "",
"checkItems": 0,
"checkItemsChecked": 0,
"checkItemsEarliestDue": null,
"comments": 0,
"attachments": 0,
"description": false,
"due": null,
"dueComplete": false,
"start": null,
"lastUpdatedByAi": false
},
"checkItemStates": [],
"closed": false,
"dueComplete": false,
"dateLastActivity": "2024-01-21T22:02:47.112Z",
"desc": "",
"descData": null,
"due": null,
"dueReminder": null,
"email": null,
"idBoard": "65ad94865aed24f70ecdce4b",
"idChecklists": [],
"idList": "65ad94865aed24f70ecdce4c",
"idMembers": [],
"idMembersVoted": [],
"idShort": 12,
"idAttachmentCover": null,
"labels": [],
"idLabels": [],
"manualCoverAttachment": false,
"name": "[Example task]",
"pinned": false,
"pos": 81920,
"shortLink": "kqHXwwev",
"shortUrl": "https://trello.com/c/kqHXwwev",
"start": null,
"subscribed": false,
"url": "https://trello.com/c/kqHXwwev/12-example-task",
"cover": {
"idAttachment": null,
"color": null,
"idUploadedBackground": null,
"size": "normal",
"brightness": "light",
"idPlugin": null
},
"isTemplate": false,
"cardRole": null
}
]

View file

@ -1,5 +1,6 @@
[
{
"foo": "trello-member-get.json",
"id": "5db72d5517a6135e166fd862",
"nodeId": "ari:cloud:trello::board/workspace/60ae020570a89b46695aae66/5db72d5517a6135e166fd862",
"name": "0 Business: Cossmass Infinities",

View file

@ -1,5 +1,6 @@
[
{
"foo": "trello-stack-get.json",
"id": "674e03794ef7340ece3ebb5f",
"badges": {
"attachmentsByType": {

View file

@ -1,5 +1,6 @@
[
{
"foo": "trello-stack-list.json",
"id": "65ad94865aed24f70ecdce4c",
"name": "Backlog",
"closed": false,