Skip to content
Open
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
724 changes: 724 additions & 0 deletions .surface

Large diffs are not rendered by default.

33 changes: 33 additions & 0 deletions e2e/smoke/smoke_account.bats
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,19 @@ setup_file() {
assert_json_value '.ok' 'true'
}

@test "templates projects list returns templates" {
run_smoke basecamp templates projects list --json
assert_success
assert_json_value '.ok' 'true'
}

@test "templates todolists list returns to-do list templates" {
run_smoke basecamp templates todolists list --json
[[ "$status" -ne 0 ]] && mark_unverifiable "Template library not available in this account"
assert_success
assert_json_value '.ok' 'true'
}

@test "people show returns person detail" {
run_smoke basecamp people show me --json
assert_success
Expand Down Expand Up @@ -102,3 +115,23 @@ setup_file() {
@test "account is out of scope" {
mark_out_of_scope "Alias for accounts — tested via canonical form"
}

@test "templates projects show returns template detail" {
local out
out=$(basecamp templates projects list --json 2>/dev/null) || mark_unverifiable "Cannot list templates"
local tmpl_id
tmpl_id=$(echo "$out" | jq -r '.data[0].id // empty')
[[ -n "$tmpl_id" ]] || mark_unverifiable "No templates found"

run_smoke basecamp templates projects show "$tmpl_id" --json
assert_success
assert_json_value '.ok' 'true'
assert_json_not_null '.data.id'
}

@test "templates card-tables list returns card table templates" {
run_smoke basecamp templates card-tables list --json
[[ "$status" -ne 0 ]] && mark_unverifiable "Card table template library not available in this account"
assert_success
assert_json_value '.ok' 'true'
}
76 changes: 76 additions & 0 deletions e2e/smoke/smoke_lifecycle.bats
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,82 @@ load smoke_helper
mark_out_of_scope "Account-wide template mutation"
}

@test "templates projects construct is out of scope" {
mark_out_of_scope "Creates project from template — account-wide mutation"
}

@test "templates projects construction is out of scope" {
mark_out_of_scope "Depends on templates projects construct (OOS)"
}

@test "templates projects create is out of scope" {
mark_out_of_scope "Account-wide template mutation"
}

@test "templates projects update is out of scope" {
mark_out_of_scope "Account-wide template mutation"
}

@test "templates projects delete is out of scope" {
mark_out_of_scope "Account-wide template mutation"
}

@test "templates todolists duplicate is out of scope" {
mark_out_of_scope "Duplicates a to-do list into a project and may grant project access"
}

@test "templates todolists duplication is out of scope" {
mark_out_of_scope "Depends on templates todolists duplicate (OOS)"
}

@test "templates todolists copy is out of scope" {
mark_out_of_scope "Alias of templates todolists duplicate (OOS)"
}

@test "templates todolists copy-status is out of scope" {
mark_out_of_scope "Alias of templates todolists duplication (OOS)"
}

@test "templates card-tables create is out of scope" {
mark_out_of_scope "Account-wide template mutation"
}

@test "templates card-tables duplicate is out of scope" {
mark_out_of_scope "Duplicates a board into a project and may grant project access"
}

@test "templates card-tables duplication is out of scope" {
mark_out_of_scope "Depends on templates card-tables duplicate (OOS)"
}

@test "templates card-tables copy is out of scope" {
mark_out_of_scope "Alias of templates card-tables duplicate (OOS)"
}

@test "templates card-tables copy-status is out of scope" {
mark_out_of_scope "Alias of templates card-tables duplication (OOS)"
}

@test "templates todolists create is out of scope" {
mark_out_of_scope "Account-wide template mutation"
}

@test "todolists templatify is out of scope" {
mark_out_of_scope "Writes a new template into the account library"
}

@test "todolists templatification is out of scope" {
mark_out_of_scope "Depends on todolists templatify (OOS)"
}

@test "card-tables templatify is out of scope" {
mark_out_of_scope "Writes a new template into the account library"
}

@test "card-tables templatification is out of scope" {
mark_out_of_scope "Depends on card-tables templatify (OOS)"
}

@test "messagetypes create is out of scope" {
mark_out_of_scope "Account-wide message type mutation"
}
Expand Down
172 changes: 172 additions & 0 deletions e2e/templates.bats
Original file line number Diff line number Diff line change
Expand Up @@ -213,3 +213,175 @@ load test_helper
run basecamp templates foobar
# Command may show help or require project - just verify it runs
}


# Kind subgroups

@test "templates --help lists the kind subgroups" {
run basecamp templates --help
assert_success
assert_output_contains "projects"
assert_output_contains "todolists"
}

@test "templates projects without subcommand shows help" {
run basecamp templates projects
assert_success
assert_output_contains "construct"
assert_output_contains "construction"
}

@test "templates todolists without subcommand shows help" {
run basecamp templates todolists
assert_success
assert_output_contains "duplicate"
assert_output_contains "duplication"
}

@test "templates projects construct without project name shows error" {
create_credentials
create_global_config '{"account_id": 99999}'

run basecamp templates projects construct 123
assert_failure
assert_output_contains "name required"
}

@test "templates projects list --status with invalid value shows error" {
create_credentials
create_global_config '{"account_id": 99999}'

run basecamp templates projects list --status bogus
assert_failure
assert_output_contains "unknown --status value"
}

@test "templates todolists duplicate without template id shows error" {
create_credentials
create_global_config '{"account_id": 99999}'

run basecamp templates todolists duplicate
assert_failure
assert_output_contains "ID required"
}

@test "templates todolists duplicate accepts --in and --confirm-adding-people" {
run basecamp templates todolists duplicate --help
assert_success
assert_output_contains "--in"
assert_output_contains "--confirm-adding-people"
}

@test "templates todolists duplication without id shows error" {
create_credentials
create_global_config '{"account_id": 99999}'

run basecamp templates todolists duplication
assert_failure
assert_output_contains "ID required"
}

@test "templates todolists copy is an alias for duplicate" {
create_credentials
create_global_config '{"account_id": 99999}'

run basecamp templates todolists copy
assert_failure
assert_output_contains "ID required"
}

@test "templates todolists copy-status is an alias for duplication" {
create_credentials
create_global_config '{"account_id": 99999}'

run basecamp templates todolists copy-status
assert_failure
assert_output_contains "ID required"
}

@test "templates card-tables without subcommand shows help" {
run basecamp templates card-tables
assert_success
assert_output_contains "duplicate"
assert_output_contains "duplication"
}

@test "templates card-tables create without name shows error" {
create_credentials
create_global_config '{"account_id": 99999}'

run basecamp templates card-tables create
assert_failure
assert_json_value '.error' '<name> required'
}

@test "templates card-tables duplicate without template id shows error" {
create_credentials
create_global_config '{"account_id": 99999}'

run basecamp templates card-tables duplicate
assert_failure
assert_output_contains "ID required"
}

@test "templates card-tables duplicate has no --todoset flag" {
run basecamp templates card-tables duplicate --help
assert_success
assert_output_contains "--in"
assert_output_not_contains "--todoset"
}

@test "templates card-tables duplication without id shows error" {
create_credentials
create_global_config '{"account_id": 99999}'

run basecamp templates card-tables duplication
assert_failure
assert_output_contains "ID required"
}

@test "todolists templatify without id shows error" {
create_credentials
create_global_config '{"account_id": 99999}'

run basecamp todolists templatify
assert_failure
assert_output_contains "ID required"
}

@test "todolists templatify has no --move-cards-to-triage flag" {
run basecamp todolists templatify --help
assert_success
assert_output_contains "--copy-comments"
assert_output_not_contains "--move-cards-to-triage"
}

@test "card-tables without subcommand shows help" {
run basecamp card-tables
assert_success
assert_output_contains "templatify"
assert_output_contains "templatification"
}

@test "card-tables templatify offers --move-cards-to-triage" {
run basecamp card-tables templatify --help
assert_success
assert_output_contains "--move-cards-to-triage"
}

@test "card-tables templatification requires two ids" {
create_credentials
create_global_config '{"account_id": 99999}'

run basecamp card-tables templatification 123
assert_failure
}

@test "templates todolists create without name shows error" {
create_credentials
create_global_config '{"account_id": 99999}'

run basecamp templates todolists create
assert_failure
assert_json_value '.error' '<name> required'
}
1 change: 1 addition & 0 deletions internal/cli/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ func Execute() {
cmd.AddCommand(commands.NewUnassignCmd())
cmd.AddCommand(commands.NewMessagesCmd())
cmd.AddCommand(commands.NewCardsCmd())
cmd.AddCommand(commands.NewCardTablesCmd())
cmd.AddCommand(commands.NewURLCmd())
cmd.AddCommand(commands.NewSearchCmd())
cmd.AddCommand(commands.NewRecordingsCmd())
Expand Down
30 changes: 30 additions & 0 deletions internal/commands/cardtables.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package commands

import (
"github.com/spf13/cobra"
)

// NewCardTablesCmd creates the card-tables command for managing card tables themselves.
func NewCardTablesCmd() *cobra.Command {
var project string

cmd := &cobra.Command{
Use: "card-tables",
Short: "Manage card tables",
Long: `Manage card tables in a project.

A card table is the board that contains columns and cards. Use this group for
actions on the table itself, such as saving it as a reusable template. Use
'basecamp cards' to manage cards, columns, steps, and wormholes inside a table.`,
}

cmd.PersistentFlags().StringVarP(&project, "project", "p", "", "Project ID or name")
cmd.PersistentFlags().StringVar(&project, "in", "", "Project ID (alias for --project)")

cmd.AddCommand(
newTemplatifyCmd(cardTableTemplatificationKind(), &project),
newTemplatificationCmd(cardTableTemplatificationKind(), &project),
)

return cmd
}
5 changes: 3 additions & 2 deletions internal/commands/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,14 @@ func CommandCategories() []CommandCategory {
Commands: []CommandInfo{
{Name: "projects", Category: "core", Description: "Manage projects", Actions: []string{"list", "show", "create", "update", "delete"}},
{Name: "todos", Category: "core", Description: "Manage to-dos", Actions: []string{"list", "show", "create", "update", "complete", "uncomplete", "position", "trash", "archive", "restore"}},
{Name: "todolists", Category: "core", Description: "Manage to-do lists", Actions: []string{"list", "show", "create", "update", "position", "trash", "archive", "restore"}},
{Name: "todolists", Category: "core", Description: "Manage to-do lists", Actions: []string{"list", "show", "create", "update", "position", "templatify", "templatification", "trash", "archive", "restore"}},
{Name: "todosets", Category: "core", Description: "Manage to-do set containers", Actions: []string{"list", "show"}},
{Name: "hillcharts", Category: "core", Description: "Manage hill charts", Actions: []string{"show", "track", "untrack"}},
{Name: "gauges", Category: "core", Description: "Manage gauges", Actions: []string{"list", "needles", "needle", "create", "update", "delete", "enable", "disable"}},
{Name: "todolistgroups", Category: "core", Description: "Manage to-do list groups", Actions: []string{"list", "show", "create", "update", "position"}},
{Name: "messages", Category: "core", Description: "Manage messages", Actions: []string{"list", "show", "create", "update", "publish", "pin", "unpin", "trash", "archive", "restore"}},
{Name: "chat", Category: "core", Description: "Chat in real-time", Actions: []string{"list", "messages", "post", "upload", "line", "update", "delete"}},
{Name: "card-tables", Category: "core", Description: "Manage card tables", Actions: []string{"templatify", "templatification"}},
{Name: "cards", Category: "core", Description: "Manage Kanban cards", Actions: []string{"list", "show", "create", "update", "move", "done", "columns", "wormholes", "steps", "trash", "archive", "restore"}},
{Name: "files", Category: "core", Description: "Manage files, documents, and folders", Actions: []string{"list", "show", "versions", "replace", "download", "update", "trash", "archive", "restore"}},
{Name: "checkins", Category: "core", Description: "View automatic check-ins", Actions: []string{"questions", "question", "answers", "answer", "reminders"}},
Expand Down Expand Up @@ -89,7 +90,7 @@ func CommandCategories() []CommandCategory {
Name: "Organization",
Commands: []CommandInfo{
{Name: "people", Category: "organization", Description: "Manage people and access", Actions: []string{"list", "show", "update", "out-of-office", "pingable", "add", "remove", "clients"}},
{Name: "templates", Category: "organization", Description: "Manage project and to-do list templates", Actions: []string{"list", "show", "create", "update", "delete", "construct", "construction", "library", "copy", "copy-status"}},
{Name: "templates", Category: "organization", Description: "Manage project, to-do list, and card table templates", Actions: []string{"projects", "todolists", "card-tables"}},
{Name: "webhooks", Category: "organization", Description: "Manage webhooks", Actions: []string{"list", "show", "create", "update", "delete"}},
{Name: "lineup", Category: "organization", Description: "Manage lineup markers", Actions: []string{"list", "create", "update", "delete"}},
},
Expand Down
1 change: 1 addition & 0 deletions internal/commands/commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ func buildRootWithAllCommands() *cobra.Command {
root.AddCommand(commands.NewUnassignCmd())
root.AddCommand(commands.NewMessagesCmd())
root.AddCommand(commands.NewCardsCmd())
root.AddCommand(commands.NewCardTablesCmd())
root.AddCommand(commands.NewURLCmd())
root.AddCommand(commands.NewSearchCmd())
root.AddCommand(commands.NewRecordingsCmd())
Expand Down
Loading
Loading