ADORSYS-GIS / ADORSYS-GIS/lightbridge-governance

[Ticket]: test: no coverage for the GitHub App JWT / installation-token / Copilot metrics fetch flow

Aperta
#58 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub
Lingua principale
Rust
Stelle
1
Fork
2
Merge medio
14h 36m
PR unite (30g)
107

Descrizione

## What's missing

`crates/governance-copilot/src/auth.rs`, `client.rs`, and `report.rs` have **zero test coverage**. Verified via `grep -rn "wiremock\|mockito"` over the whole workspace — nothing. The crate's only test file, `crates/governance-copilot/tests/store.rs`, is a Postgres-persistence integration test (`upsert_*`, `high_water_mark`, `verify_manifests`) and never touches `AppAuth`, `app_jwt`, `token_for_org`, or `fetch_report`.

This is the entire GitHub App authentication path:

1. **`AppAuth::app_jwt`** (`auth.rs`, ~L48-63) — signs an RS256 JWT from the App's private key (claims: `iss`=App ID, `iat`, `exp`=iat+600s).
2. **`AppAuth::installation_id`** (`auth.rs`, ~L85-115) — `GET /app/installations` (JWT-authed), matches `account.login` against `GH_ORG` case-insensitively. **No `GH_APP_INSTALLATION_ID` env var exists** — this is the only place the installation id comes from, so if the App is registered but never installed on the org, every run fails with `"no App installation found for org {org}"`.
3. **`AppAuth::token_for_org`** (`auth.rs`, ~L118-149) — `POST /app/installations/{id}/access_tokens`, expects HTTP 201, extracts `token`.
4. **`GithubClient::fetch_report`** (`report.rs`, ~L32-129) — `GET /orgs/{org}/copilot/metrics/reports/{report}?day={day}` bearer-authed with the installation token; follows the envelope's signed download URL (unauthenticated second GET) and streams the NDJSON body, capped at 64 MiB.

`GithubClient` (`client.rs`) is already built to accept an injected `reqwest::Client` — its own doc comment says "tests can substitute a mock transport" — but nothing exercises that path today.

## Why it matters

This is the only mechanism that authenticates `copilot-sync` against GitHub. Per this repo's own testing rules (AGENTS.md: "Prove the test catches the bug" / "Green does not mean tested"), none of the following failure modes are currently provable by CI:

- A malformed/expired PEM → does `app_jwt` fail with a clear error, or does `jsonwebtoken`'s `aws_lc_rs` backend panic instead?
- Installation lookup finds zero or multiple matching orgs (case-sensitivity, a suspended/uninstalled App, a renamed org).
- `/access_tokens` returns a non-201 (expired App JWT clock skew, revoked App, insufficient permissions) — does the caller get an actionable error, matching the `copilot-sync-failed` runbook's documented 403-troubleshooting steps?
- The signed download URL 404s outside the retention window vs. a genuine transient failure — does `fetch_report` distinguish these the way the runbook (`docs/runbooks/copilot-sync-failed.md`) claims it does?

## Suggested approach

Add a `wiremock` (or `mockito`) dev-dependency to `crates/governance-copilot/Cargo.toml`, inject a mock `reqwest::Client` via `GithubClient::new`, and cover at minimum:
- `app_jwt` produces a verifiable RS256 token with the expected claims from a test PEM.
- `installation_id` matching (found / not found / case-insensitive match).
- `token_for_org` on a non-201 response surfaces a distinguishable error.
- `fetch_report` on a 404 from the signed download URL vs. a 5xx.

## Context

Found while scoping the ai-helm deployment (ADORSYS-GIS/ai-helm#933, ADORSYS-GIS/ai-helm-values#196) — not a blocker for that work, filed as a follow-up.

Guida per i contributori

Apri la guida per i contributori

Direzione di ricerca

Read AGENTS.md, then inspect crates/governance-copilot/src/auth.rs, client.rs, and report.rs along with crates/governance-copilot/tests/store.rs. Start by tracing the injected reqwest::Client path and the existing authentication and report-fetch entry points. Done means coverage for JWT claims, installation lookup, non-201 token responses, and distinct signed-download 404 versus 5xx behavior using a mock transport.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
github, rust
Ambito
api, security, testing
Tipo di issue
Refactoring
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Tranquilla
Chiarezza
Abbastanza chiara
Idoneità per principianti
56/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.