UNPKG

@wordpress/block-library

Version:
329 lines (271 loc) 8.87 kB
/** * @jest-environment jsdom */ /** * External dependencies */ import '@testing-library/jest-dom'; /** * Internal dependencies */ import { createWaveformContainer, styleSvgIcons, setupPlayButtonAccessibility, logPlayError, } from '../waveform-utils'; // Base player data used across tests const basePlayerData = { url: 'https://example.com/song.mp3', waveformColor: 'rgba(0, 0, 0, 0.3)', progressColor: 'rgba(0, 0, 0, 0.6)', buttonColor: '#000000', }; describe( 'Waveform utilities', () => { describe( 'createWaveformContainer', () => { it( 'should create a container with required data attributes', () => { const container = createWaveformContainer( basePlayerData ); expect( container.tagName ).toBe( 'DIV' ); expect( container ).toHaveAttribute( 'data-waveform-player', '' ); expect( container ).toHaveAttribute( 'data-url', 'https://example.com/song.mp3' ); expect( container ).toHaveAttribute( 'data-height', '100' ); expect( container ).toHaveAttribute( 'data-waveform-style', 'bars' ); expect( container ).toHaveAttribute( 'data-waveform-color', 'rgba(0, 0, 0, 0.3)' ); expect( container ).toHaveAttribute( 'data-progress-color', 'rgba(0, 0, 0, 0.6)' ); expect( container ).toHaveAttribute( 'data-button-color', '#000000' ); } ); it( 'should set optional attributes when provided', () => { const container = createWaveformContainer( { ...basePlayerData, title: 'My Song', artist: 'The Artist', artwork: 'https://example.com/cover.jpg', } ); expect( container ).toHaveAttribute( 'data-title', 'My Song' ); expect( container ).toHaveAttribute( 'data-subtitle', 'The Artist' ); expect( container ).toHaveAttribute( 'data-artwork', 'https://example.com/cover.jpg' ); } ); it( 'should not set optional attributes when not provided', () => { const container = createWaveformContainer( basePlayerData ); expect( container ).not.toHaveAttribute( 'data-title' ); expect( container ).not.toHaveAttribute( 'data-subtitle' ); expect( container ).not.toHaveAttribute( 'data-artwork' ); } ); it( 'should use custom height when provided', () => { const container = createWaveformContainer( { ...basePlayerData, height: 150, } ); expect( container ).toHaveAttribute( 'data-height', '150' ); } ); } ); describe( 'styleSvgIcons', () => { it( 'should set white fill for dark button colors', () => { const container = document.createElement( 'div' ); const svg = document.createElementNS( 'http://www.w3.org/2000/svg', 'svg' ); const path = document.createElementNS( 'http://www.w3.org/2000/svg', 'path' ); svg.appendChild( path ); container.appendChild( svg ); styleSvgIcons( container, '#000000' ); expect( path ).toHaveStyle( { fill: '#ffffff' } ); } ); it( 'should set black fill for light button colors', () => { const container = document.createElement( 'div' ); const svg = document.createElementNS( 'http://www.w3.org/2000/svg', 'svg' ); const path = document.createElementNS( 'http://www.w3.org/2000/svg', 'path' ); svg.appendChild( path ); container.appendChild( svg ); styleSvgIcons( container, '#ffffff' ); expect( path ).toHaveStyle( { fill: '#000000' } ); } ); it( 'should style multiple SVG paths', () => { const container = document.createElement( 'div' ); const svg = document.createElementNS( 'http://www.w3.org/2000/svg', 'svg' ); const path1 = document.createElementNS( 'http://www.w3.org/2000/svg', 'path' ); const path2 = document.createElementNS( 'http://www.w3.org/2000/svg', 'path' ); svg.appendChild( path1 ); svg.appendChild( path2 ); container.appendChild( svg ); styleSvgIcons( container, '#000000' ); expect( path1 ).toHaveStyle( { fill: '#ffffff' } ); expect( path2 ).toHaveStyle( { fill: '#ffffff' } ); } ); it( 'should handle container with no SVG paths', () => { const container = document.createElement( 'div' ); // Should not throw. expect( () => { styleSvgIcons( container, '#000000' ); } ).not.toThrow(); } ); it( 'should use white for dark colors', () => { const container = document.createElement( 'div' ); const svg = document.createElementNS( 'http://www.w3.org/2000/svg', 'svg' ); const path = document.createElementNS( 'http://www.w3.org/2000/svg', 'path' ); svg.appendChild( path ); container.appendChild( svg ); // A dark blue color. styleSvgIcons( container, '#000080' ); expect( path ).toHaveStyle( { fill: '#ffffff' } ); } ); it( 'should use black for mid-light colors', () => { const container = document.createElement( 'div' ); const svg = document.createElementNS( 'http://www.w3.org/2000/svg', 'svg' ); const path = document.createElementNS( 'http://www.w3.org/2000/svg', 'path' ); svg.appendChild( path ); container.appendChild( svg ); // A light yellow color. styleSvgIcons( container, '#ffff00' ); expect( path ).toHaveStyle( { fill: '#000000' } ); } ); } ); describe( 'setupPlayButtonAccessibility', () => { it( 'should set aria-label to Play initially', () => { const container = document.createElement( 'div' ); const playBtn = document.createElement( 'button' ); playBtn.className = 'waveform-btn'; container.appendChild( playBtn ); setupPlayButtonAccessibility( container ); expect( playBtn ).toHaveAttribute( 'aria-label', 'Play' ); } ); it( 'should change aria-label to Pause on play event', () => { const container = document.createElement( 'div' ); const playBtn = document.createElement( 'button' ); playBtn.className = 'waveform-btn'; container.appendChild( playBtn ); setupPlayButtonAccessibility( container ); container.dispatchEvent( new CustomEvent( 'waveformplayer:play' ) ); expect( playBtn ).toHaveAttribute( 'aria-label', 'Pause' ); } ); it( 'should change aria-label back to Play on pause event', () => { const container = document.createElement( 'div' ); const playBtn = document.createElement( 'button' ); playBtn.className = 'waveform-btn'; container.appendChild( playBtn ); setupPlayButtonAccessibility( container ); container.dispatchEvent( new CustomEvent( 'waveformplayer:play' ) ); container.dispatchEvent( new CustomEvent( 'waveformplayer:pause' ) ); expect( playBtn ).toHaveAttribute( 'aria-label', 'Play' ); } ); it( 'should change aria-label back to Play on ended event', () => { const container = document.createElement( 'div' ); const playBtn = document.createElement( 'button' ); playBtn.className = 'waveform-btn'; container.appendChild( playBtn ); setupPlayButtonAccessibility( container ); container.dispatchEvent( new CustomEvent( 'waveformplayer:play' ) ); container.dispatchEvent( new CustomEvent( 'waveformplayer:ended' ) ); expect( playBtn ).toHaveAttribute( 'aria-label', 'Play' ); } ); it( 'should return cleanup function that removes listeners', () => { const container = document.createElement( 'div' ); const playBtn = document.createElement( 'button' ); playBtn.className = 'waveform-btn'; container.appendChild( playBtn ); const cleanup = setupPlayButtonAccessibility( container ); cleanup(); // After cleanup, events should not change the label. container.dispatchEvent( new CustomEvent( 'waveformplayer:play' ) ); expect( playBtn ).toHaveAttribute( 'aria-label', 'Play' ); } ); it( 'should do nothing when play button not found', () => { const container = document.createElement( 'div' ); // Should not throw. expect( () => setupPlayButtonAccessibility( container ) ).not.toThrow(); } ); } ); describe( 'logPlayError', () => { let consoleErrorSpy; beforeEach( () => { consoleErrorSpy = jest .spyOn( console, 'error' ) .mockImplementation( () => {} ); } ); afterEach( () => { consoleErrorSpy.mockRestore(); } ); it( 'should not log AbortError', () => { const abortError = new DOMException( 'Aborted', 'AbortError' ); logPlayError( abortError ); expect( consoleErrorSpy ).not.toHaveBeenCalled(); } ); it( 'should log other errors', () => { const otherError = new Error( 'Some other error' ); logPlayError( otherError ); expect( consoleErrorSpy ).toHaveBeenCalledWith( 'Playlist play error:', otherError ); } ); it( 'should log NotAllowedError', () => { const notAllowedError = new DOMException( 'Not allowed', 'NotAllowedError' ); logPlayError( notAllowedError ); expect( consoleErrorSpy ).toHaveBeenCalledWith( 'Playlist play error:', notAllowedError ); } ); } ); } );