openreplay/tracker/tracker-assist/tests/AnnotationCanvas.test.ts

149 lines
No EOL
5 KiB
TypeScript

import AnnotationCanvas from '../src/AnnotationCanvas'
import { describe, expect, test, it, jest, beforeEach, afterEach, } from '@jest/globals'
describe('AnnotationCanvas', () => {
let annotationCanvas
let documentBody
let canvasMock
let contextMock
beforeEach(() => {
canvasMock = {
width: 0,
height: 0,
style: {},
getContext: jest.fn(() => contextMock as unknown as HTMLCanvasElement),
parentNode: document,
setAttribute: jest.fn()
}
contextMock = {
globalAlpha: 1.0,
beginPath: jest.fn(),
moveTo: jest.fn(),
lineTo: jest.fn(),
lineWidth: 8,
lineCap: 'round',
lineJoin: 'round',
strokeStyle: 'red',
stroke: jest.fn(),
globalCompositeOperation: '',
fillStyle: '',
fillRect: jest.fn(),
clearRect: jest.fn(),
}
documentBody = document.body
// @ts-ignore
document['removeChild'] = (el) => jest.fn(el)
// @ts-ignore
document['createElement'] = () => canvasMock
jest.spyOn(documentBody, 'appendChild').mockImplementation(jest.fn())
jest.spyOn(documentBody, 'removeChild').mockImplementation(jest.fn())
jest.spyOn(window, 'addEventListener').mockImplementation(jest.fn())
jest.spyOn(window, 'removeEventListener').mockImplementation(jest.fn())
annotationCanvas = new AnnotationCanvas()
})
afterEach(() => {
jest.restoreAllMocks()
})
it('should create a canvas element with correct styles when initialized', () => {
const createElSpy = jest.spyOn(document, 'createElement')
annotationCanvas = new AnnotationCanvas()
expect(createElSpy).toHaveBeenCalledWith('canvas')
expect(canvasMock.style.position).toBe('fixed')
expect(canvasMock.style.left).toBe(0)
expect(canvasMock.style.top).toBe(0)
expect(canvasMock.style.pointerEvents).toBe('none')
expect(canvasMock.style.zIndex).toBe(2147483647 - 2)
})
it('should resize the canvas when calling resizeCanvas method', () => {
annotationCanvas.resizeCanvas()
expect(canvasMock.width).toBe(window.innerWidth)
expect(canvasMock.height).toBe(window.innerHeight)
})
it('should start painting and set the last position when calling start method', () => {
const position = [10, 20,]
annotationCanvas.start(position)
expect(annotationCanvas.painting).toBe(true)
expect(annotationCanvas.clrTmID).toBeNull()
expect(annotationCanvas.lastPosition).toEqual(position)
})
it('should stop painting and call fadeOut method when calling stop method', () => {
annotationCanvas.painting = true
const fadeOutSpy = jest.spyOn(annotationCanvas, 'fadeOut')
annotationCanvas.stop()
expect(annotationCanvas.painting).toBe(false)
expect(fadeOutSpy).toHaveBeenCalled()
})
it('should not stop painting or call fadeOut method when calling stop method while not painting', () => {
annotationCanvas.painting = false
const fadeOutSpy = jest.spyOn(annotationCanvas, 'fadeOut')
annotationCanvas.stop()
expect(fadeOutSpy).not.toHaveBeenCalled()
})
it('should draw a line on the canvas when calling move method', () => {
annotationCanvas.painting = true
annotationCanvas.ctx = contextMock
const initialLastPosition = [0, 0,]
const position = [10, 20,]
annotationCanvas.move(position)
expect(contextMock.globalAlpha).toBe(1.0)
expect(contextMock.beginPath).toHaveBeenCalled()
expect(contextMock.moveTo).toHaveBeenCalledWith(initialLastPosition[0], initialLastPosition[1])
expect(contextMock.lineTo).toHaveBeenCalledWith(position[0], position[1])
expect(contextMock.stroke).toHaveBeenCalled()
expect(annotationCanvas.lastPosition).toEqual(position)
})
it('should not draw a line on the canvas when calling move method while not painting', () => {
annotationCanvas.painting = false
annotationCanvas.ctx = contextMock
const position = [10, 20,]
annotationCanvas.move(position)
expect(contextMock.beginPath).not.toHaveBeenCalled()
expect(contextMock.stroke).not.toHaveBeenCalled()
expect(annotationCanvas.lastPosition).toEqual([0, 0,])
})
it('should fade out the canvas when calling fadeOut method', () => {
annotationCanvas.ctx = contextMock
jest.useFakeTimers()
const timerSpy = jest.spyOn(window, 'setTimeout')
annotationCanvas.fadeOut()
expect(timerSpy).toHaveBeenCalledTimes(2)
expect(contextMock.globalCompositeOperation).toBe('source-over')
expect(contextMock.fillStyle).toBe('rgba(255, 255, 255, 0.1)')
expect(contextMock.fillRect).toHaveBeenCalledWith(0, 0, canvasMock.width, canvasMock.height)
jest.runOnlyPendingTimers()
expect(contextMock.clearRect).toHaveBeenCalledWith(0, 0, canvasMock.width, canvasMock.height)
})
it('should remove the canvas element when calling remove method', () => {
const spyOnRemove = jest.spyOn(document, 'removeChild')
annotationCanvas.remove()
expect(spyOnRemove).toHaveBeenCalledWith(canvasMock)
expect(window.removeEventListener).toHaveBeenCalledWith('resize', annotationCanvas.resizeCanvas)
})
})