import React from 'react'
import { act, render } from '@testing-library/react'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import BackgroundPattern from './BackgroundPattern'
import DotCloudIcon from './DotCloudIcon'
const context = {
arc: vi.fn(),
beginPath: vi.fn(),
clearRect: vi.fn(),
closePath: vi.fn(),
drawImage: vi.fn(),
ellipse: vi.fn(),
fill: vi.fn(),
getImageData: vi.fn(() => ({ data: new Uint8ClampedArray(140 * 140 * 4) })),
lineTo: vi.fn(),
moveTo: vi.fn(),
quadraticCurveTo: vi.fn(),
scale: vi.fn(),
setTransform: vi.fn(),
}
function setReducedMotion(matches) {
vi.stubGlobal('matchMedia', vi.fn(() => ({
matches,
addEventListener: vi.fn(),
removeEventListener: vi.fn(),
})))
}
describe('canvas animation lifecycle', () => {
beforeEach(() => {
vi.spyOn(HTMLCanvasElement.prototype, 'getContext').mockReturnValue(context)
Object.defineProperty(document, 'hidden', { configurable: true, value: false })
vi.stubGlobal('requestAnimationFrame', vi.fn(() => 17))
vi.stubGlobal('cancelAnimationFrame', vi.fn())
})
afterEach(() => {
vi.restoreAllMocks()
vi.unstubAllGlobals()
})
it('does not schedule background animation with reduced motion', () => {
setReducedMotion(true)
render()
expect(requestAnimationFrame).not.toHaveBeenCalled()
})
it('cancels a scheduled background frame on unmount', () => {
setReducedMotion(false)
const { unmount } = render()
expect(requestAnimationFrame).toHaveBeenCalled()
unmount()
expect(cancelAnimationFrame).toHaveBeenCalledWith(17)
})
it('does not schedule dot animation with reduced motion', async () => {
setReducedMotion(true)
render()
await act(async () => Promise.resolve())
expect(requestAnimationFrame).not.toHaveBeenCalled()
})
})