import 'reflect-metadata'; import { SimpleChange, SimpleChanges, } from '@angular/core'; import { requiredMocks, } from './../../../test-mocks'; requiredMocks(jest); import { CanvasGuideAreaComponent, } from './canvas-guide-area.component'; import { CoordsInterface, PIGPrintGuideAreaInterface, } from '../../models'; import { BrowserDetectorService, CanvasUtilitiesService, WindowResizeEventsService, } from './../../helpers/services/index'; const initCanvasGuideAreaComponent = ( canvasUtilitiesService?: CanvasUtilitiesService, windowResizeEventsService?: WindowResizeEventsService, browserDetectorService?: BrowserDetectorService, ) => { return new CanvasGuideAreaComponent( canvasUtilitiesService, windowResizeEventsService, browserDetectorService, ); }; describe('constructor', () => { test('Sets the default guideAreaColor', () => { expect(initCanvasGuideAreaComponent().guideAreaColor).toBe('#E27B7B'); }); test('Sets the default guideAreaStrokeWidth', () => { expect(initCanvasGuideAreaComponent().guideAreaStrokeWidth).toBe(3); }); test('Sets the default guideAreaOpacity', () => { expect(initCanvasGuideAreaComponent().guideAreaOpacity).toBe(1); }); }); describe('get canvas', () => { test('Returns the canvasElement.nativeElement', () => { const canvasGuideAreaComponent = initCanvasGuideAreaComponent(); canvasGuideAreaComponent.canvasElement = { nativeElement: {}, }; expect(canvasGuideAreaComponent.canvas) .toBe(canvasGuideAreaComponent.canvasElement.nativeElement); }); }); describe('get canvasCtx', () => { test('Returns the canvas 2d context', () => { const canvasGuideAreaComponent = initCanvasGuideAreaComponent(); canvasGuideAreaComponent.canvasElement = { nativeElement: { getContext: jest.fn().mockReturnValue('testCanvasContext'), }, }; expect(canvasGuideAreaComponent.canvasCtx).toBe('testCanvasContext'); }); }); describe('ngOnChanges', () => { const runNgOnChangesTest = ({ simpleChanges = {}, }: { simpleChanges?: SimpleChanges, } = {}) => { const canvasGuideAreaComponent = initCanvasGuideAreaComponent(); canvasGuideAreaComponent.drawOnCanvas = jest.fn(); canvasGuideAreaComponent.ngOnChanges(simpleChanges); return { canvasGuideAreaComponent, }; }; // tslint:disable-next-line test('Calls drawOnCanvas if the changes do not include the printGuideArea', () => { const { canvasGuideAreaComponent, } = runNgOnChangesTest(); expect(canvasGuideAreaComponent.drawOnCanvas).toHaveBeenCalled(); }); // tslint:disable-next-line test('Calls drawOnCanvas if the changes do include the printGuideArea and it is not the first change', () => { const { canvasGuideAreaComponent, } = runNgOnChangesTest({ simpleChanges: { printGuideArea: { firstChange: false, } as SimpleChange, }, }); expect(canvasGuideAreaComponent.drawOnCanvas).toHaveBeenCalled(); }); // tslint:disable-next-line test('Does not call drawOnCanvas if the changes do include the printGuideArea but it is the first change', () => { const { canvasGuideAreaComponent, } = runNgOnChangesTest({ simpleChanges: { printGuideArea: { firstChange: true, } as SimpleChange, }, }); expect(canvasGuideAreaComponent.drawOnCanvas).not.toHaveBeenCalled(); }); }); describe('ngAfterViewInit', () => { const runNgAfterViewInitData = () => { const mockAddEvents = jest.fn(); const windowResizeEventsService = {} as WindowResizeEventsService; const browserDetectorService = {} as BrowserDetectorService; browserDetectorService.isSafari = jest.fn().mockReturnValue(false); windowResizeEventsService.addEvent = mockAddEvents; const canvasGuideAreaComponent = initCanvasGuideAreaComponent( undefined, windowResizeEventsService, browserDetectorService, ); canvasGuideAreaComponent.initCanvasSize = jest.fn(); canvasGuideAreaComponent.drawOnCanvas = jest.fn(); canvasGuideAreaComponent.ngAfterViewInit(); return { canvasGuideAreaComponent, mockAddEvents, windowResizeEventsService, }; }; test('Calls initCanvasSize once when the function is run', () => { const { canvasGuideAreaComponent, } = runNgAfterViewInitData(); expect(canvasGuideAreaComponent.initCanvasSize) .toHaveBeenCalledTimes(1); }); test('Calls drawOnCanvas once when the function is run', () => { const { canvasGuideAreaComponent, } = runNgAfterViewInitData(); expect(canvasGuideAreaComponent.drawOnCanvas) .toHaveBeenCalledTimes(1); }); test('Adds an event to the windowResizeEventsService', () => { const { windowResizeEventsService, } = runNgAfterViewInitData(); expect(windowResizeEventsService.addEvent).toHaveBeenCalled(); }); // tslint:disable-next-line test('When the windowResizeEventsService is run call initCanvasSize a second time', () => { const { canvasGuideAreaComponent, mockAddEvents, } = runNgAfterViewInitData(); mockAddEvents.mock.calls[0][0](); expect(canvasGuideAreaComponent.initCanvasSize) .toHaveBeenCalledTimes(2); }); // tslint:disable-next-line test('When the windowResizeEventsService is run, call drawOnCanvas a second time', () => { const { canvasGuideAreaComponent, mockAddEvents, } = runNgAfterViewInitData(); mockAddEvents.mock.calls[0][0](); expect(canvasGuideAreaComponent.drawOnCanvas).toHaveBeenCalledTimes(2); }); }); describe('initCanvasSize', () => { test('Sets the canvas height to the canvas offsetHeight', () => { const canvasGuideAreaComponent = initCanvasGuideAreaComponent(); canvasGuideAreaComponent.canvasElement = { nativeElement: { offsetHeight: 15, }, }; canvasGuideAreaComponent.initCanvasSize(); expect(canvasGuideAreaComponent.canvas.height).toBe(15); }); test('Sets the canvas width to the canvas offsetWidth', () => { const canvasGuideAreaComponent = initCanvasGuideAreaComponent(); canvasGuideAreaComponent.canvasElement = { nativeElement: { offsetWidth: 15, }, }; canvasGuideAreaComponent.initCanvasSize(); expect(canvasGuideAreaComponent.canvas.width).toBe(15); }); }); describe('clearCanvas', () => { const runClearCanvasTest = () => { const canvasGuideAreaComponent = initCanvasGuideAreaComponent(); const canvas = { height: 15, width: 10, } as HTMLCanvasElement; const canvasContext = {} as CanvasRenderingContext2D; canvasContext.clearRect = jest.fn(); canvas.getContext = jest.fn().mockReturnValue(canvasContext); canvasGuideAreaComponent.clearCanvas( canvas, ); return { canvas, canvasContext, canvasGuideAreaComponent, }; }; test('Get the 2d context of the canvas', () => { const { canvas, } = runClearCanvasTest(); expect(canvas.getContext).toHaveBeenCalledWith('2d'); }); test('Clears the canvas', () => { const { canvasContext, } = runClearCanvasTest(); expect(canvasContext.clearRect).toHaveBeenCalledWith( 0, 0, 10, 15, ); }); }); describe('drawOnCanvas', () => { const initDrawOnCanvasData = () => { const canvasUtilitiesService = {} as CanvasUtilitiesService; canvasUtilitiesService.getAdjustedGuideAreaPoints = jest.fn() .mockReturnValue([[{ x: 10, y: 15, }, { x: 50, y: 100, }]] as CoordsInterface[][]); const canvasGuideAreaComponent = initCanvasGuideAreaComponent( canvasUtilitiesService, ); canvasGuideAreaComponent.clearCanvas = jest.fn(); canvasGuideAreaComponent.printGuideArea = [{ heightAdjustedForNegativeBleed: 50, widthAdjustedForNegativeBleed: 100, }, {}] as PIGPrintGuideAreaInterface[]; const canvasContext = {} as CanvasRenderingContext2D; canvasContext.beginPath = jest.fn(); canvasContext.moveTo = jest.fn(); canvasContext.lineTo = jest.fn(); canvasContext.closePath = jest.fn(); canvasContext.stroke = jest.fn(); canvasGuideAreaComponent.canvasElement = { nativeElement: { getContext: jest.fn().mockReturnValue(canvasContext), height: 10, width: 15, }, }; return { canvasContext, canvasGuideAreaComponent, canvasUtilitiesService, }; }; test('Calls clearCanvas', () => { const { canvasGuideAreaComponent, } = initDrawOnCanvasData(); canvasGuideAreaComponent.drawOnCanvas(); expect(canvasGuideAreaComponent.clearCanvas) .toHaveBeenCalledWith(canvasGuideAreaComponent.canvas); }); test('Sets the canvas strokeStyle to the guideAreaColor', () => { const { canvasContext, canvasGuideAreaComponent, } = initDrawOnCanvasData(); canvasGuideAreaComponent.guideAreaColor = '#FFFFFF'; canvasGuideAreaComponent.drawOnCanvas(); expect(canvasContext.strokeStyle).toBe('#FFFFFF'); }); test('Sets the canvas lineWidth to the guideAreaStrokeWidth', () => { const { canvasContext, canvasGuideAreaComponent, } = initDrawOnCanvasData(); canvasGuideAreaComponent.guideAreaStrokeWidth = 1; canvasGuideAreaComponent.drawOnCanvas(); expect(canvasContext.lineWidth).toBe(1); }); test('Sets the canvas globalAlpha to the guideAreaOpacity', () => { const { canvasContext, canvasGuideAreaComponent, } = initDrawOnCanvasData(); canvasGuideAreaComponent.guideAreaOpacity = 0.5; canvasGuideAreaComponent.drawOnCanvas(); expect(canvasContext.globalAlpha).toBe(0.5); }); test('Calls getAdjustedGuideAreaPoints with the expected arguments', () => { const { canvasGuideAreaComponent, canvasUtilitiesService, } = initDrawOnCanvasData(); canvasGuideAreaComponent.drawOnCanvas(); expect(canvasUtilitiesService.getAdjustedGuideAreaPoints) .toHaveBeenCalledWith( canvasGuideAreaComponent.printGuideArea[0], 15, 10, 100, 50, ); }); test('Calls getAdjustedGuideAreaPoints for each printGuideArea', () => { const { canvasGuideAreaComponent, canvasUtilitiesService, } = initDrawOnCanvasData(); canvasGuideAreaComponent.drawOnCanvas(); expect(canvasUtilitiesService.getAdjustedGuideAreaPoints) .toHaveBeenCalledTimes(2); }); test('Calls closePath on the canvas context', () => { const { canvasContext, canvasGuideAreaComponent, } = initDrawOnCanvasData(); canvasGuideAreaComponent.drawOnCanvas(); expect(canvasContext.closePath).toHaveBeenCalled(); }); test('Calls stroke on the canvas context', () => { const { canvasContext, canvasGuideAreaComponent, } = initDrawOnCanvasData(); canvasGuideAreaComponent.drawOnCanvas(); expect(canvasContext.stroke).toHaveBeenCalled(); }); test('Calls beginPath for each set of points', () => { const { canvasContext, canvasGuideAreaComponent, } = initDrawOnCanvasData(); canvasGuideAreaComponent.drawOnCanvas(); expect(canvasContext.beginPath).toHaveBeenCalledTimes(2); }); test('Calls moveTo for each set of points', () => { const { canvasContext, canvasGuideAreaComponent, } = initDrawOnCanvasData(); canvasGuideAreaComponent.drawOnCanvas(); expect(canvasContext.moveTo).toHaveBeenCalledWith(10, 15); }); test('Calls lineTo for points beyond the first', () => { const { canvasContext, canvasGuideAreaComponent, } = initDrawOnCanvasData(); canvasGuideAreaComponent.drawOnCanvas(); expect(canvasContext.lineTo).toHaveBeenCalledWith(50, 100); }); test('Calls lineTo for every point beyond the first', () => { const { canvasContext, canvasGuideAreaComponent, } = initDrawOnCanvasData(); canvasGuideAreaComponent.drawOnCanvas(); expect(canvasContext.lineTo).toHaveBeenCalledTimes(2); }); });