diff --git a/npm/ng-packs/jest.config.js b/npm/ng-packs/jest.config.js index 580ba0bcdf..8fabbc2a39 100644 --- a/npm/ng-packs/jest.config.js +++ b/npm/ng-packs/jest.config.js @@ -11,7 +11,7 @@ module.exports = { coverageDirectory: '/coverage', coverageReporters: ['html'], preset: 'jest-preset-angular', - setupFilesAfterEnv: ['/test-setup.ts'], + setupFilesAfterEnv: ['/test-setup.ts', 'jest-canvas-mock'], snapshotSerializers: [ 'jest-preset-angular/AngularSnapshotSerializer.js', 'jest-preset-angular/HTMLCommentSerializer.js', diff --git a/npm/ng-packs/package.json b/npm/ng-packs/package.json index 1875b16ac9..84dec91088 100644 --- a/npm/ng-packs/package.json +++ b/npm/ng-packs/package.json @@ -52,6 +52,7 @@ "font-awesome": "^4.7.0", "husky": "^3.0.9", "jest": "^24.9.0", + "jest-canvas-mock": "^2.1.2", "jest-preset-angular": "^7.1.1", "just-clone": "3.1.0", "just-compare": "^1.3.0", diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/chart/chart.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/chart/chart.component.ts index 45829c8ee4..e019840b7c 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/components/chart/chart.component.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/components/chart/chart.component.ts @@ -6,7 +6,7 @@ import { Input, OnDestroy, Output, - ChangeDetectorRef + ChangeDetectorRef, } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; import { chartJsLoaded$ } from '../../utils/widget-utils'; @@ -14,7 +14,7 @@ declare const Chart: any; @Component({ selector: 'abp-chart', - templateUrl: './chart.component.html' + templateUrl: './chart.component.html', }) export class ChartComponent implements AfterViewInit, OnDestroy { @Input() type: string; @@ -61,30 +61,33 @@ export class ChartComponent implements AfterViewInit, OnDestroy { ngAfterViewInit() { chartJsLoaded$.subscribe(() => { - try { - // tslint:disable-next-line: no-unused-expression - Chart; - } catch (error) { - console.error(`Chart is not found. Import the Chart from app.module like shown below: - import('chart.js'); - `); - return; - } + this.testChartJs(); this.initChart(); this._initialized = true; }); } + testChartJs() { + try { + // tslint:disable-next-line: no-unused-expression + Chart; + } catch (error) { + throw new Error(`Chart is not found. Import the Chart from app.module like shown below: + import('chart.js'); + `); + } + } + onCanvasClick = event => { if (this.chart) { const element = this.chart.getElementAtEvent(event); const dataset = this.chart.getDatasetAtEvent(event); - if (element && element[0] && dataset) { + if (element && element.length && dataset) { this.onDataSelect.emit({ originalEvent: event, element: element[0], - dataset + dataset, }); } } @@ -99,11 +102,11 @@ export class ChartComponent implements AfterViewInit, OnDestroy { opts.maintainAspectRatio = false; } - this.chart = new Chart(this.el.nativeElement.children[0].children[0], { + this.chart = new Chart(this.canvas, { type: this.type, data: this.data, options: this.options, - plugins: this.plugins + plugins: this.plugins, }); this.cdRef.detectChanges(); diff --git a/npm/ng-packs/packages/theme-shared/src/lib/tests/chart.component.spec.ts b/npm/ng-packs/packages/theme-shared/src/lib/tests/chart.component.spec.ts new file mode 100644 index 0000000000..b1bd0fba16 --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/tests/chart.component.spec.ts @@ -0,0 +1,126 @@ +import { createHostFactory, SpectatorHost } from '@ngneat/spectator/jest'; +import { ChartComponent } from '../components'; +import { chartJsLoaded$ } from '../utils/widget-utils'; +import { ReplaySubject } from 'rxjs'; +import * as widgetUtils from '../utils/widget-utils'; +// import 'chart.js'; +declare const Chart; + +Object.defineProperty(window, 'getComputedStyle', { + value: () => ({ + getPropertyValue: prop => { + return ''; + }, + }), +}); + +describe('ChartComponent', () => { + let spectator: SpectatorHost; + const createHost = createHostFactory({ component: ChartComponent }); + + beforeEach(() => { + (widgetUtils as any).chartJsLoaded$ = new ReplaySubject(1); + spectator = createHost('', { + hostProps: { + data: { + datasets: [ + { + data: [11], + backgroundColor: ['#FF6384'], + label: 'My dataset', + }, + ], + labels: ['Red'], + }, + }, + }); + }); + + test('should throw error when chart.js is not loaded', () => { + try { + spectator.component.testChartJs(); + } catch (error) { + expect(error.message).toContain('Chart is not found'); + } + }); + + test('should have a success class by default', async done => { + await import('chart.js'); + + chartJsLoaded$.next(); + setTimeout(() => { + expect(spectator.component.chart).toBeTruthy(); + done(); + }, 0); + }); + + describe('#reinit', () => { + it('should call the destroy method', done => { + chartJsLoaded$.next(); + const spy = jest.spyOn(spectator.component.chart, 'destroy'); + spectator.setHostInput({ + data: { + datasets: [ + { + data: [12], + label: 'My dataset', + }, + ], + labels: ['Red'], + }, + }); + spectator.detectChanges(); + setTimeout(() => { + expect(spy).toHaveBeenCalled(); + done(); + }, 0); + }); + }); + + describe('#refresh', () => { + it('should call the update method', done => { + chartJsLoaded$.next(); + const spy = jest.spyOn(spectator.component.chart, 'update'); + spectator.component.refresh(); + setTimeout(() => { + expect(spy).toHaveBeenCalled(); + done(); + }, 0); + }); + }); + + describe('#generateLegend', () => { + it('should call the generateLegend method', done => { + chartJsLoaded$.next(); + const spy = jest.spyOn(spectator.component.chart, 'generateLegend'); + spectator.component.generateLegend(); + setTimeout(() => { + expect(spy).toHaveBeenCalled(); + done(); + }, 0); + }); + }); + + describe('#onCanvasClick', () => { + it('should emit the onDataSelect', done => { + spectator.component.onDataSelect.subscribe(() => { + done(); + }); + + chartJsLoaded$.next(); + jest.spyOn(spectator.component.chart, 'getElementAtEvent').mockReturnValue([document.createElement('div')]); + spectator.click('canvas'); + }); + }); + + describe('#base64Image', () => { + it('should return the base64 image', done => { + chartJsLoaded$.next(); + + setTimeout(() => { + expect(spectator.component.base64Image).toContain('base64'); + done(); + }, 0); + }); + }); +}); diff --git a/npm/ng-packs/test-setup.ts b/npm/ng-packs/test-setup.ts index 8d88704e8f..162c24c518 100644 --- a/npm/ng-packs/test-setup.ts +++ b/npm/ng-packs/test-setup.ts @@ -1 +1,2 @@ import 'jest-preset-angular'; +import 'jest-canvas-mock';