Skip to content

fix(jtk): align automation API parsing with Jira Cloud#87

Merged
rianjs merged 2 commits intoopen-cli-collective:mainfrom
lunareed720:fix-automation-api-types
Feb 7, 2026
Merged

fix(jtk): align automation API parsing with Jira Cloud#87
rianjs merged 2 commits intoopen-cli-collective:mainfrom
lunareed720:fix-automation-api-types

Conversation

@lunareed720
Copy link
Copy Markdown
Contributor

@lunareed720 lunareed720 commented Feb 7, 2026

Fixes #81

Automation API responses in Jira Cloud differ from the documented types (e.g. list uses {links,data} and rules are identified by uuid).

Changes:

  • Parse list responses from both legacy {values,next} and Cloud {data,links.next} shapes
  • Parse get responses when wrapped in {rule: ...} envelope (fallback to legacy top-level rule)
  • Prefer UUID identifiers in CLI output for list/get/update/create
  • Update tests to cover the Cloud response shapes (including pagination)

@rianjs
Copy link
Copy Markdown
Contributor

rianjs commented Feb 7, 2026

TDD Assessment for PR #87

Summary

This PR adapts the automation API layer and CLI commands to handle Jira Cloud's actual response shapes, which differ from the documented types. The changes span 8 files: 3 in the api/ package (types, client, tests) and 5 in the command layer (create, get, list, update, and their tests).

What the PR changes

  1. Dual-shape response parsing -- AutomationRuleSummaryResponse now supports both the Cloud shape ({data, links}) and the legacy shape ({values, next, total}), mediated by Items() and NextURL() helper methods.
  2. Envelope unwrapping for GetAutomationRule -- tries {rule: ...} envelope first, falls back to top-level rule object.
  3. Identifier normalization -- new Identifier() methods on both AutomationRule and AutomationRuleSummary with a priority chain of UUID > RuleKey > ID.
  4. RuleKey-to-UUID backfill -- GetAutomationRule copies RuleKey into UUID when UUID is absent.
  5. CLI output -- list/get/create/update commands now display UUID instead of numeric ID.

Coverage verdict: Adequate at the API layer, but has gaps worth closing

The API-layer tests are well-structured and were updated alongside the code. The command-layer tests are thinner. Here is the breakdown:

Well-covered (no action needed)

Area Notes
ListAutomationRules (82.4%) Cloud shape tested, pagination tested with links.next pointer.
ListAutomationRulesFiltered (90%) ENABLED/DISABLED/empty filter all tested.
NextURL() (100%) Both links.next and legacy next paths exercised.
TestGetAutomationRule Updated to use the Cloud envelope {rule: ...}. Asserts trigger/components.
TestListAutomationRulesPagination Multi-page with links.next pointer fully tested.
runCreate (76%) Happy path, invalid JSON, missing file tested. Output asserts new-uuid.
summarizeComponents (100%) Good table-driven coverage.
runSetState (82.4%) Already-enabled, already-disabled, enable-disabled-rule tested.

Gaps that should be addressed

1. Identifier() methods -- 0% coverage (both AutomationRule and AutomationRuleSummary)

These methods encode a priority chain (UUID > RuleKey > ID > "") that is a core behavioral change in this PR. Every CLI command now calls Identifier() for display, and all three fallback tiers are untested. This is the most important gap.

Suggested tests:

  • UUID set -> returns UUID
  • UUID empty, RuleKey set -> returns RuleKey
  • Both empty, ID set -> returns ID string
  • All empty -> returns ""

2. GetAutomationRule -- 50% coverage, legacy fallback path not explicitly tested

The new try-envelope-then-fallback logic in GetAutomationRule is partially tested: the envelope path is tested (TestGetAutomationRule), and the enable_test.go tests happen to exercise the legacy fallback (because newAutomationTestServer returns the rule at the top level). However, the legacy fallback is exercised accidentally via a different package's test helpers, not intentionally. There is also no test for the RuleKey -> UUID normalization in either path.

Suggested tests:

  • Legacy shape (top-level rule object, no envelope) -> parses correctly
  • Envelope with RuleKey but no UUID -> UUID gets populated from RuleKey
  • Legacy shape with RuleKey but no UUID -> same normalization

3. Items() legacy fallback -- 66.7% coverage

Items() returns Data when it is non-empty, else falls back to Values. All existing list tests populate Data, so the Values fallback is never exercised. If this PR claims to maintain backward compatibility with the legacy shape, that path should be tested.

Suggested test:

  • Response with only Values populated (empty Data) -> Items() returns Values

4. runGet, runList, runUpdate -- 0% coverage

These three commands were modified in this PR (ID -> UUID in output formatting) but have zero test coverage. The list.go and get.go changes are display-only (swapping r.ID.String() for r.Identifier() and changing the header from "ID" to "UUID"), and update.go similarly changes the info message. These are low-risk cosmetic changes, so I would not block the PR on this, but they are worth noting for future work.


Bottom line

The most consequential new logic in this PR -- the Identifier() methods and the GetAutomationRule dual-shape parsing with RuleKey normalization -- has meaningful test gaps. The Identifier() methods are at 0% coverage despite being called in every CLI command that was changed. And the backward-compatibility claim (legacy response shapes still work) is only accidentally tested.

I would recommend adding:

  1. Unit tests for Identifier() on both types (table-driven, 4 cases each) -- these are pure functions and trivial to test.
  2. An explicit TestGetAutomationRule_LegacyShape test that returns the rule at the top level (no envelope).
  3. A TestGetAutomationRule_RuleKeyNormalization test for the RuleKey -> UUID backfill.
  4. A TestItems_LegacyFallback test for Items() returning Values when Data is empty.

These additions are small (probably ~60-80 lines total) and would close the meaningful coverage gaps without being dogmatic about hitting arbitrary coverage percentages.

rianjs added a commit to lunareed720/atlassian-cli that referenced this pull request Feb 7, 2026
…normalization

Cover the gaps in PR open-cli-collective#87:
- Identifier() priority chain on both AutomationRule and AutomationRuleSummary
- Items() fallback from Data to Values for legacy list responses
- NextURL() fallback from Links.Next to top-level Next
- GetAutomationRule legacy shape (no envelope) parsing
- RuleKey→UUID normalization in both envelope and legacy paths
- End-to-end ListAutomationRules with legacy response shape
Luna Reed and others added 2 commits February 7, 2026 11:25
Handle Cloud automation list/get response shapes (data/links envelope + uuid identifiers) and update CLI output to use UUIDs.
…normalization

Cover the gaps in PR open-cli-collective#87:
- Identifier() priority chain on both AutomationRule and AutomationRuleSummary
- Items() fallback from Data to Values for legacy list responses
- NextURL() fallback from Links.Next to top-level Next
- GetAutomationRule legacy shape (no envelope) parsing
- RuleKey→UUID normalization in both envelope and legacy paths
- End-to-end ListAutomationRules with legacy response shape
@rianjs rianjs force-pushed the fix-automation-api-types branch from d5bd89b to 18d0157 Compare February 7, 2026 16:25
@rianjs rianjs merged commit 7959c4f into open-cli-collective:main Feb 7, 2026
7 checks passed
@rianjs
Copy link
Copy Markdown
Contributor

rianjs commented Feb 7, 2026

@lunareed720 - fix is available via homebrew now - jtk-v1.0.19

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.

fix: automation API response types don't match actual API

2 participants