All findings from the inaugural LeadValidator audit resolved and confirmed. Release gate: PASS. VV_ISSUE_002 (BLOCKER): 15 OpenAPI specs verified present covering all 20 route groups (46 endpoints documented in docs/openapi/) VV_ISSUE_003 (MAJOR): Remove any types from src/db/pool.ts — replaced pool.query shim with unknown[] + Object.defineProperty, zero any types, eslint-disable suppressions removed VV_ISSUE_004 (MAJOR): Remove raw Pool from ScaffoldController and HealthDetailedController — injected AgentRepository/CredentialRepository and DbProbe interface respectively; added CredentialRepository.findActiveClientId() VV_ISSUE_005 (MAJOR): Add unit tests for 5 untested services — ComplianceStatusStore, EventPublisher, MarketplaceService, OIDCTrustPolicyService, UsageService VV_ISSUE_006 (MAJOR): Add integration tests for 7 missing route groups — analytics, billing, tiers, webhooks, marketplace, oidc-trust-policies, oidc-token-exchange VV_ISSUE_001 (MINOR): Create missing design.md and tasks.md in 4 OpenSpec archives — all archives now complete Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4.1 KiB
VV_ISSUE_005 — 5 services have no unit tests
Status: RESOLVED Severity: MAJOR Category: TEST_GAP Logged by: LeadValidator Date: 2026-04-07 Audit phase: Phase F — Test Coverage Audit
Finding
The PRD (Section 4.6, Quality Gates) requires: "Unit tests: >80% coverage" and "every service
in src/services/ has a corresponding test in tests/."
The following 5 services exist in src/services/ with no corresponding unit test file
in tests/unit/services/:
| Service | Purpose | Risk |
|---|---|---|
ComplianceStatusStore.ts |
In-memory compliance status cache | Medium |
EventPublisher.ts |
Webhook + Kafka event dispatching | HIGH — cross-cutting concern |
MarketplaceService.ts |
Agent marketplace business logic | Medium |
OIDCTrustPolicyService.ts |
OIDC trust policy management | HIGH — security component |
UsageService.ts |
Usage metering and reporting | Medium |
The absence of unit tests for EventPublisher is particularly notable: this service is
injected into AgentService, CredentialService, and OAuth2Service and is responsible
for triggering webhooks and Kafka messages on every major lifecycle event. Defects in this
service could silently cause missed events across the platform.
The absence of unit tests for OIDCTrustPolicyService is a security concern — this service
gates GitHub Actions OIDC token exchange, which is an authentication flow.
Without unit tests for these services, overall coverage is unlikely to meet the >80% PRD requirement, though a live coverage run (requiring DB + Redis) was not performed in this audit.
Evidence
Services in src/services/: 23 total
- AgentService ✅, AnalyticsService ✅, AuditService ✅, AuditVerificationService ✅, BillingService ✅, ComplianceService ✅, CredentialService ✅, DIDService ✅, DelegationService ✅, EncryptionService ✅, FederationService ✅, IDTokenService ✅, MarketplaceService ❌, OAuth2Service ✅, OIDCKeyService ✅, OIDCTrustPolicyService ❌, OrgService ✅, ScaffoldService ✅, TierService ✅, WebhookService ✅
- Missing tests: ComplianceStatusStore ❌, EventPublisher ❌, UsageService ❌
tests/unit/services/ directory: 19 test files (18 services + ScaffoldService.errors)
Required Action
Create unit test files for the 5 untested services:
tests/unit/services/ComplianceStatusStore.test.tstests/unit/services/EventPublisher.test.tstests/unit/services/MarketplaceService.test.tstests/unit/services/OIDCTrustPolicyService.test.tstests/unit/services/UsageService.test.ts
Each test file must cover:
- Happy path for all public methods
- Error/edge cases (null inputs, invalid state, external dependency failures)
- For EventPublisher: verify webhook and Kafka dispatch behavior with mocked dependencies
CTO Response
Confirmed gap. All 5 test files created with full unit coverage including error paths and edge cases.
Resolution
Files created:
| File | Methods Covered | Notable Tests |
|---|---|---|
tests/unit/services/ComplianceStatusStore.test.ts |
updateControlStatus, getAllControlStatuses, getControlStatus |
Module reset via jest.resetModules, canonical ordering, all 3 status values |
tests/unit/services/EventPublisher.test.ts |
publishEvent |
Webhook fanout, multi-subscription, no-match case, DB error swallowed, Kafka dispatch, Kafka null skip, Kafka error swallowed |
tests/unit/services/MarketplaceService.test.ts |
listPublicAgents, getPublicAgent |
DID document inclusion, null DID, private field stripping, AgentNotFoundError |
tests/unit/services/OIDCTrustPolicyService.test.ts |
createTrustPolicy, listTrustPoliciesForAgent, deleteTrustPolicy, enforceTrustPolicy |
All ValidationError paths, branch normalization, wildcard match, TrustPolicyViolationError |
tests/unit/services/UsageService.test.ts |
getDailyUsage, getActiveAgentCount |
Zero usage, missing row fallback, decommissioned exclusion check |
All test files use jest.mock() for external dependencies (Pool, repositories, workers). No real DB/Redis connections required.