Files
satellite-provider/_docs/03_implementation/reviews/batch_02_cycle3_review.md
T
Oleksandr Bezdieniezhnykh c396740644
ci/woodpecker/push/01-test Pipeline was successful
ci/woodpecker/push/02-build-push Pipeline was successful
[AZ-491] Cycle 3 batch 2: consolidate JWT test-mint helpers into TestSupport
AZ-491 (3 SP): eliminate the cycle-2 duplicate of JWT-minting logic
that existed in both SatelliteProvider.Tests/TestUtilities/
JwtTokenFactory.cs (unit-side) and SatelliteProvider.IntegrationTests/
JwtTestHelpers.cs (integration-side), where the same Expires <
NotBefore bug needed parallel fixes in commits f64d0d7 + 11b7074.

Option A chosen: new SatelliteProvider.TestSupport class library
(no test framework) holds the canonical JwtTokenFactory.Create /
CreateExpired / TamperSignature. Both Tests and IntegrationTests
consume it via ProjectReference; production projects (Api, Common,
DataAccess, Services.*) cannot depend on it. The notBefore-shift
workaround is preserved with an inline regression-prevention comment
back-referencing the cycle-2 fix commits.

SatelliteProvider.IntegrationTests/JwtTestHelpers.cs is stripped to
runner-only concerns: ResolveSecretOrThrow, AttachDefaultAuthorization,
and the DefaultSubject = "integration-tests" constant. Call sites in
Program.cs, JwtIntegrationTests.cs, and UavUploadTests.cs (10 sites)
switched to JwtTokenFactory.* with JwtTestHelpers.DefaultSubject
explicitly passed for the runner subject - behavior parity preserved.

Dockerfile for IntegrationTests gets the new TestSupport csproj
in its pre-restore COPY layer. Api Dockerfile unchanged (TestSupport
is NOT a production dependency).

A new code-review SKILL.md Phase 6 checklist row flags near-identical
helper logic across test projects as a Medium / Maintainability
finding with explicit cycle-2 retro back-reference, so this whole
pattern stops at one occurrence.

module-layout.md adds a TestSupport Shared/Cross-Cutting entry
documenting the production-isolation invariant. tests_unit.md +
tests_integration.md updated to describe the consolidated layout.
sln updated.

Test-suite gate (AC-2 + AC-3) deferred to Step 16 Final Test Run
per implement-skill convention. Per-batch review verdict:
PASS_WITH_WARNINGS with 1 Low (pre-existing 7.0.3 version pin
preserved verbatim from cycle-2 IntegrationTests csproj for parity;
not blocking; deferred bump).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 01:32:24 +03:00

5.4 KiB

Code Review Report — Batch 02 cycle 3

Batch: 02 (cycle 3) — AZ-491 (consolidate JWT test-mint helpers) Date: 2026-05-12 Verdict: PASS_WITH_WARNINGS

Findings

# Severity Category File:Line Title
1 Low Maintainability SatelliteProvider.TestSupport/SatelliteProvider.TestSupport.csproj:10-11 Pinned System.IdentityModel.Tokens.Jwt 7.0.3 lives alongside the API's transitive Microsoft.AspNetCore.Authentication.JwtBearer 8.0.25

Finding Details

F1: Pinned System.IdentityModel.Tokens.Jwt 7.0.3 lives alongside the API's transitive Microsoft.AspNetCore.Authentication.JwtBearer 8.0.25 (Low / Maintainability)

  • Location: SatelliteProvider.TestSupport/SatelliteProvider.TestSupport.csproj:10-11
  • Description: TestSupport's two pinned packages (Microsoft.IdentityModel.Tokens 7.0.3, System.IdentityModel.Tokens.Jwt 7.0.3) are the same versions that the integration-tests project previously pinned directly. These are not the same package family as the API's Microsoft.AspNetCore.Authentication.JwtBearer 8.0.25 — they belong to a different .NET versioning track. Token-minting logic in the test library and token-validation logic in the API consume related-but-separate IdentityModel types, so this is structurally fine, but a future agent reading the csproj could be confused about why the test library is one major version behind the API. The pre-AZ-491 IntegrationTests csproj had the same pinning; this batch preserved it for parity.
  • Suggestion: Defer. The 7.0.x → 8.0.x bump for System.IdentityModel.Tokens.Jwt would be a separate hardening task — out of scope for AZ-491 (which is a refactor, not a dependency bump). If the team chooses to align minor versions, it should ship as a single coordinated bump across all IdentityModel.* references with regression coverage. For AZ-491 the existing pinning is preserved unchanged so behavior parity with cycle 2 is guaranteed.
  • Task: AZ-491

Phase-by-Phase Summary

Phase Result Notes
1. Context Loading OK AZ-491 spec read; 6 ACs identified; Option A chosen with documented rationale
2. Spec Compliance OK 6/6 ACs verified at code level. AC-2 + AC-3 wait on Step 16 final test gate; their structural prerequisites (call-site signatures preserved; subject explicitly passed) are in place
3. Code Quality OK New JwtTokenFactory is a stateless static class — SRP satisfied; eliminates duplication; regression-prevention comment on the notBefore branch is the only doc-comment kept (justified per coderule.mdc — references cycle-2 fix commits)
4. Security Quick-Scan OK No production-code change; no new attack surface. Token-minting moved into a test-only library that production code MUST NOT consume — the module-layout.md entry encodes this invariant
5. Performance Scan OK (N/A) Test-infrastructure refactor; no hot-path code
6. Cross-Task Consistency OK Single task in batch; the new code-review rule introduced by this same batch will prevent future duplicate-helper regressions
7. Architecture Compliance OK TestSupport is correctly placed in the Shared / Cross-Cutting layer of module-layout.md. It is referenced only by Tests + IntegrationTests (both via ProjectReference); zero production projects reference it. No cycle introduced. Layering: TestSupport sits below both test projects (foundation); both test projects sit outside the production layering table

Cross-cutting observations (info, no finding)

  • The subject-value migration is the only semantic delta. Pre-AZ-491 the integration project's MintValidToken(secret) defaulted to subject = "integration-tests". Post-AZ-491 the same call site now reads JwtTokenFactory.Create(secret, JwtTestHelpers.DefaultSubject)JwtTestHelpers.DefaultSubject = "integration-tests" is still the canonical runner subject; the explicit-pass form preserves behavior exactly. Unit tests retain their own subject choices ("alice", "test-user", explicit per-test) unchanged.
  • The using System.IdentityModel.Tokens.Jwt; and using Microsoft.IdentityModel.Tokens; imports were removed from JwtTestHelpers.cs because the file no longer uses those namespaces after the mint logic moved out. No dead-import remains.
  • The SatelliteProvider.Tests/TestUtilities/ folder is intentionally retained (not deleted) because it still owns UavTileImageFactory.cs. That fixture-factory is out of scope per AZ-491 § Excluded — a future task could consolidate it into TestSupport, but only if/when integration tests also need it.

Baseline Delta

Class Count Notes
Carried over 0 No Architecture findings in baseline; nothing recurring
Resolved 1 (informal) The cycle-2 duplicate-helper Maintainability pattern (documented in LESSONS.md 2026-05-11 testing entry + retrospective Pattern 1) is structurally closed by this batch. Not an Architecture-class baseline entry, so it does not appear in the cycle-1 baseline; tracked here for the cycle retrospective
Newly introduced 0

Verdict Logic

  • 0 Critical, 0 High, 0 Medium, 1 Low → PASS_WITH_WARNINGS
  • The single Low finding is informational (pre-existing version pinning preserved verbatim from cycle-2 IntegrationTests csproj); does not block commit per the implement-skill auto-fix gate.

Recommendation to /implement

Proceed to commit + push + tracker transition (Steps 11-13).