import '@testing-library/jest-dom'; import { render } from '@testing-library/react'; import React, { useRef } from 'react'; import * as optaFn from '../replaceTeamDetails'; import { useUpdateTeamDetails } from '../useUpdateTeamDetails'; // Mock the replaceTeamDetails function jest.mock('../replaceTeamDetails', () => ({ replaceTeamDetails: jest.fn() })); describe('useUpdateTeamDetails', () => { const mockedReplaceTeamDetails = optaFn.replaceTeamDetails as jest.MockedFunction< typeof optaFn.replaceTeamDetails >; // Test component that uses the hook const UpdateTeamDetails = ({ container = 'team' }: { container?: string; }) => { const ref = useRef(null); useUpdateTeamDetails(ref, container); return (
Test Content
); }; beforeEach(() => { jest.clearAllMocks(); // Clear any existing elements with team class document.querySelectorAll('.team').forEach(el => el.remove()); }); afterEach(() => { // Clean up DOM after each test document.body.innerHTML = ''; }); // test for customised flags is currently disabled it.skip('should add team-flags class to ref element', () => { const { getByTestId } = render(); const container = getByTestId('test-container'); expect(container).toHaveClass('team-flags'); }); it('should call replaceTeamDetails with elements matching container class', () => { // Create mock DOM elements with the container class const wrapper = document.createElement('div'); for (let i = 0; i < 3; i++) { const teamElement = document.createElement('div'); teamElement.className = 'team'; teamElement.dataset.teamId = `${i}`; teamElement.innerText = `Team ${i}`; wrapper.appendChild(teamElement); } document.body.appendChild(wrapper); render(); expect(mockedReplaceTeamDetails).toHaveBeenCalledTimes(1); const calledWith = mockedReplaceTeamDetails.mock.calls[0][0]; expect(calledWith).toBeInstanceOf(HTMLCollection); expect(calledWith.length).toBe(3); }); it('should work with custom container class name', () => { // Create mock DOM elements with custom class const customElement = document.createElement('div'); customElement.className = 'custom-team-container'; customElement.innerText = 'Custom Team'; document.body.appendChild(customElement); render(); expect(mockedReplaceTeamDetails).toHaveBeenCalledTimes(1); const calledWith = mockedReplaceTeamDetails.mock.calls[0][0]; expect(calledWith.length).toBe(1); expect(calledWith[0]).toBe(customElement); }); it('should handle empty HTMLCollection when no matching elements exist', () => { // No elements with the target class exist in DOM render(); expect(mockedReplaceTeamDetails).toHaveBeenCalledTimes(1); const calledWith = mockedReplaceTeamDetails.mock.calls[0][0]; expect(calledWith).toBeInstanceOf(HTMLCollection); expect(calledWith.length).toBe(0); }); it('should not call replaceTeamDetails if ref.current is null', () => { // Test component with null ref const UpdateTeamDetailsWithNullRef = () => { const ref = useRef(null); // Don't attach ref to any element to simulate null ref useUpdateTeamDetails(ref, 'team'); return
Test Content
; }; render(); // Should still call replaceTeamDetails even if ref is null expect(mockedReplaceTeamDetails).toHaveBeenCalledTimes(1); }); it('should work with multiple team elements in DOM', () => { // Create multiple team elements similar to replaceTeamDetails test const wrapper = document.createElement('div'); const teamData = [ { id: '0', text: 'Team 0' }, { id: '1', text: 'British & Irish Lions' }, { id: '2', text: 'Quarter-Finalist' }, { id: '3', text: 'Semi-Finalist' }, { id: '4', text: 'Third Place' } ]; teamData.forEach(team => { const teamElement = document.createElement('div'); teamElement.className = 'team'; teamElement.dataset.teamId = team.id; teamElement.innerText = team.text; wrapper.appendChild(teamElement); }); document.body.appendChild(wrapper); render(); expect(mockedReplaceTeamDetails).toHaveBeenCalledTimes(1); const calledWith = mockedReplaceTeamDetails.mock.calls[0][0]; expect(calledWith.length).toBe(5); // Verify the elements have the expected structure Array.from(calledWith as HTMLCollectionOf).forEach( (element, index) => { expect(element.className).toBe('team'); expect(element.dataset.teamId).toBe(teamData[index].id); expect(element.innerText).toBe(teamData[index].text); } ); }); it('should handle DOM elements with mixed classes', () => { // Create elements with team class and additional classes const elements = [ { className: 'team primary', text: 'Primary Team' }, { className: 'team secondary active', text: 'Secondary Team' }, { className: 'other-class', text: 'Not a team' }, { className: 'team', text: 'Simple Team' } ]; elements.forEach(el => { const element = document.createElement('div'); element.className = el.className; element.innerText = el.text; document.body.appendChild(element); }); render(); const calledWith = mockedReplaceTeamDetails.mock.calls[0][0]; // Should only include elements with 'team' class (3 out of 4) expect(calledWith.length).toBe(3); }); });