test(#411): QA-015 — add credentials fallback test + fix refreshSession test name
Add test for non-string error.message fallback in handleCredentialsLogin. Rename misleading refreshSession test to match actual behavior. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -341,6 +341,33 @@ describe("LoginPage", (): void => {
|
|||||||
expect(mockPush).not.toHaveBeenCalled();
|
expect(mockPush).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should show fallback PDA-friendly message when error.message is not a string", async (): Promise<void> => {
|
||||||
|
mockFetchConfig(EMAIL_ONLY_CONFIG);
|
||||||
|
// Return an error object where message is NOT a string (e.g. numeric code, no message field)
|
||||||
|
mockSignInEmail.mockResolvedValueOnce({
|
||||||
|
error: { code: 123 },
|
||||||
|
});
|
||||||
|
const user = userEvent.setup();
|
||||||
|
|
||||||
|
render(<LoginPage />);
|
||||||
|
|
||||||
|
await waitFor((): void => {
|
||||||
|
expect(screen.getByLabelText(/email/i)).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
await user.type(screen.getByLabelText(/email/i), "test@example.com");
|
||||||
|
await user.type(screen.getByLabelText(/password/i), "wrong");
|
||||||
|
await user.click(screen.getByRole("button", { name: /continue/i }));
|
||||||
|
|
||||||
|
await waitFor((): void => {
|
||||||
|
expect(
|
||||||
|
screen.getByText("Unable to sign in. Please check your credentials and try again.")
|
||||||
|
).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(mockPush).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
it("shows parseAuthError message on unexpected sign-in exception", async (): Promise<void> => {
|
it("shows parseAuthError message on unexpected sign-in exception", async (): Promise<void> => {
|
||||||
mockFetchConfig(EMAIL_ONLY_CONFIG);
|
mockFetchConfig(EMAIL_ONLY_CONFIG);
|
||||||
mockSignInEmail.mockRejectedValueOnce(new TypeError("Failed to fetch"));
|
mockSignInEmail.mockRejectedValueOnce(new TypeError("Failed to fetch"));
|
||||||
|
|||||||
@@ -411,7 +411,7 @@ describe("AuthContext", (): void => {
|
|||||||
consoleErrorSpy.mockRestore();
|
consoleErrorSpy.mockRestore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should clear authError after successful session refresh", async (): Promise<void> => {
|
it("should persist authError across re-renders when no new session check occurs", async (): Promise<void> => {
|
||||||
const consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {
|
const consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {
|
||||||
// Intentionally empty
|
// Intentionally empty
|
||||||
});
|
});
|
||||||
@@ -429,26 +429,16 @@ describe("AuthContext", (): void => {
|
|||||||
expect(screen.getByTestId("auth-error")).toHaveTextContent("network");
|
expect(screen.getByTestId("auth-error")).toHaveTextContent("network");
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set up successful response for refresh
|
// Re-render does NOT trigger a new session check, so authError persists
|
||||||
const mockUser: AuthUser = {
|
|
||||||
id: "user-1",
|
|
||||||
email: "test@example.com",
|
|
||||||
name: "Test User",
|
|
||||||
};
|
|
||||||
vi.mocked(apiGet).mockResolvedValueOnce({
|
|
||||||
user: mockUser,
|
|
||||||
session: { id: "session-1", token: "token123", expiresAt: futureExpiry() },
|
|
||||||
});
|
|
||||||
|
|
||||||
// Trigger a rerender (simulating refreshSession being called)
|
|
||||||
rerender(
|
rerender(
|
||||||
<AuthProvider>
|
<AuthProvider>
|
||||||
<TestComponent />
|
<TestComponent />
|
||||||
</AuthProvider>
|
</AuthProvider>
|
||||||
);
|
);
|
||||||
|
|
||||||
// The initial render will have checked session once, error should still be there
|
// authError should still be "network" — re-render alone does not clear it
|
||||||
// A real refresh would need to call refreshSession
|
expect(screen.getByTestId("auth-error")).toHaveTextContent("network");
|
||||||
|
|
||||||
consoleErrorSpy.mockRestore();
|
consoleErrorSpy.mockRestore();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user