ADORSYS-GIS / ADORSYS-GIS/lightbridge-governance

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

Ouverte
#58 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub
Langage dominant
Rust
Étoiles
1
Forks
2
Merge moyen
13 h 13 min
PR mergées (30 j)
110

Description

## 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.

Guide de contribution

Ouvrir le guide de contribution

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.