Improve test coverage from 1.18% to 89.21%
- Add comprehensive test suite for api.ts service layer - Create component tests for BackToTop, ColorCell, MaterialBadge - Add tests for data modules: bambuLabColors and bambuLabColorsComplete - Include specialized tests for UI features, CRUD operations, and data consistency - Achieve 100% coverage for core components and data utilities - All 91 tests passing with robust mocking strategies
This commit is contained in:
148
__tests__/components/BackToTop.test.tsx
Normal file
148
__tests__/components/BackToTop.test.tsx
Normal file
@@ -0,0 +1,148 @@
|
||||
import React from 'react';
|
||||
import { render, fireEvent, act } from '@testing-library/react';
|
||||
import { BackToTop } from '@/src/components/BackToTop';
|
||||
|
||||
// Mock window properties
|
||||
global.scrollTo = jest.fn();
|
||||
Object.defineProperty(window, 'pageYOffset', {
|
||||
writable: true,
|
||||
configurable: true,
|
||||
value: 0,
|
||||
});
|
||||
|
||||
describe('BackToTop', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
window.pageYOffset = 0;
|
||||
});
|
||||
|
||||
it('does not render button when at top of page', () => {
|
||||
const { container } = render(<BackToTop />);
|
||||
const button = container.querySelector('button');
|
||||
expect(button).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders button when scrolled down', () => {
|
||||
const { container } = render(<BackToTop />);
|
||||
|
||||
// Simulate scroll down
|
||||
act(() => {
|
||||
window.pageYOffset = 400;
|
||||
fireEvent.scroll(window);
|
||||
});
|
||||
|
||||
const button = container.querySelector('button');
|
||||
expect(button).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('hides button when scrolled back up', () => {
|
||||
const { container } = render(<BackToTop />);
|
||||
|
||||
// Scroll down first
|
||||
act(() => {
|
||||
window.pageYOffset = 400;
|
||||
fireEvent.scroll(window);
|
||||
});
|
||||
|
||||
expect(container.querySelector('button')).toBeInTheDocument();
|
||||
|
||||
// Scroll back up
|
||||
act(() => {
|
||||
window.pageYOffset = 100;
|
||||
fireEvent.scroll(window);
|
||||
});
|
||||
|
||||
expect(container.querySelector('button')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('scrolls to top when clicked', () => {
|
||||
const { container } = render(<BackToTop />);
|
||||
|
||||
// Make button visible
|
||||
act(() => {
|
||||
window.pageYOffset = 400;
|
||||
fireEvent.scroll(window);
|
||||
});
|
||||
|
||||
const button = container.querySelector('button');
|
||||
fireEvent.click(button!);
|
||||
|
||||
expect(global.scrollTo).toHaveBeenCalledWith({
|
||||
top: 0,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
});
|
||||
|
||||
it('has correct styling when visible', () => {
|
||||
const { container } = render(<BackToTop />);
|
||||
|
||||
// Make button visible
|
||||
act(() => {
|
||||
window.pageYOffset = 400;
|
||||
fireEvent.scroll(window);
|
||||
});
|
||||
|
||||
const button = container.querySelector('button');
|
||||
|
||||
expect(button).toHaveClass('fixed');
|
||||
expect(button).toHaveClass('bottom-8');
|
||||
expect(button).toHaveClass('right-8');
|
||||
expect(button).toHaveClass('bg-blue-600');
|
||||
expect(button).toHaveClass('text-white');
|
||||
expect(button).toHaveClass('rounded-full');
|
||||
expect(button).toHaveClass('shadow-lg');
|
||||
});
|
||||
|
||||
it('has hover effect', () => {
|
||||
const { container } = render(<BackToTop />);
|
||||
|
||||
// Make button visible
|
||||
act(() => {
|
||||
window.pageYOffset = 400;
|
||||
fireEvent.scroll(window);
|
||||
});
|
||||
|
||||
const button = container.querySelector('button');
|
||||
expect(button).toHaveClass('hover:bg-blue-700');
|
||||
expect(button).toHaveClass('hover:scale-110');
|
||||
});
|
||||
|
||||
it('contains arrow icon', () => {
|
||||
const { container } = render(<BackToTop />);
|
||||
|
||||
// Make button visible
|
||||
act(() => {
|
||||
window.pageYOffset = 400;
|
||||
fireEvent.scroll(window);
|
||||
});
|
||||
|
||||
const svg = container.querySelector('svg');
|
||||
|
||||
expect(svg).toBeInTheDocument();
|
||||
expect(svg).toHaveClass('w-6');
|
||||
expect(svg).toHaveClass('h-6');
|
||||
});
|
||||
|
||||
it('has aria-label for accessibility', () => {
|
||||
const { container } = render(<BackToTop />);
|
||||
|
||||
// Make button visible
|
||||
act(() => {
|
||||
window.pageYOffset = 400;
|
||||
fireEvent.scroll(window);
|
||||
});
|
||||
|
||||
const button = container.querySelector('button');
|
||||
expect(button).toHaveAttribute('aria-label', 'Back to top');
|
||||
});
|
||||
|
||||
it('cleans up scroll listener on unmount', () => {
|
||||
const removeEventListenerSpy = jest.spyOn(window, 'removeEventListener');
|
||||
const { unmount } = render(<BackToTop />);
|
||||
|
||||
unmount();
|
||||
|
||||
expect(removeEventListenerSpy).toHaveBeenCalledWith('scroll', expect.any(Function));
|
||||
removeEventListenerSpy.mockRestore();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user