/** * Elections API Tests * Tests for Bug #1: Missing /api/elections/upcoming and /completed endpoints */ import * as api from "@/lib/api" // Mock fetch global.fetch = jest.fn() describe("Elections API - Bug #1: Missing Endpoints Fix", () => { beforeEach(() => { jest.clearAllMocks() localStorage.getItem = jest.fn().mockReturnValue("test-token") }) test("getActive elections endpoint works", async () => { const mockElections = [ { id: 1, name: "Active Election", description: "Currently active", start_date: new Date().toISOString(), end_date: new Date(Date.now() + 86400000).toISOString(), is_active: true, results_published: false, candidates: [], }, ] ;(global.fetch as jest.Mock).mockResolvedValueOnce({ ok: true, status: 200, json: async () => mockElections, }) const response = await api.electionsApi.getActive() expect(response.status).toBe(200) expect(response.data).toEqual(mockElections) expect(global.fetch).toHaveBeenCalledWith( expect.stringContaining("/api/elections/active"), expect.any(Object) ) }) test("getUpcoming elections endpoint works", async () => { const mockUpcomingElections = [ { id: 2, name: "Upcoming Election", description: "Starting soon", start_date: new Date(Date.now() + 864000000).toISOString(), end_date: new Date(Date.now() + 950400000).toISOString(), is_active: true, results_published: false, candidates: [], }, ] ;(global.fetch as jest.Mock).mockResolvedValueOnce({ ok: true, status: 200, json: async () => mockUpcomingElections, }) const response = await api.electionsApi.getUpcoming() expect(response.status).toBe(200) expect(response.data).toEqual(mockUpcomingElections) expect(global.fetch).toHaveBeenCalledWith( expect.stringContaining("/api/elections/upcoming"), expect.any(Object) ) }) test("getCompleted elections endpoint works", async () => { const mockCompletedElections = [ { id: 3, name: "Completed Election", description: "Already finished", start_date: new Date(Date.now() - 864000000).toISOString(), end_date: new Date(Date.now() - 777600000).toISOString(), is_active: true, results_published: true, candidates: [], }, ] ;(global.fetch as jest.Mock).mockResolvedValueOnce({ ok: true, status: 200, json: async () => mockCompletedElections, }) const response = await api.electionsApi.getCompleted() expect(response.status).toBe(200) expect(response.data).toEqual(mockCompletedElections) expect(global.fetch).toHaveBeenCalledWith( expect.stringContaining("/api/elections/completed"), expect.any(Object) ) }) test("all election endpoints accept authentication token", async () => { ;(global.fetch as jest.Mock).mockResolvedValue({ ok: true, status: 200, json: async () => [], }) const token = "test-auth-token" ;(localStorage.getItem as jest.Mock).mockReturnValue(token) await api.electionsApi.getActive() const callArgs = (global.fetch as jest.Mock).mock.calls[0][1] expect(callArgs.headers.Authorization).toBe(`Bearer ${token}`) }) test("election endpoints handle errors gracefully", async () => { const errorMessage = "Server error" ;(global.fetch as jest.Mock).mockResolvedValueOnce({ ok: false, status: 500, json: async () => ({ detail: errorMessage }), }) const response = await api.electionsApi.getUpcoming() expect(response.error).toBeDefined() expect(response.status).toBe(500) }) test("election endpoints return array of elections", async () => { const mockElections = [ { id: 1, name: "Election 1" }, { id: 2, name: "Election 2" }, ] ;(global.fetch as jest.Mock).mockResolvedValueOnce({ ok: true, status: 200, json: async () => mockElections, }) const response = await api.electionsApi.getActive() expect(Array.isArray(response.data)).toBe(true) expect(response.data).toHaveLength(2) }) }) describe("Elections API - Response Format Consistency", () => { test("all election endpoints return consistent response format", async () => { const mockData = [] ;(global.fetch as jest.Mock).mockResolvedValue({ ok: true, status: 200, json: async () => mockData, }) const activeResp = await api.electionsApi.getActive() const upcomingResp = await api.electionsApi.getUpcoming() const completedResp = await api.electionsApi.getCompleted() // All should have same structure expect(activeResp).toHaveProperty("data") expect(activeResp).toHaveProperty("status") expect(upcomingResp).toHaveProperty("data") expect(upcomingResp).toHaveProperty("status") expect(completedResp).toHaveProperty("data") expect(completedResp).toHaveProperty("status") }) test("election endpoints return array directly, not wrapped in object", async () => { const mockElections = [{ id: 1, name: "Test" }] ;(global.fetch as jest.Mock).mockResolvedValueOnce({ ok: true, status: 200, json: async () => mockElections, }) const response = await api.electionsApi.getActive() // Should be array, not { elections: [...] } expect(Array.isArray(response.data)).toBe(true) expect(response.data[0].name).toBe("Test") }) })