Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
190 changes: 190 additions & 0 deletions .surface
Original file line number Diff line number Diff line change
Expand Up @@ -334,11 +334,15 @@ ARG basecamp project delete 00 <id>
ARG basecamp project show 00 <id>
ARG basecamp project trash 00 <id>
ARG basecamp project update 00 <id>
ARG basecamp project wallpaper mode 00 <fill|tile>
ARG basecamp project wallpaper set 00 <file>
ARG basecamp projects create 00 <name>
ARG basecamp projects delete 00 <id>
ARG basecamp projects show 00 <id>
ARG basecamp projects trash 00 <id>
ARG basecamp projects update 00 <id>
ARG basecamp projects wallpaper mode 00 <fill|tile>
ARG basecamp projects wallpaper set 00 <file>
ARG basecamp recordings 00 [type]
ARG basecamp recordings active 00 <id|url>
ARG basecamp recordings archive 00 <id|url>
Expand Down Expand Up @@ -1028,13 +1032,21 @@ CMD basecamp project list
CMD basecamp project show
CMD basecamp project trash
CMD basecamp project update
CMD basecamp project wallpaper
CMD basecamp project wallpaper mode
CMD basecamp project wallpaper remove
CMD basecamp project wallpaper set
CMD basecamp projects
CMD basecamp projects create
CMD basecamp projects delete
CMD basecamp projects list
CMD basecamp projects show
CMD basecamp projects trash
CMD basecamp projects update
CMD basecamp projects wallpaper
CMD basecamp projects wallpaper mode
CMD basecamp projects wallpaper remove
CMD basecamp projects wallpaper set
CMD basecamp recordings
CMD basecamp recordings active
CMD basecamp recordings archive
Expand Down Expand Up @@ -13236,6 +13248,91 @@ FLAG basecamp project update --stats type=bool
FLAG basecamp project update --styled type=bool
FLAG basecamp project update --todolist type=string
FLAG basecamp project update --verbose type=count
FLAG basecamp project wallpaper --account type=string
FLAG basecamp project wallpaper --agent type=bool
FLAG basecamp project wallpaper --cache-dir type=string
FLAG basecamp project wallpaper --count type=bool
FLAG basecamp project wallpaper --help type=bool
FLAG basecamp project wallpaper --hints type=bool
FLAG basecamp project wallpaper --ids-only type=bool
FLAG basecamp project wallpaper --in type=string
FLAG basecamp project wallpaper --jq type=string
FLAG basecamp project wallpaper --json type=bool
FLAG basecamp project wallpaper --markdown type=bool
FLAG basecamp project wallpaper --md type=bool
FLAG basecamp project wallpaper --no-hints type=bool
FLAG basecamp project wallpaper --no-stats type=bool
FLAG basecamp project wallpaper --profile type=string
FLAG basecamp project wallpaper --project type=string
FLAG basecamp project wallpaper --quiet type=bool
FLAG basecamp project wallpaper --stats type=bool
FLAG basecamp project wallpaper --styled type=bool
FLAG basecamp project wallpaper --todolist type=string
FLAG basecamp project wallpaper --verbose type=count
FLAG basecamp project wallpaper mode --account type=string
FLAG basecamp project wallpaper mode --agent type=bool
FLAG basecamp project wallpaper mode --cache-dir type=string
FLAG basecamp project wallpaper mode --count type=bool
FLAG basecamp project wallpaper mode --help type=bool
FLAG basecamp project wallpaper mode --hints type=bool
FLAG basecamp project wallpaper mode --ids-only type=bool
FLAG basecamp project wallpaper mode --in type=string
FLAG basecamp project wallpaper mode --jq type=string
FLAG basecamp project wallpaper mode --json type=bool
FLAG basecamp project wallpaper mode --markdown type=bool
FLAG basecamp project wallpaper mode --md type=bool
FLAG basecamp project wallpaper mode --no-hints type=bool
FLAG basecamp project wallpaper mode --no-stats type=bool
FLAG basecamp project wallpaper mode --profile type=string
FLAG basecamp project wallpaper mode --project type=string
FLAG basecamp project wallpaper mode --quiet type=bool
FLAG basecamp project wallpaper mode --stats type=bool
FLAG basecamp project wallpaper mode --styled type=bool
FLAG basecamp project wallpaper mode --todolist type=string
FLAG basecamp project wallpaper mode --verbose type=count
FLAG basecamp project wallpaper remove --account type=string
FLAG basecamp project wallpaper remove --agent type=bool
FLAG basecamp project wallpaper remove --cache-dir type=string
FLAG basecamp project wallpaper remove --count type=bool
FLAG basecamp project wallpaper remove --help type=bool
FLAG basecamp project wallpaper remove --hints type=bool
FLAG basecamp project wallpaper remove --ids-only type=bool
FLAG basecamp project wallpaper remove --in type=string
FLAG basecamp project wallpaper remove --jq type=string
FLAG basecamp project wallpaper remove --json type=bool
FLAG basecamp project wallpaper remove --markdown type=bool
FLAG basecamp project wallpaper remove --md type=bool
FLAG basecamp project wallpaper remove --no-hints type=bool
FLAG basecamp project wallpaper remove --no-stats type=bool
FLAG basecamp project wallpaper remove --profile type=string
FLAG basecamp project wallpaper remove --project type=string
FLAG basecamp project wallpaper remove --quiet type=bool
FLAG basecamp project wallpaper remove --stats type=bool
FLAG basecamp project wallpaper remove --styled type=bool
FLAG basecamp project wallpaper remove --todolist type=string
FLAG basecamp project wallpaper remove --verbose type=count
FLAG basecamp project wallpaper set --account type=string
FLAG basecamp project wallpaper set --agent type=bool
FLAG basecamp project wallpaper set --cache-dir type=string
FLAG basecamp project wallpaper set --count type=bool
FLAG basecamp project wallpaper set --help type=bool
FLAG basecamp project wallpaper set --hints type=bool
FLAG basecamp project wallpaper set --ids-only type=bool
FLAG basecamp project wallpaper set --in type=string
FLAG basecamp project wallpaper set --jq type=string
FLAG basecamp project wallpaper set --json type=bool
FLAG basecamp project wallpaper set --markdown type=bool
FLAG basecamp project wallpaper set --md type=bool
FLAG basecamp project wallpaper set --mode type=string
FLAG basecamp project wallpaper set --no-hints type=bool
FLAG basecamp project wallpaper set --no-stats type=bool
FLAG basecamp project wallpaper set --profile type=string
FLAG basecamp project wallpaper set --project type=string
FLAG basecamp project wallpaper set --quiet type=bool
FLAG basecamp project wallpaper set --stats type=bool
FLAG basecamp project wallpaper set --styled type=bool
FLAG basecamp project wallpaper set --todolist type=string
FLAG basecamp project wallpaper set --verbose type=count
FLAG basecamp projects --account type=string
FLAG basecamp projects --agent type=bool
FLAG basecamp projects --cache-dir type=string
Expand Down Expand Up @@ -13393,6 +13490,91 @@ FLAG basecamp projects update --stats type=bool
FLAG basecamp projects update --styled type=bool
FLAG basecamp projects update --todolist type=string
FLAG basecamp projects update --verbose type=count
FLAG basecamp projects wallpaper --account type=string
FLAG basecamp projects wallpaper --agent type=bool
FLAG basecamp projects wallpaper --cache-dir type=string
FLAG basecamp projects wallpaper --count type=bool
FLAG basecamp projects wallpaper --help type=bool
FLAG basecamp projects wallpaper --hints type=bool
FLAG basecamp projects wallpaper --ids-only type=bool
FLAG basecamp projects wallpaper --in type=string
FLAG basecamp projects wallpaper --jq type=string
FLAG basecamp projects wallpaper --json type=bool
FLAG basecamp projects wallpaper --markdown type=bool
FLAG basecamp projects wallpaper --md type=bool
FLAG basecamp projects wallpaper --no-hints type=bool
FLAG basecamp projects wallpaper --no-stats type=bool
FLAG basecamp projects wallpaper --profile type=string
FLAG basecamp projects wallpaper --project type=string
FLAG basecamp projects wallpaper --quiet type=bool
FLAG basecamp projects wallpaper --stats type=bool
FLAG basecamp projects wallpaper --styled type=bool
FLAG basecamp projects wallpaper --todolist type=string
FLAG basecamp projects wallpaper --verbose type=count
FLAG basecamp projects wallpaper mode --account type=string
FLAG basecamp projects wallpaper mode --agent type=bool
FLAG basecamp projects wallpaper mode --cache-dir type=string
FLAG basecamp projects wallpaper mode --count type=bool
FLAG basecamp projects wallpaper mode --help type=bool
FLAG basecamp projects wallpaper mode --hints type=bool
FLAG basecamp projects wallpaper mode --ids-only type=bool
FLAG basecamp projects wallpaper mode --in type=string
FLAG basecamp projects wallpaper mode --jq type=string
FLAG basecamp projects wallpaper mode --json type=bool
FLAG basecamp projects wallpaper mode --markdown type=bool
FLAG basecamp projects wallpaper mode --md type=bool
FLAG basecamp projects wallpaper mode --no-hints type=bool
FLAG basecamp projects wallpaper mode --no-stats type=bool
FLAG basecamp projects wallpaper mode --profile type=string
FLAG basecamp projects wallpaper mode --project type=string
FLAG basecamp projects wallpaper mode --quiet type=bool
FLAG basecamp projects wallpaper mode --stats type=bool
FLAG basecamp projects wallpaper mode --styled type=bool
FLAG basecamp projects wallpaper mode --todolist type=string
FLAG basecamp projects wallpaper mode --verbose type=count
FLAG basecamp projects wallpaper remove --account type=string
FLAG basecamp projects wallpaper remove --agent type=bool
FLAG basecamp projects wallpaper remove --cache-dir type=string
FLAG basecamp projects wallpaper remove --count type=bool
FLAG basecamp projects wallpaper remove --help type=bool
FLAG basecamp projects wallpaper remove --hints type=bool
FLAG basecamp projects wallpaper remove --ids-only type=bool
FLAG basecamp projects wallpaper remove --in type=string
FLAG basecamp projects wallpaper remove --jq type=string
FLAG basecamp projects wallpaper remove --json type=bool
FLAG basecamp projects wallpaper remove --markdown type=bool
FLAG basecamp projects wallpaper remove --md type=bool
FLAG basecamp projects wallpaper remove --no-hints type=bool
FLAG basecamp projects wallpaper remove --no-stats type=bool
FLAG basecamp projects wallpaper remove --profile type=string
FLAG basecamp projects wallpaper remove --project type=string
FLAG basecamp projects wallpaper remove --quiet type=bool
FLAG basecamp projects wallpaper remove --stats type=bool
FLAG basecamp projects wallpaper remove --styled type=bool
FLAG basecamp projects wallpaper remove --todolist type=string
FLAG basecamp projects wallpaper remove --verbose type=count
FLAG basecamp projects wallpaper set --account type=string
FLAG basecamp projects wallpaper set --agent type=bool
FLAG basecamp projects wallpaper set --cache-dir type=string
FLAG basecamp projects wallpaper set --count type=bool
FLAG basecamp projects wallpaper set --help type=bool
FLAG basecamp projects wallpaper set --hints type=bool
FLAG basecamp projects wallpaper set --ids-only type=bool
FLAG basecamp projects wallpaper set --in type=string
FLAG basecamp projects wallpaper set --jq type=string
FLAG basecamp projects wallpaper set --json type=bool
FLAG basecamp projects wallpaper set --markdown type=bool
FLAG basecamp projects wallpaper set --md type=bool
FLAG basecamp projects wallpaper set --mode type=string
FLAG basecamp projects wallpaper set --no-hints type=bool
FLAG basecamp projects wallpaper set --no-stats type=bool
FLAG basecamp projects wallpaper set --profile type=string
FLAG basecamp projects wallpaper set --project type=string
FLAG basecamp projects wallpaper set --quiet type=bool
FLAG basecamp projects wallpaper set --stats type=bool
FLAG basecamp projects wallpaper set --styled type=bool
FLAG basecamp projects wallpaper set --todolist type=string
FLAG basecamp projects wallpaper set --verbose type=count
FLAG basecamp recordings --account type=string
FLAG basecamp recordings --agent type=bool
FLAG basecamp recordings --all type=bool
Expand Down Expand Up @@ -19873,13 +20055,21 @@ SUB basecamp project list
SUB basecamp project show
SUB basecamp project trash
SUB basecamp project update
SUB basecamp project wallpaper
SUB basecamp project wallpaper mode
SUB basecamp project wallpaper remove
SUB basecamp project wallpaper set
SUB basecamp projects
SUB basecamp projects create
SUB basecamp projects delete
SUB basecamp projects list
SUB basecamp projects show
SUB basecamp projects trash
SUB basecamp projects update
SUB basecamp projects wallpaper
SUB basecamp projects wallpaper mode
SUB basecamp projects wallpaper remove
SUB basecamp projects wallpaper set
SUB basecamp recordings
SUB basecamp recordings active
SUB basecamp recordings archive
Expand Down
11 changes: 8 additions & 3 deletions API-COVERAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@ Coverage of Basecamp 3 API endpoints. Source: [bc3-api/sections](https://github.

| Status | Sections | Endpoints |
|--------|----------|-----------|
| ✅ Implemented | 55 | 211 |
| ✅ Implemented | 55 | 213 |
| ⚠️ Blocked | 0 | 0 |
| ⏭️ Out of scope | 4 | 12 |
| **Total tracked** | **59** | **223** |
| **Total tracked** | **59** | **225** |

**211 of 211 tracked in-scope endpoints.** Spotlighting a recording on its
**213 of 213 tracked in-scope endpoints.** Uploading and removing a project's
wallpaper (`PUT`/`DELETE /projects/:id/wallpaper.json`, added by
[bc3#14062](https://github.com/basecamp/bc3/pull/14062) and shipped in
[SDK v0.28.0](https://github.com/basecamp/basecamp-sdk/releases/tag/v0.28.0))
land as `projects wallpaper`. Spotlighting a recording on its
project or template home page (`POST`/`DELETE /recordings/:id/spotlight.json`,
SDK v0.27.0) lands as `spotlight` and `unspotlight`. The two embed endpoints bc3 documents
in `embeds.md` — `POST /embeds.json` and `GET /embeds/:sgid.json` — land as
Expand Down Expand Up @@ -201,6 +205,7 @@ cannot faithfully cover at least one endpoint for a reason outside the CLI. A
|---------|-----------|-------------|--------|-------|----------|-------|
| **Core** |
| projects | 9 | `projects` | ✅ | BC4 | - | list, show, create, update, delete |
| projects (wallpaper) | 2 | `projects wallpaper` | ✅ | BC5 | - | set (`PUT /projects/:id/wallpaper.json`, multipart `wallpaper` with an optional `mode`), remove (`DELETE` on the same route; 204 with or without a wallpaper). `mode` sends `wallpaper_mode` through the existing `PUT /projects/:id.json`, with the current name the SDK requires. PNG, JPEG, GIF, WebP, AVIF, HEIF or HEIC up to 10 MB, checked before the upload using a local MIME hint; the server applies its shared image validations. People and personal assistants follow project-edit permissions; shared agents are refused with 403. Project JSON carries `wallpaper {url, mode}` when one is attached, so `projects show` shows it. Project-scoped via `--in`/`--project` |
| todos | 12 | `todos`, `todo`, `done`, `reopen` | ✅ | BC4 | - | list, show, create, update, complete, uncomplete, position (BC5: `steps` shown on `todos show`, plus `subtasks_count`/`subtasks_completed_count`/`subtasks_url`; edit via `subtasks`). `todos create --loose` creates on the to-do set, outside any list |
| subtasks | 8 | `subtasks` | ✅ | BC5 | - | list (`GET /recordings/:id/subtasks.json`, paginated), show, create (`POST` on the same list route), update (partial; `--no-due`/`--no-assignees` clear), complete/uncomplete (`POST`/`DELETE /subtasks/:id/completion.json`), move (`PUT /subtasks/:id/position.json`, 1-based), delete. Account-scoped flat routes (bc3#12659), so no `--in`. Parents are to-dos and cards only. Same `Kanban::Step` records as `card_table_steps` |
| todolists | 9 | `todolists` | ✅ | BC4 | - | list, show, create, update, position |
Expand Down
93 changes: 93 additions & 0 deletions e2e/projects.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#!/usr/bin/env bats
# projects.bats - Test projects command input handling

load test_helper


# Help

@test "projects wallpaper without subcommand shows help" {
run basecamp projects wallpaper
assert_success
assert_output_contains "COMMANDS"
assert_output_contains "set"
assert_output_contains "mode"
assert_output_contains "remove"
}

@test "projects wallpaper set help names the formats and the size cap" {
run basecamp projects wallpaper set --help
assert_success
assert_output_contains "PNG, JPEG, GIF, WebP, AVIF, HEIF, or HEIC files up to 10 MB"
}


# Input errors that need no network

@test "projects wallpaper set without a file shows error" {
create_credentials
create_global_config '{"account_id": 99999, "project_id": 123}'

run basecamp projects wallpaper set
assert_failure
assert_json_value '.error' '<file> required'
assert_json_value '.code' 'usage'
}

@test "projects wallpaper set refuses an SVG" {
create_credentials
create_global_config '{"account_id": 99999, "project_id": 123}'
printf '<svg></svg>' > image.svg

run basecamp projects wallpaper set image.svg
assert_failure
assert_json_value '.error' 'image.svg: unsupported image type image/svg+xml (use PNG, JPEG, GIF, WebP, AVIF, HEIF, or HEIC)'
assert_json_value '.code' 'usage'
}

@test "projects wallpaper set refuses a file over 10 MB" {
create_credentials
create_global_config '{"account_id": 99999, "project_id": 123}'
dd if=/dev/zero of=big.png bs=1 count=1 seek=10485760 2>/dev/null

run basecamp projects wallpaper set big.png
assert_failure
assert_json_value '.error' 'big.png exceeds maximum wallpaper size of 10 MB'
}

@test "projects wallpaper set refuses an unknown --mode" {
create_credentials
create_global_config '{"account_id": 99999, "project_id": 123}'
printf '\x89PNG\r\n\x1a\n' > skyline.png

run basecamp projects wallpaper set skyline.png --mode stretch
assert_failure
assert_json_value '.error' 'unknown wallpaper mode "stretch"'
assert_json_value '.hint' 'Use fill or tile'
}

@test "projects wallpaper mode without a mode shows error" {
create_credentials
create_global_config '{"account_id": 99999, "project_id": 123}'

run basecamp projects wallpaper mode
assert_failure
assert_json_value '.error' '<fill|tile> required'
}

@test "projects wallpaper mode refuses an unknown mode" {
create_credentials
create_global_config '{"account_id": 99999, "project_id": 123}'

run basecamp projects wallpaper mode stretch
assert_failure
assert_json_value '.error' 'unknown wallpaper mode "stretch"'
}

@test "projects wallpaper remove takes no arguments" {
create_credentials
create_global_config '{"account_id": 99999, "project_id": 123}'

run basecamp projects wallpaper remove skyline.png
assert_failure
}
Loading
Loading