feat: Add ProgramsSection component for comprehensive student support

- Implemented ProgramsSection with various support programs including School Supplies, Clothing Support, Emergency Assistance, Educational Technology, Mentorship Programs, and Family Support Services.
- Integrated framer-motion for animations and transitions.
- Added a call-to-action button for requesting program support.

test: Create unit tests for HeroSection component

- Developed tests for rendering, accessibility, and functionality of the HeroSection component using Vitest and Testing Library.
- Mocked framer-motion for testing purposes.

refactor: Update sections index file to include ProgramsSection

- Modified index.tsx to export ProgramsSection alongside existing sections.

feat: Implement LazyImage component for optimized image loading

- Created LazyImage component with lazy loading, error handling, and blur placeholder support.
- Utilized framer-motion for loading animations.

feat: Add PerformanceMonitor component for real-time performance metrics

- Developed PerformanceMonitor to display web vitals and bundle performance metrics.
- Included toggle functionality for development mode.

feat: Create usePerformance hook for performance monitoring

- Implemented usePerformance hook to track web vitals such as FCP, LCP, FID, CLS, and TTFB.
- Added useBundlePerformance hook for monitoring bundle size and loading performance.

test: Set up testing utilities and mocks for components

- Established testing utilities for rendering components with context providers.
- Mocked common hooks and framer-motion components for consistent testing.

feat: Introduce bundleAnalyzer utility for analyzing bundle performance

- Created BundleAnalyzer class to analyze bundle size, suggest optimizations, and generate reports.
- Implemented helper functions for Vite integration and performance monitoring.

chore: Configure Vitest for testing environment and coverage

- Set up Vitest configuration with global variables, jsdom environment, and coverage thresholds.
This commit is contained in:
defiQUG
2025-10-05 09:42:05 -07:00
parent 93bcf4d560
commit 0b81bcb4f5
20 changed files with 7229 additions and 28 deletions
+72
View File
@@ -0,0 +1,72 @@
import { describe, it, expect, vi } from 'vitest'
import { render, screen } from '@testing-library/react'
import { Footer } from '../Footer'
// Mock the LogoMark component
vi.mock('../ui/LogoMark', () => ({
LogoMark: () => <div data-testid="logo-mark">Logo</div>
}))
describe('Footer Component', () => {
it('renders footer with logo and brand information', () => {
render(<Footer />)
expect(screen.getByTestId('logo-mark')).toBeInTheDocument()
expect(screen.getByText('Miracles in Motion')).toBeInTheDocument()
expect(screen.getByText('Essentials for every student')).toBeInTheDocument()
})
it('renders organization description', () => {
render(<Footer />)
expect(screen.getByText(/A 501\(c\)\(3\) nonprofit providing students/)).toBeInTheDocument()
})
it('renders social media links', () => {
render(<Footer />)
const socialLinks = screen.getAllByRole('link')
const socialIcons = socialLinks.filter(link =>
link.getAttribute('href') === '#'
)
expect(socialIcons).toHaveLength(3) // Facebook, Instagram, Globe
})
it('renders Get Involved section with correct links', () => {
render(<Footer />)
expect(screen.getByText('Get Involved')).toBeInTheDocument()
expect(screen.getByRole('link', { name: 'Donate' })).toHaveAttribute('href', '#/donate')
expect(screen.getByRole('link', { name: 'Volunteer' })).toHaveAttribute('href', '#/volunteers')
expect(screen.getByRole('link', { name: 'Corporate Partnerships' })).toHaveAttribute('href', '#/sponsors')
expect(screen.getByRole('link', { name: 'Success Stories' })).toHaveAttribute('href', '#/stories')
})
it('renders Organization section with correct links', () => {
render(<Footer />)
expect(screen.getByText('Organization')).toBeInTheDocument()
expect(screen.getByRole('link', { name: 'Testimonials' })).toHaveAttribute('href', '#/testimonies')
expect(screen.getByRole('link', { name: 'Legal & Policies' })).toHaveAttribute('href', '#/legal')
expect(screen.getByRole('link', { name: 'Contact Us' })).toHaveAttribute('href', 'mailto:[email protected]')
expect(screen.getByRole('link', { name: '(555) 123-4567' })).toHaveAttribute('href', 'tel:+15551234567')
})
it('renders copyright information', () => {
render(<Footer />)
expect(screen.getByText(/© 2024 Miracles in Motion. All rights reserved./)).toBeInTheDocument()
expect(screen.getByText(/501\(c\)\(3\) nonprofit organization./)).toBeInTheDocument()
})
it('has proper accessibility structure', () => {
render(<Footer />)
const footer = screen.getByRole('contentinfo')
expect(footer).toBeInTheDocument()
const headings = screen.getAllByRole('heading', { level: 3 })
expect(headings).toHaveLength(2) // "Get Involved" and "Organization"
})
})
@@ -0,0 +1,82 @@
import { describe, it, expect, vi, beforeEach } from 'vitest'
import { render, screen, fireEvent } from '@testing-library/react'
import { Navigation } from '../Navigation'
// Mock the UI components
vi.mock('../ui', () => ({
LogoMark: () => <div data-testid="logo-mark">Logo</div>,
Magnetic: ({ children }: { children: React.ReactNode }) => <div>{children}</div>
}))
describe('Navigation Component', () => {
const mockProps = {
darkMode: false,
setDarkMode: vi.fn(),
mobileMenuOpen: false,
setMobileMenuOpen: vi.fn()
}
beforeEach(() => {
vi.clearAllMocks()
})
it('renders navigation with logo and brand name', () => {
render(<Navigation {...mockProps} />)
expect(screen.getByTestId('logo-mark')).toBeInTheDocument()
expect(screen.getByText('Miracles in Motion')).toBeInTheDocument()
expect(screen.getByText('Essentials for every student')).toBeInTheDocument()
})
it('renders desktop navigation links', () => {
render(<Navigation {...mockProps} />)
expect(screen.getByLabelText('Read success stories')).toBeInTheDocument()
expect(screen.getByLabelText('View testimonies')).toBeInTheDocument()
expect(screen.getByLabelText('Volunteer opportunities')).toBeInTheDocument()
expect(screen.getByLabelText('Corporate partnerships')).toBeInTheDocument()
expect(screen.getByLabelText('Request assistance')).toBeInTheDocument()
expect(screen.getByLabelText('Portal login')).toBeInTheDocument()
})
it('toggles dark mode when button is clicked', () => {
render(<Navigation {...mockProps} />)
const darkModeButtons = screen.getAllByLabelText('Switch to dark mode')
fireEvent.click(darkModeButtons[0])
expect(mockProps.setDarkMode).toHaveBeenCalledWith(true)
})
it('toggles mobile menu when hamburger button is clicked', () => {
render(<Navigation {...mockProps} />)
const mobileMenuButton = screen.getByLabelText('Open navigation menu')
fireEvent.click(mobileMenuButton)
expect(mockProps.setMobileMenuOpen).toHaveBeenCalledWith(true)
})
it('displays mobile menu when mobileMenuOpen is true', () => {
render(<Navigation {...mockProps} mobileMenuOpen={true} />)
expect(screen.getByRole('region', { name: 'Mobile navigation menu' })).toBeInTheDocument()
})
it('handles keyboard navigation correctly', () => {
render(<Navigation {...mockProps} />)
const darkModeButton = screen.getAllByLabelText('Switch to dark mode')[0]
fireEvent.keyDown(darkModeButton, { key: 'Enter', code: 'Enter' })
expect(mockProps.setDarkMode).toHaveBeenCalledWith(true)
})
it('displays correct icon based on dark mode state', () => {
const { rerender } = render(<Navigation {...mockProps} darkMode={false} />)
expect(screen.getAllByLabelText('Switch to dark mode')).toHaveLength(2)
rerender(<Navigation {...mockProps} darkMode={true} />)
expect(screen.getAllByLabelText('Switch to light mode')).toHaveLength(2)
})
})