Background
Follow-up to merged PR #56 (E-21 image generation exception mapping). Codex review flagged a test-design issue that was not addressed before merge.
Problem
agency.tests/GptServiceImageErrorTests.cs asserts against a local helper MapImageException that reimplements the catch/filter logic from GptService.Image.cs. Because the tests run through the duplicated helper rather than invoking GptService.GenerateImageAsync<T> itself, the suite can stay green even if the real production mapping drifts — for example, if a future edit in GptService.Image.cs changes or removes the 401/429 clauses, the tests will not catch it.
This weakens regression protection for a behavior P5 and P8 callers depend on (401 → UnauthorizedAccessException, 429 → ImageRateLimitedException).
Codex severity: P2.
Proposed fix
Either:
- Extract the status-to-exception mapping into a shared, internal static method on
GptService (e.g. GptService.MapImageException(ClientResultException) in a partial file), have both production and tests call it directly. Delete the test-local duplicate.
- Or rewrite the tests to call
GptService.GenerateImageAsync<T> through a fake OpenAIClient / HttpMessageHandler that returns specific ClientResultException status codes — exercising the full production code path.
Option 1 is smaller; option 2 is stricter. Pick based on how hard it is to stub OpenAIClient cleanly in the existing test setup.
Acceptance
- No duplicated catch/filter logic between production and tests.
- Tests fail if
GptService.Image.cs:56-80 is changed in a way that alters observable exception mapping.
- All 12 existing E-21 tests still pass.
References
Background
Follow-up to merged PR #56 (E-21 image generation exception mapping). Codex review flagged a test-design issue that was not addressed before merge.
Problem
agency.tests/GptServiceImageErrorTests.csasserts against a local helperMapImageExceptionthat reimplements the catch/filter logic fromGptService.Image.cs. Because the tests run through the duplicated helper rather than invokingGptService.GenerateImageAsync<T>itself, the suite can stay green even if the real production mapping drifts — for example, if a future edit inGptService.Image.cschanges or removes the 401/429 clauses, the tests will not catch it.This weakens regression protection for a behavior P5 and P8 callers depend on (401 →
UnauthorizedAccessException, 429 →ImageRateLimitedException).Codex severity: P2.
Proposed fix
Either:
GptService(e.g.GptService.MapImageException(ClientResultException)in a partial file), have both production and tests call it directly. Delete the test-local duplicate.GptService.GenerateImageAsync<T>through a fakeOpenAIClient/HttpMessageHandlerthat returns specificClientResultExceptionstatus codes — exercising the full production code path.Option 1 is smaller; option 2 is stricter. Pick based on how hard it is to stub
OpenAIClientcleanly in the existing test setup.Acceptance
GptService.Image.cs:56-80is changed in a way that alters observable exception mapping.References