diff --git a/cspell.json b/cspell.json index b5b5801a1e..7c331f7e70 100644 --- a/cspell.json +++ b/cspell.json @@ -145,7 +145,8 @@ "Whitespaces", "xdescribe", "xsrf", - "zestiria" + "zestiria", + "webscript" ], "dictionaries": [ "html", diff --git a/lib/core/src/lib/notifications/components/notification-history.component.html b/lib/core/src/lib/notifications/components/notification-history.component.html index 05c10a953f..aa067a1700 100644 --- a/lib/core/src/lib/notifications/components/notification-history.component.html +++ b/lib/core/src/lib/notifications/components/notification-history.component.html @@ -8,7 +8,7 @@ id="adf-notification-history-open-button" (menuOpened)="onMenuOpened()" > - + { fixture.detectChanges(); }); + afterEach(() => { + fixture.destroy(); + }); + describe('default value', () => { it('should use default zoom if is not present a custom zoom in the app.config', () => { fixture.detectChanges(); @@ -103,6 +107,10 @@ describe('Test Img viewer component ', () => { fixture.detectChanges(); }); + afterEach(() => { + fixture.destroy(); + }); + it('should display current scale as percent string', () => { component.scale = 0.5; expect(component.currentScaleText).toBe('50%'); @@ -127,6 +135,10 @@ describe('Test Img viewer component ', () => { fixture.detectChanges(); }); + afterEach(() => { + fixture.destroy(); + }); + it('should thrown an error if no url or blob are passed', () => { const change = new SimpleChange(null, null, true); expect(() => { @@ -181,6 +193,10 @@ describe('Test Img viewer component ', () => { fixture.detectChanges(); }); + afterEach(() => { + fixture.destroy(); + }); + it('should update scales on zoom in', fakeAsync(() => { spyOn(component, 'zoomIn').and.callThrough(); spyOn(component.cropper, 'zoom'); @@ -377,6 +393,10 @@ describe('Test Img viewer component ', () => { component = fixture.componentInstance; }); + afterEach(() => { + fixture.destroy(); + }); + it('should conditionally display rotate and crop buttons based on allowedEditActions', () => { component.readOnly = false; component.allowedEditActions = { rotate: true, crop: true }; @@ -401,7 +421,14 @@ describe('Test Img viewer component ', () => { fixture = TestBed.createComponent(ImgViewerComponent); testingUtils = new UnitTestingUtils(fixture.debugElement); component = fixture.componentInstance; + component.urlFile = + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='; fixture.detectChanges(); + component.ngAfterViewInit(); + }); + + afterEach(() => { + fixture.destroy(); }); it('should rotate the image when r key is pressed', () => { @@ -428,101 +455,119 @@ describe('Test Img viewer component ', () => { expect(component.zoomIn).toHaveBeenCalled(); }); - it('should move the cropper when arrow keys are pressed', () => { + it('should move the cropper when arrow keys are pressed', fakeAsync(() => { spyOn(component.cropper, 'move'); dispatchKeyboardEvent('ArrowLeft'); fixture.detectChanges(); + tick(); expect(component.cropper.move).toHaveBeenCalledWith(-3, 0); dispatchKeyboardEvent('ArrowRight'); fixture.detectChanges(); + tick(); expect(component.cropper.move).toHaveBeenCalledWith(3, 0); dispatchKeyboardEvent('ArrowUp'); fixture.detectChanges(); + tick(); expect(component.cropper.move).toHaveBeenCalledWith(0, -3); dispatchKeyboardEvent('ArrowDown'); fixture.detectChanges(); + tick(); expect(component.cropper.move).toHaveBeenCalledWith(0, 3); - }); + })); - it('should increase crop box area when arrow keys with shift are pressed', () => { + it('should increase crop box area when arrow keys with shift are pressed', fakeAsync(() => { component.cropImage(); spyOn(component.cropper, 'setCropBoxData'); let expectedCropBoxData = getExpectedCropBoxData(component.cropper, -3, 3, 0, 0); dispatchKeyboardEvent('ArrowLeft', true); fixture.detectChanges(); + tick(); expect(component.cropper.setCropBoxData).toHaveBeenCalledWith(expectedCropBoxData); expectedCropBoxData = getExpectedCropBoxData(component.cropper, 0, 3, 0, 0); dispatchKeyboardEvent('ArrowRight', true); fixture.detectChanges(); + tick(); expect(component.cropper.setCropBoxData).toHaveBeenCalledWith(expectedCropBoxData); expectedCropBoxData = getExpectedCropBoxData(component.cropper, 0, 0, -3, 3); dispatchKeyboardEvent('ArrowUp', true); fixture.detectChanges(); + tick(); expect(component.cropper.setCropBoxData).toHaveBeenCalledWith(expectedCropBoxData); expectedCropBoxData = getExpectedCropBoxData(component.cropper, 0, 0, 0, 3); dispatchKeyboardEvent('ArrowDown', true); fixture.detectChanges(); + tick(); expect(component.cropper.setCropBoxData).toHaveBeenCalledWith(expectedCropBoxData); - }); + })); - it('should decrease crop box area when arrow keys with alt are pressed', () => { + it('should decrease crop box area when arrow keys with alt are pressed', fakeAsync(() => { component.cropImage(); spyOn(component.cropper, 'setCropBoxData'); let expectedCropBoxData = getExpectedCropBoxData(component.cropper, 3, -3, 0, 0); dispatchKeyboardEvent('ArrowLeft', false, true); fixture.detectChanges(); + tick(); expect(component.cropper.setCropBoxData).toHaveBeenCalledWith(expectedCropBoxData); expectedCropBoxData = getExpectedCropBoxData(component.cropper, 0, -3, 0, 0); dispatchKeyboardEvent('ArrowRight', false, true); fixture.detectChanges(); + tick(); expect(component.cropper.setCropBoxData).toHaveBeenCalledWith(expectedCropBoxData); expectedCropBoxData = getExpectedCropBoxData(component.cropper, 0, 0, 3, -3); dispatchKeyboardEvent('ArrowUp', false, true); fixture.detectChanges(); + tick(); expect(component.cropper.setCropBoxData).toHaveBeenCalledWith(expectedCropBoxData); expectedCropBoxData = getExpectedCropBoxData(component.cropper, 0, 0, 0, -3); dispatchKeyboardEvent('ArrowDown', false, true); fixture.detectChanges(); + tick(); expect(component.cropper.setCropBoxData).toHaveBeenCalledWith(expectedCropBoxData); - }); + })); + + it('should prevent default for all arrow keys events', fakeAsync(() => { + spyOn(component.cropper, 'move'); - it('should prevent default for all arrow keys events', () => { const leftEvent = dispatchKeyboardEvent('ArrowLeft'); fixture.detectChanges(); + tick(); expect(leftEvent.preventDefault).toHaveBeenCalled(); const rightEvent = dispatchKeyboardEvent('ArrowRight'); fixture.detectChanges(); + tick(); expect(rightEvent.preventDefault).toHaveBeenCalled(); const upEvent = dispatchKeyboardEvent('ArrowUp'); fixture.detectChanges(); + tick(); expect(upEvent.preventDefault).toHaveBeenCalled(); const downEvent = dispatchKeyboardEvent('ArrowDown'); fixture.detectChanges(); + tick(); expect(downEvent.preventDefault).toHaveBeenCalled(); - }); + })); }); }); diff --git a/lib/core/src/lib/viewer/components/img-viewer/img-viewer.component.ts b/lib/core/src/lib/viewer/components/img-viewer/img-viewer.component.ts index 2e33eb48a7..f0682ed0c9 100644 --- a/lib/core/src/lib/viewer/components/img-viewer/img-viewer.component.ts +++ b/lib/core/src/lib/viewer/components/img-viewer/img-viewer.component.ts @@ -87,6 +87,9 @@ export class ImgViewerComponent implements AfterViewInit, OnChanges, OnDestroy { @HostListener('document:keyup', ['$event']) onKeyDown(event: KeyboardEvent) { + if (this.destroyed || !this.cropper) { + return; + } switch (event.key) { case 'ArrowLeft': { this.handleArrowLeftKey(event); @@ -130,6 +133,7 @@ export class ImgViewerComponent implements AfterViewInit, OnChanges, OnDestroy { scale: number = 1.0; cropper: Cropper; isEditing: boolean = false; + private destroyed: boolean = false; get currentScaleText(): string { return Math.round(this.scale * 100) + '%'; @@ -178,7 +182,11 @@ export class ImgViewerComponent implements AfterViewInit, OnChanges, OnDestroy { } ngOnDestroy() { - this.cropper.destroy(); + this.destroyed = true; + if (this.cropper) { + this.cropper.destroy(); + this.cropper = null; + } } initializeScaling() { @@ -189,11 +197,17 @@ export class ImgViewerComponent implements AfterViewInit, OnChanges, OnDestroy { } zoomIn() { + if (this.destroyed || !this.cropper) { + return; + } this.cropper.zoom(0.2); this.scale = +(this.scale + 0.2).toFixed(1); } zoomOut() { + if (this.destroyed || !this.cropper) { + return; + } if (this.scale > 0.2) { this.cropper.zoom(-0.2); this.scale = +(this.scale - 0.2).toFixed(1); @@ -201,6 +215,9 @@ export class ImgViewerComponent implements AfterViewInit, OnChanges, OnDestroy { } rotateImage() { + if (this.destroyed || !this.cropper) { + return; + } this.isEditing = true; this.cropper.rotate(-90); } diff --git a/lib/js-api/.eslintrc.json b/lib/js-api/.eslintrc.json index 0ec7a3424f..4a3a3d1d5c 100644 --- a/lib/js-api/.eslintrc.json +++ b/lib/js-api/.eslintrc.json @@ -48,7 +48,8 @@ "@typescript-eslint/consistent-type-definitions": "off", "no-redeclare": "off", "space-before-function-paren": "off", - "@typescript-eslint/no-empty-interface": "warn" + "@typescript-eslint/no-empty-interface": "warn", + "@typescript-eslint/no-explicit-any": "off" } } ] diff --git a/lib/js-api/src/superagentHttpClient.ts b/lib/js-api/src/superagentHttpClient.ts index 7871a071b4..721e408f2a 100644 --- a/lib/js-api/src/superagentHttpClient.ts +++ b/lib/js-api/src/superagentHttpClient.ts @@ -129,8 +129,7 @@ export class SuperagentHttpClient implements HttpClient { queryParams: { [key: string]: any }, headerParams: { [key: string]: any }, formParams: { [key: string]: any }, - // eslint-disable-next-line @typescript-eslint/ban-types - bodyParam: string | Object, + bodyParam: string | object, contentType: string, accept: string, responseType: string, diff --git a/lib/js-api/test/upload.spec.ts b/lib/js-api/test/upload.spec.ts index 36d8c3e649..5083b97278 100644 --- a/lib/js-api/test/upload.spec.ts +++ b/lib/js-api/test/upload.spec.ts @@ -301,21 +301,20 @@ describe('Upload', () => { uploadMock.get401Response(); - let promiseProgressOne = {}; - let promiseProgressTwo = {}; + const promises: Promise[] = []; const uploadPromise: any = uploadApi.uploadFile(file); uploadPromise.catch(() => {}); uploadPromise .once('error', () => { - promiseProgressOne = Promise.resolve('Resolving'); + promises.push(Promise.resolve('Resolving')); }) .once('unauthorized', () => { - promiseProgressTwo = Promise.resolve('Resolving'); + promises.push(Promise.resolve('Resolving')); }); - Promise.all([promiseProgressOne, promiseProgressTwo]).then(() => { + Promise.all(promises).then(() => { done(); }); });