/** * Auth Context Tests * Tests for the authentication context and has_voted state fix */ import React from "react" import { render, screen, waitFor } from "@testing-library/react" import { AuthProvider, useAuth } from "@/lib/auth-context" import * as api from "@/lib/api" // Mock the API module jest.mock("@/lib/api", () => ({ authApi: { login: jest.fn(), register: jest.fn(), getProfile: jest.fn(), logout: jest.fn(), }, getAuthToken: jest.fn(), setAuthToken: jest.fn(), clearAuthToken: jest.fn(), })) // Mock window.localStorage const localStorageMock = { getItem: jest.fn(), setItem: jest.fn(), removeItem: jest.fn(), clear: jest.fn(), } global.localStorage = localStorageMock as any describe("Auth Context - Bug #2: has_voted State Fix", () => { beforeEach(() => { jest.clearAllMocks() localStorageMock.getItem.mockReturnValue(null) }) test("login response includes has_voted field", async () => { const mockLoginResponse = { data: { access_token: "test-token", id: 1, email: "test@example.com", first_name: "Test", last_name: "User", has_voted: false, expires_in: 1800, }, status: 200, } ;(api.authApi.login as jest.Mock).mockResolvedValue(mockLoginResponse) ;(api.setAuthToken as jest.Mock).mockImplementation(() => {}) let authContextValue: any const TestComponent = () => { authContextValue = useAuth() return
{authContextValue.isLoading ? "Loading..." : "Ready"}
} const { rerender } = render( ) // Simulate login await waitFor(async () => { await authContextValue.login("test@example.com", "password123") }) expect(authContextValue.user).toBeDefined() expect(authContextValue.user?.has_voted).toBeDefined() expect(typeof authContextValue.user?.has_voted).toBe("boolean") }) test("register response includes has_voted field", async () => { const mockRegisterResponse = { data: { access_token: "test-token", id: 2, email: "newuser@example.com", first_name: "New", last_name: "User", has_voted: false, expires_in: 1800, }, status: 200, } ;(api.authApi.register as jest.Mock).mockResolvedValue(mockRegisterResponse) ;(api.setAuthToken as jest.Mock).mockImplementation(() => {}) let authContextValue: any const TestComponent = () => { authContextValue = useAuth() return
{authContextValue.isLoading ? "Loading..." : "Ready"}
} render( ) // Simulate registration await waitFor(async () => { await authContextValue.register( "newuser@example.com", "password123", "New", "User", "ID123456" ) }) expect(authContextValue.user?.has_voted).toBe(false) }) test("has_voted is correctly set from server response, not hardcoded", async () => { const mockLoginResponseVoted = { data: { access_token: "test-token", id: 3, email: "voted@example.com", first_name: "Voted", last_name: "User", has_voted: true, // User has already voted expires_in: 1800, }, status: 200, } ;(api.authApi.login as jest.Mock).mockResolvedValue(mockLoginResponseVoted) ;(api.setAuthToken as jest.Mock).mockImplementation(() => {}) let authContextValue: any const TestComponent = () => { authContextValue = useAuth() return
{authContextValue.isLoading ? "Loading..." : "Ready"}
} render( ) // Simulate login with user who has voted await waitFor(async () => { await authContextValue.login("voted@example.com", "password123") }) // Verify has_voted is true (from server) not false (hardcoded) expect(authContextValue.user?.has_voted).toBe(true) }) test("has_voted defaults to false if not in response", async () => { const mockLoginResponseNoField = { data: { access_token: "test-token", id: 4, email: "nofield@example.com", first_name: "No", last_name: "Field", // has_voted missing from response expires_in: 1800, }, status: 200, } ;(api.authApi.login as jest.Mock).mockResolvedValue(mockLoginResponseNoField) ;(api.setAuthToken as jest.Mock).mockImplementation(() => {}) let authContextValue: any const TestComponent = () => { authContextValue = useAuth() return
{authContextValue.isLoading ? "Loading..." : "Ready"}
} render( ) await waitFor(async () => { await authContextValue.login("nofield@example.com", "password123") }) // Should default to false if not present expect(authContextValue.user?.has_voted).toBe(false) }) test("profile refresh updates has_voted state", async () => { const mockProfileResponse = { data: { id: 5, email: "profile@example.com", first_name: "Profile", last_name: "User", has_voted: true, created_at: new Date().toISOString(), }, status: 200, } ;(api.authApi.getProfile as jest.Mock).mockResolvedValue(mockProfileResponse) ;(api.getAuthToken as jest.Mock).mockReturnValue("test-token") let authContextValue: any const TestComponent = () => { authContextValue = useAuth() return (
{authContextValue.user?.has_voted !== undefined ? `has_voted: ${authContextValue.user.has_voted}` : "no user"}
) } render( ) // Simulate profile refresh await waitFor(async () => { await authContextValue.refreshProfile() }) expect(authContextValue.user?.has_voted).toBe(true) }) }) describe("Auth Context - API Token Type Fix", () => { test("AuthToken interface includes has_voted field", () => { // This test ensures the TypeScript interface is correct const token: api.AuthToken = { access_token: "token", expires_in: 1800, id: 1, email: "test@example.com", first_name: "Test", last_name: "User", has_voted: false, } expect(token.has_voted).toBeDefined() expect(typeof token.has_voted).toBe("boolean") }) })