test(tpagectl): add comprehensive test suite #612

Merged
fuzzy merged 1 commit from test/tpagectl-test-suite into main 2026-08-08 16:07:56 +00:00
Owner

What

Implements Phase 8 test coverage (roadmap #288).

  • #284 — client unit tests with mocks — a roundTripFunc mock http.RoundTripper covering the previously-untested do() branches (JSON encode-request error, decode-response error on a 2xx with invalid JSON) plus mock-driven bearer-token attachment. Client coverage → 90.9%.
  • #285 — integration tests against a test instance — new cmd/tpagectl/integration_test.go with a stateful fake daemon (httptest) implementing the full /api/v1 surface + /healthz//readyz, running the real root command end-to-end (config → client → command → output → exit code): site lifecycle (create/list/get/update/delete), deployment list/get/promote/rollback, preview deploy/list/get/delete, status, --format json/yaml, and exit-code classification (not-found 4, validation 5). Running the actual daemon requires Forgejo+K8s, noted as out of scope.
  • #286 — golden testsinternal/tpagectl/testutil.Golden with a -update flag; .golden files for site list (table/json), site get, deployment list, preview list, status, and root --help.
  • #287 — coverage >80% — aggregate raised to 86.4% (weighted, tpagectl packages): credentials 3.8% → 88.5% via an injectable openKeyring opener tested with keyring.NewArrayKeyring; gap tests for config (→81.9%), docs (→89.3%), auth (→87.3%), interactive (→72.8%; the TTY-gated picker path is documented as not unit-testable). Added a Makefile coverage target gating weighted coverage of ./internal/tpagectl/... ./cmd/tpagectl/... at ≥80%.

Why

Roadmap task #288.

Testing

  • go test -race ./... passes (30 packages)
  • make coverage reports 86.4% and passes the ≥80% gate
  • golangci-lint run clean
  • pre-commit hooks pass (gofmt, go mod tidy, go test)

Breaking Changes

None. credentials.open() now uses an injectable openKeyring var (default keyring.Open); behavior unchanged.

Notes

The interactive ResolveSite TTY path (raw-mode fuzzy picker) cannot be unit-tested without a pty; its selectInteractive core is covered via synthetic key bytes. CI enforcement of the coverage gate is deferred to task #293 (CI pipeline).

Closes #284
Closes #285
Closes #286
Closes #287

## What Implements Phase 8 test coverage (roadmap #288). - **#284 — client unit tests with mocks** — a `roundTripFunc` mock `http.RoundTripper` covering the previously-untested `do()` branches (JSON encode-request error, decode-response error on a 2xx with invalid JSON) plus mock-driven bearer-token attachment. Client coverage → 90.9%. - **#285 — integration tests against a test instance** — new `cmd/tpagectl/integration_test.go` with a stateful **fake daemon** (httptest) implementing the full `/api/v1` surface + `/healthz`/`/readyz`, running the real root command end-to-end (config → client → command → output → exit code): site lifecycle (create/list/get/update/delete), deployment list/get/promote/rollback, preview deploy/list/get/delete, status, `--format json/yaml`, and exit-code classification (not-found 4, validation 5). Running the actual daemon requires Forgejo+K8s, noted as out of scope. - **#286 — golden tests** — `internal/tpagectl/testutil.Golden` with a `-update` flag; `.golden` files for site list (table/json), site get, deployment list, preview list, status, and root `--help`. - **#287 — coverage >80%** — aggregate raised to **86.4%** (weighted, tpagectl packages): `credentials` 3.8% → 88.5% via an injectable `openKeyring` opener tested with `keyring.NewArrayKeyring`; gap tests for `config` (→81.9%), `docs` (→89.3%), `auth` (→87.3%), `interactive` (→72.8%; the TTY-gated picker path is documented as not unit-testable). Added a Makefile `coverage` target gating weighted coverage of `./internal/tpagectl/... ./cmd/tpagectl/...` at ≥80%. ## Why Roadmap task #288. ## Testing - [x] `go test -race ./...` passes (30 packages) - [x] `make coverage` reports 86.4% and passes the ≥80% gate - [x] `golangci-lint run` clean - [x] pre-commit hooks pass (gofmt, go mod tidy, go test) ## Breaking Changes None. `credentials.open()` now uses an injectable `openKeyring` var (default `keyring.Open`); behavior unchanged. ## Notes The interactive `ResolveSite` TTY path (raw-mode fuzzy picker) cannot be unit-tested without a pty; its `selectInteractive` core is covered via synthetic key bytes. CI enforcement of the coverage gate is deferred to task #293 (CI pipeline). Closes #284 Closes #285 Closes #286 Closes #287
test(tpagectl): add comprehensive test suite
All checks were successful
Test and Release / lint (pull_request) Successful in 7m46s
Test and Release / test (pull_request) Successful in 8m4s
d635624e02
- #284: client unit tests with a mock RoundTripper covering encode and
  decode failure paths plus bearer-token attachment.
- #285: integration tests against a stateful fake daemon (httptest)
  running the real root command end-to-end: site lifecycle, deployments,
  previews, status, output formats, and exit-code classification.
- #286: golden tests for stable outputs (site list table/json, site get,
  deployment list, preview list, status, root help) with a -update flag.
- #287: coverage raised to 86.4% aggregate (credentials 3.8% -> 88.5% via
  an injectable keyring opener and ArrayKeyring tests; config/docs/auth/
  interactive gap tests) and a Makefile coverage target gating the
  tpagectl packages at >= 80%.

Closes #284
Closes #285
Closes #286
Closes #287
fuzzy scheduled this pull request to auto merge when all checks succeed 2026-08-08 16:06:15 +00:00
the.auditor left a comment

Excellent test suite. The stateful fake daemon covers the full /api/v1 surface end-to-end (config → client → command → output → exit codes) with deterministic ordering (slice-based payloads, substring assertions on the map-order list), the credentials tests close the #593 coverage gap cleanly via the injectable openKeyring (with a withOpener restore-helper, covering unavailable/genuine-failure/notfound paths), golden tests use fixed-body servers for determinism, and the Makefile coverage gate math is correct. Approving; no new issues — the CI enforcement gap is already tracked as #293.

Notes (non-blocking)

  • cmd/tpagectl/integration_test.go:493var _ = fmt.Sprintf is a dummy keeping an unused fmt import; trivial cleanup.
  • credentials.openKeyring is a mutable package-global for test injection — safe today (no t.Parallel), but a latent footgun if parallel tests are added later.
  • Golden root-help.golden is brittle by design (help output changes with any flag/command addition); standard golden-test tradeoff.

Praise

  • Client roundTripFunc mock covers the previously-untested do() encode/decode-error branches and bearer-token attachment.
  • Integration tests exercise the real root command with --token/--server, keeping the keychain out of the path.
  • Coverage improvements are targeted (gap tests per package) rather than padding, and the gate is measurable and reproducible.
Excellent test suite. The stateful fake daemon covers the full `/api/v1` surface end-to-end (config → client → command → output → exit codes) with deterministic ordering (slice-based payloads, substring assertions on the map-order list), the `credentials` tests close the #593 coverage gap cleanly via the injectable `openKeyring` (with a `withOpener` restore-helper, covering unavailable/genuine-failure/notfound paths), golden tests use fixed-body servers for determinism, and the Makefile coverage gate math is correct. Approving; no new issues — the CI enforcement gap is already tracked as #293. ## Notes (non-blocking) - `cmd/tpagectl/integration_test.go:493` – `var _ = fmt.Sprintf` is a dummy keeping an unused `fmt` import; trivial cleanup. - `credentials.openKeyring` is a mutable package-global for test injection — safe today (no `t.Parallel`), but a latent footgun if parallel tests are added later. - Golden `root-help.golden` is brittle by design (help output changes with any flag/command addition); standard golden-test tradeoff. ## Praise - Client `roundTripFunc` mock covers the previously-untested `do()` encode/decode-error branches and bearer-token attachment. - Integration tests exercise the real root command with `--token`/`--server`, keeping the keychain out of the path. - Coverage improvements are targeted (gap tests per package) rather than padding, and the gate is measurable and reproducible.
fuzzy merged commit d635624e02 into main 2026-08-08 16:07:56 +00:00
fuzzy deleted branch test/tpagectl-test-suite 2026-08-08 16:07:56 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
thwap/thwap-pagesd!612
No description provided.