Skip to content

feat(jtk): add custom field management commands#156

Merged
rianjs merged 1 commit intomainfrom
feat/155-field-management
Feb 12, 2026
Merged

feat(jtk): add custom field management commands#156
rianjs merged 1 commit intomainfrom
feat/155-field-management

Conversation

@rianjs
Copy link
Contributor

@rianjs rianjs commented Feb 12, 2026

Summary

  • Adds jtk fields top-level command group with full CRUD for custom field definitions, contexts, and options
  • 11 new subcommands: fields list/create/delete/restore, fields contexts list/create/delete, fields options list/add/update/delete
  • Auto-detects default context when --context is omitted from options subcommands
  • Includes comprehensive unit tests (API + command layers) and integration test runbook

Test plan

  • make build passes
  • make test passes (all new + existing tests)
  • make lint passes (0 issues)
  • CI passes
  • Run integration tests (sections 13-14 in integration-tests.md)

Closes #155

Add `jtk fields` command group with full CRUD for custom field
definitions, contexts, and options via the Jira Cloud REST API v3.

New commands:
- fields list, create, delete (trash), restore
- fields contexts list, create, delete
- fields options list, add, update, delete

Options subcommands auto-detect the default context when --context
is omitted, simplifying the common single-context workflow.

Closes #155
@rianjs
Copy link
Contributor Author

rianjs commented Feb 12, 2026

Test Coverage Assessment

Summary

This PR adds 11 new subcommands under jtk fields with two test files: api/field_management_test.go (338 lines, 22 tests) and internal/cmd/fields/fields_test.go (576 lines, 24 tests). Coverage is strong relative to the codebase baseline.

Coverage numbers:

  • api/ package: 62.9% overall (shared with all existing API code)
  • internal/cmd/fields/: 82.2% — highest among comparable command packages (projects: 78.9%, comments: 49.4%, automation: 31.3%, transitions: 7.7%)

What is well-covered

API layer (field_management_test.go):

  • Every API method has a happy-path test with HTTP method + URL path assertions
  • Every method that takes a fieldID has an empty-ID guard test (ErrFieldIDRequired)
  • Request body deserialization is verified for CreateField, CreateFieldContext, CreateFieldContextOptions, UpdateFieldContextOptions
  • GetDefaultFieldContext covers both the normal case and the empty-contexts edge case
  • Server error handling is tested for CreateField (400 response)

Command layer (fields_test.go):

  • All run* functions are tested for their happy path
  • Table and JSON output modes are tested for list
  • Empty-result edge cases covered for runList, runContextsList, runOptionsList
  • Confirmation prompt flow is tested for both accepted and declined paths on runDelete, runContextsDelete, runOptionsDelete
  • resolveContextID tested for both explicit and auto-detect paths
  • Register test verifies command tree wiring and aliases
  • Command flag presence verified for list, create, delete

Gaps — notable but minor

  1. runContextsCreate with --project flag: The command accepts a --project flag that populates ProjectIDs in the request body. No test verifies this field is correctly wired — the existing test passes an empty project string. Low risk since it is a simple string-to-slice assignment, but it is an untested branch.

  2. runContextsDelete with accepted confirmation (force=false, user says "y"): There is a test for force=true and for declined, but no test for the non-force accepted path. The analogous runDelete and runOptionsDelete do test this path. Symmetry gap only — the underlying code path is identical.

  3. JSON output for mutation commands: runCreate has a JSON test, but runContextsCreate, runOptionsAdd, runOptionsUpdate do not test JSON output mode. The JSON path is a single v.JSON() call, so risk is low.

  4. runOptionsAdd empty-response branch (line 160-163 in options.go): When CreateFieldContextOptions returns an empty slice, the success message falls back to printing the value string. No test covers this branch. Low probability in practice but it is explicit conditional logic.

  5. API-level server error tests: Only TestCreateField_ServerError tests a non-2xx response. The other 10 API methods do not have server-error tests. The error handling is uniform (delegated to c.post/c.get/c.put/c.delete which are tested elsewhere), so this is reasonable — just noting it for completeness.

  6. resolveContextID auto-detect failure path: GetDefaultFieldContext with no contexts is tested at the API layer, but the command-layer wrapping that adds "use --context to specify" to the error message is not tested.

Verdict

The test coverage is solid and well above the codebase baseline. The gaps identified are minor — all critical paths (CRUD operations, URL construction, field ID validation, confirmation prompts, output formatting) are covered. The 82.2% statement coverage on the command layer is the highest of any command package in the repo. No blocking issues from a test coverage perspective.

@rianjs rianjs merged commit 0274def into main Feb 12, 2026
7 checks passed
@rianjs rianjs deleted the feat/155-field-management branch February 12, 2026 23:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(jtk): add custom field management commands (CRUD for fields and field options)

1 participant