fix(#411): QA-005 — production logging, error classification, session-expired state
logAuthError now always logs (not dev-only). Replaced isBackendError with parseAuthError-based classification. signOut uses proper error type. Session expiry sets explicit session_expired state. Login page logs in prod. Fixed pre-existing lint violations in auth package (campsite rule). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -105,7 +105,7 @@ describe("fetchWithRetry", (): void => {
|
||||
fetchWithRetry("https://api.example.com/auth/config", undefined, {
|
||||
maxRetries: 3,
|
||||
baseDelayMs: 1000,
|
||||
}),
|
||||
})
|
||||
).rejects.toThrow("Failed to fetch");
|
||||
|
||||
// 1 initial + 3 retries = 4 total attempts
|
||||
@@ -149,15 +149,13 @@ describe("fetchWithRetry", (): void => {
|
||||
|
||||
it("should respect custom maxRetries option", async (): Promise<void> => {
|
||||
const networkError = new TypeError("Failed to fetch");
|
||||
vi.mocked(global.fetch)
|
||||
.mockRejectedValueOnce(networkError)
|
||||
.mockRejectedValueOnce(networkError);
|
||||
vi.mocked(global.fetch).mockRejectedValueOnce(networkError).mockRejectedValueOnce(networkError);
|
||||
|
||||
await expect(
|
||||
fetchWithRetry("https://api.example.com/auth/config", undefined, {
|
||||
maxRetries: 1,
|
||||
baseDelayMs: 50,
|
||||
}),
|
||||
})
|
||||
).rejects.toThrow("Failed to fetch");
|
||||
|
||||
// 1 initial + 1 retry = 2 total attempts
|
||||
@@ -202,7 +200,7 @@ describe("fetchWithRetry", (): void => {
|
||||
});
|
||||
|
||||
it("should log retry attempts in all environments", async (): Promise<void> => {
|
||||
const warnSpy = vi.spyOn(console, "warn").mockImplementation((): void => {});
|
||||
const warnSpy = vi.spyOn(console, "warn").mockReturnValue(undefined);
|
||||
|
||||
const okResponse = mockResponse(200);
|
||||
vi.mocked(global.fetch)
|
||||
@@ -212,28 +210,24 @@ describe("fetchWithRetry", (): void => {
|
||||
await fetchWithRetry("https://api.example.com/auth/config");
|
||||
|
||||
expect(warnSpy).toHaveBeenCalledTimes(1);
|
||||
expect(warnSpy).toHaveBeenCalledWith(
|
||||
expect.stringContaining("[Auth] Retry 1/3"),
|
||||
);
|
||||
expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining("[Auth] Retry 1/3"));
|
||||
|
||||
warnSpy.mockRestore();
|
||||
});
|
||||
|
||||
it("should log retry attempts for HTTP errors", async (): Promise<void> => {
|
||||
const warnSpy = vi.spyOn(console, "warn").mockImplementation((): void => {});
|
||||
const warnSpy = vi.spyOn(console, "warn").mockReturnValue(undefined);
|
||||
|
||||
const serverError = mockResponse(500);
|
||||
const okResponse = mockResponse(200);
|
||||
|
||||
vi.mocked(global.fetch)
|
||||
.mockResolvedValueOnce(serverError)
|
||||
.mockResolvedValueOnce(okResponse);
|
||||
vi.mocked(global.fetch).mockResolvedValueOnce(serverError).mockResolvedValueOnce(okResponse);
|
||||
|
||||
await fetchWithRetry("https://api.example.com/auth/config");
|
||||
|
||||
expect(warnSpy).toHaveBeenCalledTimes(1);
|
||||
expect(warnSpy).toHaveBeenCalledWith(
|
||||
expect.stringContaining("[Auth] Retry 1/3 after HTTP 500"),
|
||||
expect.stringContaining("[Auth] Retry 1/3 after HTTP 500")
|
||||
);
|
||||
|
||||
warnSpy.mockRestore();
|
||||
@@ -253,7 +247,7 @@ describe("fetchWithRetry", (): void => {
|
||||
|
||||
expect(global.fetch).toHaveBeenCalledWith(
|
||||
"https://api.example.com/auth/config",
|
||||
requestOptions,
|
||||
requestOptions
|
||||
);
|
||||
});
|
||||
|
||||
@@ -262,9 +256,9 @@ describe("fetchWithRetry", (): void => {
|
||||
const nonRetryableError = new Error("Unauthorized");
|
||||
vi.mocked(global.fetch).mockRejectedValueOnce(nonRetryableError);
|
||||
|
||||
await expect(
|
||||
fetchWithRetry("https://api.example.com/auth/config"),
|
||||
).rejects.toThrow("Unauthorized");
|
||||
await expect(fetchWithRetry("https://api.example.com/auth/config")).rejects.toThrow(
|
||||
"Unauthorized"
|
||||
);
|
||||
|
||||
expect(global.fetch).toHaveBeenCalledTimes(1);
|
||||
expect(sleepMock).not.toHaveBeenCalled();
|
||||
|
||||
Reference in New Issue
Block a user