From a460e0e4f2c9ba19a4c13d349971b18c13ae49a0 Mon Sep 17 00:00:00 2001 From: Felipe Cardoso Date: Sun, 2 Nov 2025 07:35:45 +0100 Subject: [PATCH] Add unit tests for core components and layouts - **ThemeToggle:** Introduce comprehensive tests to validate button functionality, dropdown options, and active theme indicators. - **ThemeProvider:** Add tests for theme management, localStorage persistence, system preferences, and DOM updates. - **Header & Footer:** Verify header rendering, user menu functionality, and footer content consistency. - **AuthInitializer:** Ensure authentication state is correctly loaded from storage on mount. --- .../src/components/dev/ComponentShowcase.tsx | 3 + .../components/auth/AuthInitializer.test.tsx | 58 +++ .../tests/components/layout/Footer.test.tsx | 33 ++ .../tests/components/layout/Header.test.tsx | 345 +++++++++++++++++ .../components/theme/ThemeProvider.test.tsx | 349 ++++++++++++++++++ .../components/theme/ThemeToggle.test.tsx | 186 ++++++++++ 6 files changed, 974 insertions(+) create mode 100644 frontend/tests/components/auth/AuthInitializer.test.tsx create mode 100644 frontend/tests/components/layout/Footer.test.tsx create mode 100644 frontend/tests/components/layout/Header.test.tsx create mode 100644 frontend/tests/components/theme/ThemeProvider.test.tsx create mode 100644 frontend/tests/components/theme/ThemeToggle.test.tsx diff --git a/frontend/src/components/dev/ComponentShowcase.tsx b/frontend/src/components/dev/ComponentShowcase.tsx index b94d438..c56bcdf 100644 --- a/frontend/src/components/dev/ComponentShowcase.tsx +++ b/frontend/src/components/dev/ComponentShowcase.tsx @@ -1,6 +1,9 @@ +/* istanbul ignore file */ + /** * Component Showcase * Comprehensive display of all design system components + * This file is excluded from coverage as it's a demo/showcase page */ 'use client'; diff --git a/frontend/tests/components/auth/AuthInitializer.test.tsx b/frontend/tests/components/auth/AuthInitializer.test.tsx new file mode 100644 index 0000000..9b7a0a7 --- /dev/null +++ b/frontend/tests/components/auth/AuthInitializer.test.tsx @@ -0,0 +1,58 @@ +/** + * Tests for AuthInitializer + * Verifies authentication state is loaded from storage on mount + */ + +import { render, waitFor } from '@testing-library/react'; +import { AuthInitializer } from '@/components/auth/AuthInitializer'; +import { useAuthStore } from '@/stores/authStore'; + +// Mock the auth store +jest.mock('@/stores/authStore', () => ({ + useAuthStore: jest.fn(), +})); + +describe('AuthInitializer', () => { + const mockLoadAuthFromStorage = jest.fn(); + + beforeEach(() => { + jest.clearAllMocks(); + + (useAuthStore as unknown as jest.Mock).mockImplementation((selector: any) => { + const state = { + loadAuthFromStorage: mockLoadAuthFromStorage, + }; + return selector(state); + }); + }); + + describe('Initialization', () => { + it('renders nothing (null)', () => { + const { container } = render(); + + expect(container.firstChild).toBeNull(); + }); + + it('calls loadAuthFromStorage on mount', async () => { + render(); + + await waitFor(() => { + expect(mockLoadAuthFromStorage).toHaveBeenCalledTimes(1); + }); + }); + + it('does not call loadAuthFromStorage again on re-render', async () => { + const { rerender } = render(); + + await waitFor(() => { + expect(mockLoadAuthFromStorage).toHaveBeenCalledTimes(1); + }); + + // Force re-render + rerender(); + + // Should still only be called once (useEffect dependencies prevent re-call) + expect(mockLoadAuthFromStorage).toHaveBeenCalledTimes(1); + }); + }); +}); diff --git a/frontend/tests/components/layout/Footer.test.tsx b/frontend/tests/components/layout/Footer.test.tsx new file mode 100644 index 0000000..8d14eab --- /dev/null +++ b/frontend/tests/components/layout/Footer.test.tsx @@ -0,0 +1,33 @@ +/** + * Tests for Footer Component + * Verifies footer rendering and content + */ + +import { render, screen } from '@testing-library/react'; +import { Footer } from '@/components/layout/Footer'; + +describe('Footer', () => { + describe('Rendering', () => { + it('renders footer element', () => { + const { container } = render(