[ADF-5378] ADF Previewer: Image Rotate + Save (#6958)

* updates including cropperJS

* update on rotation + unit tests

* small fix

* hide toolbar on save

* remove unused & duplicate method

* added readonly & prettier code

* include readOnly mode to hide/show media management actions

* updated dependencies

* fix emit spy

* ADF-5378: Fix failing e2es

* Fix comments for unit tests

* ADF-5378: Removed obsolete buttons from e2e

Co-authored-by: kristian <kristian.dimitrov@alfresco.com>
Co-authored-by: adomi <ardit.domi@alfresco.com>
This commit is contained in:
Urse Daniel
2021-05-01 17:54:37 +03:00
committed by GitHub
parent 8b5e45f4eb
commit e8ffe8e35e
15 changed files with 358 additions and 374 deletions

View File

@@ -16,14 +16,13 @@
*/
import { SimpleChange } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { ContentService } from '../../services/content.service';
import { ImgViewerComponent } from './img-viewer.component';
import { setupTestBed } from '../../testing/setup-test-bed';
import { setupTestBed, CoreTestingModule } from '../../testing';
import { AppConfigService } from '@alfresco/adf-core';
import { CoreTestingModule } from '../../testing/core.testing.module';
import { TranslateModule } from '@ngx-translate/core';
import { By } from '@angular/platform-browser';
describe('Test Img viewer component ', () => {
@@ -52,218 +51,24 @@ describe('Test Img viewer component ', () => {
element = fixture.nativeElement;
component = fixture.componentInstance;
component.urlFile = 'fake-url-file.png';
component.urlFile = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==';
fixture.detectChanges();
fixture.componentInstance.ngAfterViewInit();
component.ngAfterViewInit();
fixture.detectChanges();
});
it('should display current scale as percent string', () => {
component.scaleX = 0.5;
component.scale = 0.5;
expect(component.currentScaleText).toBe('50%');
component.scaleX = 1.0;
component.scale = 1.0;
expect(component.currentScaleText).toBe('100%');
});
it('should generate transform settings', () => {
component.scaleX = 1.0;
component.scaleY = 2.0;
component.rotate = 10;
component.offsetX = 20;
component.offsetY = 30;
fixture.detectChanges();
const elementCss: any = element.querySelector('#adf-image-container');
expect(elementCss.style.transform).toBe('scale(1, 2) rotate(10deg) translate(20px, 30px)');
});
it('should start drag on mouse down', () => {
expect(component.isDragged).toBeFalsy();
component.onMouseDown(<any> new CustomEvent('mousedown'));
expect(component.isDragged).toBeTruthy();
});
it('should prevent default behaviour on mouse down', () => {
const event = jasmine.createSpyObj('mousedown', ['preventDefault']);
component.onMouseDown(event);
expect(event.preventDefault).toHaveBeenCalled();
});
it('should prevent default mouse move during drag', () => {
const event = jasmine.createSpyObj('mousemove', ['preventDefault']);
component.onMouseDown(<any> new CustomEvent('mousedown'));
component.onMouseMove(event);
expect(event.preventDefault).toHaveBeenCalled();
});
it('should not prevent default mouse move if not dragged', () => {
const event = jasmine.createSpyObj('mousemove', ['preventDefault']);
component.onMouseMove(event);
expect(component.isDragged).toBeFalsy();
expect(event.preventDefault).not.toHaveBeenCalled();
});
it('should prevent default mouse up during drag end', () => {
const event = jasmine.createSpyObj('mouseup', ['preventDefault']);
component.onMouseDown(<any> new CustomEvent('mousedown'));
expect(component.isDragged).toBeTruthy();
component.onMouseUp(event);
expect(event.preventDefault).toHaveBeenCalled();
});
it('should stop drag on mouse up', () => {
component.onMouseDown(<any> new CustomEvent('mousedown'));
expect(component.isDragged).toBeTruthy();
component.onMouseUp(<any> new CustomEvent('mouseup'));
expect(component.isDragged).toBeFalsy();
});
it('should stop drag on mouse leave', () => {
component.onMouseDown(<any> new CustomEvent('mousedown'));
expect(component.isDragged).toBeTruthy();
component.onMouseLeave(<any> new CustomEvent('mouseleave'));
expect(component.isDragged).toBeFalsy();
});
it('should stop drag on mouse out', () => {
component.onMouseDown(<any> new CustomEvent('mousedown'));
expect(component.isDragged).toBeTruthy();
component.onMouseOut(<any> new CustomEvent('mouseout'));
expect(component.isDragged).toBeFalsy();
});
it('should update offset on keydown ArrowDown event', () => {
const arrowDownEvent = new KeyboardEvent('keydown', { key : 'ArrowDown' });
component.onKeyDown(arrowDownEvent);
expect(component.offsetY).toBe(4);
component.onKeyDown(arrowDownEvent);
expect(component.offsetY).toBe(8);
});
it('should update offset on keydown ArrowUp event', () => {
const arrowUpEvent = new KeyboardEvent('keydown', { key : 'ArrowUp' });
component.onKeyDown(arrowUpEvent);
expect(component.offsetY).toBe(-4);
component.onKeyDown(arrowUpEvent);
expect(component.offsetY).toBe(-8);
});
it('should update offset on keydown ArrowLeft event', () => {
const arrowLeftEvent = new KeyboardEvent('keydown', { key : 'ArrowLeft' });
component.onKeyDown(arrowLeftEvent);
expect(component.offsetX).toBe(-4);
component.onKeyDown(arrowLeftEvent);
expect(component.offsetX).toBe(-8);
});
it('should update offset on keydown ArrowRight event', () => {
const arrowRightEvent = new KeyboardEvent('keydown', { key : 'ArrowRight' });
component.onKeyDown(arrowRightEvent);
expect(component.offsetX).toBe(4);
component.onKeyDown(arrowRightEvent);
expect(component.offsetX).toBe(8);
});
it('should update scales on zoom in', () => {
component.scaleX = 1.0;
component.zoomIn();
expect(component.scaleX).toBe(1.2);
expect(component.scaleY).toBe(1.2);
component.zoomIn();
expect(component.scaleX).toBe(1.4);
expect(component.scaleY).toBe(1.4);
});
it('should update scales on zoom out', () => {
component.scaleX = 1.0;
component.zoomOut();
expect(component.scaleX).toBe(0.8);
expect(component.scaleY).toBe(0.8);
component.zoomOut();
expect(component.scaleX).toBe(0.6);
expect(component.scaleY).toBe(0.6);
});
it('should not zoom out past 20%', () => {
component.scaleX = 0.4;
component.zoomOut();
component.zoomOut();
component.zoomOut();
expect(component.scaleX).toBe(0.2);
});
it('should update angle by 90 degrees on rotate left', () => {
component.rotate = 0;
component.rotateLeft();
expect(component.rotate).toBe(-90);
component.rotateLeft();
expect(component.rotate).toBe(-180);
});
it('should reset to 0 degrees for full rotate left round', () => {
component.rotate = -270;
component.rotateLeft();
expect(component.rotate).toBe(0);
});
it('should update angle by 90 degrees on rotate right', () => {
component.rotate = 0;
component.rotateRight();
expect(component.rotate).toBe(90);
component.rotateRight();
expect(component.rotate).toBe(180);
});
it('should reset to 0 degrees for full rotate right round', () => {
component.rotate = 270;
component.rotateRight();
expect(component.rotate).toBe(0);
});
it('should reset all image modifications', () => {
component.rotate = 10;
component.scaleX = 20;
component.scaleY = 30;
component.offsetX = 40;
component.offsetY = 50;
component.reset();
expect(component.rotate).toBe(0);
expect(component.scaleX).toBe(1.0);
expect(component.scaleY).toBe(1.0);
expect(component.offsetX).toBe(0);
expect(component.offsetY).toBe(0);
it('should define cropper after init', () => {
fixture.componentInstance.ngAfterViewInit();
expect(component.cropper).toBeDefined();
});
});
@@ -326,8 +131,7 @@ describe('Test Img viewer component ', () => {
it('should use default zoom if is not present a custom zoom in the app.config', () => {
fixture.detectChanges();
expect(component.scaleX).toBe(1.0);
expect(component.scaleY).toBe(1.0);
expect(component.scale).toBe(1.0);
});
});
@@ -344,11 +148,178 @@ describe('Test Img viewer component ', () => {
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(component.scaleX).toBe(0.70);
expect(component.scaleY).toBe(0.70);
expect(component.scale).toBe(0.70);
done();
});
});
});
});
describe('toolbar actions', () => {
beforeEach(() => {
fixture = TestBed.createComponent(ImgViewerComponent);
element = fixture.nativeElement;
component = fixture.componentInstance;
component.blobFile = createFakeBlob();
const change = new SimpleChange(null, component.blobFile, true);
component.ngOnChanges({ 'blobFile': change });
fixture.detectChanges();
});
it('should update scales on zoom in', fakeAsync(() => {
spyOn(component, 'zoomIn').and.callThrough();
spyOn(component.cropper, 'zoom');
component.scale = 1.0;
tick();
component.zoomIn();
expect(component.scale).toBe(1.2);
expect(component.cropper.zoom).toHaveBeenCalledWith(0.2);
component.zoomIn();
expect(component.scale).toBe(1.4);
expect(component.cropper.zoom).toHaveBeenCalledWith(0.2);
}));
it('should update scales on zoom out', fakeAsync(() => {
spyOn(component, 'zoomOut').and.callThrough();
spyOn(component.cropper, 'zoom');
component.scale = 1.0;
tick();
component.zoomOut();
expect(component.scale).toBe(0.8);
expect(component.cropper.zoom).toHaveBeenCalledWith(-0.2);
component.zoomOut();
expect(component.scale).toBe(0.6);
expect(component.cropper.zoom).toHaveBeenCalledWith(-0.2);
}));
it('should not zoom out past 20%', fakeAsync(() => {
component.scale = 0.2;
tick();
component.zoomOut();
component.zoomOut();
component.zoomOut();
expect(component.scale).toBe(0.2);
}));
it('should show rotate button if not in read only mode', () => {
component.readOnly = false;
fixture.detectChanges();
const rotateButtonElement = element.querySelector('#viewer-rotate-button');
expect(rotateButtonElement).not.toEqual(null);
});
it('should not show rotate button by default', () => {
const rotateButtonElement = element.querySelector('#viewer-rotate-button');
expect(rotateButtonElement).toEqual(null);
});
it('should rotate image by -90 degrees on button click', fakeAsync(() => {
component.readOnly = false;
spyOn(component, 'rotateImage').and.callThrough();
spyOn(component.cropper, 'rotate');
fixture.detectChanges();
const rotateButtonElement = fixture.debugElement.query(By.css('#viewer-rotate-button'));
rotateButtonElement.triggerEventHandler('click', null);
tick();
expect(component.rotateImage).toHaveBeenCalled();
expect(component.cropper.rotate).toHaveBeenCalledWith(-90);
}));
it('should display the second toolbar when in editing and not in read only mode', fakeAsync(() => {
component.readOnly = false;
component.isEditing = true;
fixture.detectChanges();
const secondaryToolbar = document.querySelector('.adf-secondary-toolbar');
expect(secondaryToolbar).not.toEqual(null);
}));
it('should not display the second toolbar when in read only mode', () => {
component.readOnly = true;
fixture.detectChanges();
const secondaryToolbar = document.querySelector('.adf-secondary-toolbar');
expect(secondaryToolbar).toEqual(null);
});
it('should not display the second toolbar when not in editing', () => {
component.readOnly = true;
component.isEditing = false;
fixture.detectChanges();
const secondaryToolbar = document.querySelector('.adf-secondary-toolbar');
expect(secondaryToolbar).toEqual(null);
});
it('should display second toolbar in rotate mode', fakeAsync(() => {
component.readOnly = false;
component.isEditing = true;
fixture.detectChanges();
const secondaryToolbar = document.querySelector('.adf-secondary-toolbar');
const resetButton = document.querySelector('#viewer-cancel-button');
const saveButton = document.querySelector('#viewer-save-button');
expect(secondaryToolbar).not.toEqual(null);
expect(resetButton).not.toEqual(null);
expect(saveButton).not.toEqual(null);
}));
it('should not be in editing mode by default', () => {
component.readOnly = false;
expect(component.isEditing).toEqual(false);
});
it('should get in editing mode when the image gets rotated', () => {
component.readOnly = false;
component.rotateImage();
expect(component.isEditing).toEqual(true);
});
it('should reset the scale and hide second toolbar', fakeAsync(() => {
component.readOnly = false;
component.isEditing = true;
spyOn(component, 'reset').and.callThrough();
spyOn(component.cropper, 'reset');
spyOn(component.cropper, 'zoomTo');
fixture.detectChanges();
const cancelButtonElement = fixture.debugElement.query(By.css('#viewer-cancel-button'));
cancelButtonElement.triggerEventHandler('click', null);
tick();
expect(component.reset).toHaveBeenCalled();
expect(component.scale).toEqual(1.0);
expect(component.isEditing).toEqual(false);
expect(component.cropper.reset).toHaveBeenCalled();
expect(component.cropper.zoomTo).toHaveBeenCalledWith(component.scale);
}));
it('should save when clicked on toolbar button', fakeAsync(() => {
component.readOnly = false;
component.isEditing = true;
spyOn(component, 'save');
fixture.detectChanges();
const saveButtonElement = fixture.debugElement.query(By.css('#viewer-save-button'));
saveButtonElement.triggerEventHandler('click', null);
tick();
expect(component.save).toHaveBeenCalled();
}));
});
});