Cleaning test IMG viewer component (#4906)

* promote use setupTestbed

* fix sanatize transform img

* fix sanatize transform img
This commit is contained in:
Eugenio Romano 2019-07-08 10:21:48 +01:00 committed by GitHub
parent a4fc53a742
commit cf761ba0b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 242 additions and 290 deletions

View File

@ -1,83 +0,0 @@
---
Title: Icon Component
Added: v3.0.0
Status: Active
Last reviewed: 2019-02-08
---
# [Icon Component](../../../lib/core/icon/icon.component.ts "Defined in icon.component.ts")
Provides a universal way of rendering registered and named icons.
## Basic usage
```html
<!-- Font ligature -->
<adf-icon value="alert"></adf-icon>
<!-- ADF Thumbnail Service -->
<adf-icon value="image/png"></adf-icon>
<!-- Custom icon from MatIconRegistry -->
<adf-icon value="my-company:my-icon"></adf-icon>
```
## Class members
### Properties
| Name | Type | Default value | Description |
| ---- | ---- | ------------- | ----------- |
| color | `ThemePalette` | | Theme color palette for the component. |
| value | `string` | | Icon value, which can be either a ligature name or a custom icon in the format `[namespace]:[name]`. |
## Details
You can register custom SVG files as named icons in the format `[namespace]:[name]`.
The example below shows how to register a new icon named `adf:move_file`
that points to an external file within the `assets` folder:
```ts
import { Component, OnInit } from '@angular/core';
import { MatIconRegistry } from '@angular/material';
import { DomSanitizer } from '@angular/platform-browser';
@Component({...})
export class AppComponent implements OnInit {
constructor(
private matIconRegistry: MatIconRegistry,
private sanitizer: DomSanitizer
) {}
ngOnInit() {
this.matIconRegistry.addSvgIconInNamespace(
'adf',
'move_file',
this.sanitizer.bypassSecurityTrustResourceUrl(
'./assets/images/adf-move-file-24px.svg'
)
);
}
}
```
In the HTML, you can now use the icon as shown below:
```html
<adf-icon value="adf:move_file"></adf-icon>
```
### Thumbnail Service
You can also reference the icons registered with the [Thumbnail Service](../services/thumbnail.service.md)
using the `adf:` namespace.
```html
<adf-icon value="adf:image/gif"></adf-icon>
```
## See also
- [Thumbnail service](../services/thumbnail.service.md)

View File

@ -1,4 +1,4 @@
<div class="adf-image-container" tabindex="0" role="img" [attr.aria-label]="nameFile" [ngStyle]="{ transform: transform }" data-automation-id="adf-image-container">
<div id="adf-image-container" class="adf-image-container" tabindex="0" role="img" [attr.aria-label]="nameFile" [style.transform]="transform" data-automation-id="adf-image-container">
<img id="viewer-image" [src]="urlFile" [alt]="nameFile" [ngStyle]="{ 'cursor' : isDragged ? 'move': 'default' } " />
</div>

View File

@ -45,218 +45,248 @@ describe('Test Img viewer component ', () => {
]
});
beforeEach(() => {
service = TestBed.get(ContentService);
fixture = TestBed.createComponent(ImgViewerComponent);
describe('Url', () => {
element = fixture.nativeElement;
component = fixture.componentInstance;
fixture.detectChanges();
beforeEach(() => {
service = TestBed.get(ContentService);
fixture = TestBed.createComponent(ImgViewerComponent);
element = fixture.nativeElement;
component = fixture.componentInstance;
component.urlFile = 'fake-url-file.png';
fixture.detectChanges();
});
it('should display current scale as percent string', () => {
component.scaleX = 0.5;
expect(component.currentScaleText).toBe('50%');
component.scaleX = 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 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 display current scale as percent string', () => {
component.scaleX = 0.5;
expect(component.currentScaleText).toBe('50%');
describe('Blob', () => {
component.scaleX = 1.0;
expect(component.currentScaleText).toBe('100%');
});
beforeEach(() => {
service = TestBed.get(ContentService);
fixture = TestBed.createComponent(ImgViewerComponent);
it('should generate transform settings', () => {
component.scaleX = 1.0;
component.scaleY = 2.0;
component.rotate = 10;
component.offsetX = 20;
component.offsetY = 30;
element = fixture.nativeElement;
component = fixture.componentInstance;
fixture.detectChanges();
});
expect(component.transform).toBe('scale(1, 2) rotate(10deg) translate(20px, 30px)');
});
it('If no url or blob are passed should thrown an error', () => {
const change = new SimpleChange(null, null, true);
expect(() => {
component.ngOnChanges({ 'blobFile': change });
}).toThrow(new Error('Attribute urlFile or blobFile is required'));
});
it('should start drag on mouse down', () => {
expect(component.isDragged).toBeFalsy();
it('If url is passed should not thrown an error', () => {
component.urlFile = 'fake-url';
expect(() => {
component.ngOnChanges(null);
}).not.toThrow(new Error('Attribute urlFile or blobFile is required'));
});
component.onMouseDown(<any> new CustomEvent('mousedown'));
it('The file Name should be present in the alt attribute', () => {
component.nameFile = 'fake-name';
fixture.detectChanges();
expect(element.querySelector('#viewer-image').getAttribute('alt')).toEqual('fake-name');
});
expect(component.isDragged).toBeTruthy();
});
it('If blob is passed should not thrown an error', () => {
const blob = createFakeBlob();
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 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('If no url or blob are passed should thrown an error', () => {
const change = new SimpleChange(null, null, true);
expect(() => {
component.ngOnChanges({ 'blobFile': change });
}).toThrow(new Error('Attribute urlFile or blobFile is required'));
});
it('If url is passed should not thrown an error', () => {
component.urlFile = 'fake-url';
expect(() => {
component.ngOnChanges(null);
}).not.toThrow(new Error('Attribute urlFile or blobFile is required'));
});
it('The file Name should be present in the alt attribute', () => {
component.nameFile = 'fake-name';
fixture.detectChanges();
expect(element.querySelector('#viewer-image').getAttribute('alt')).toEqual('fake-name');
});
it('If blob is passed should not thrown an error', () => {
const blob = createFakeBlob();
spyOn(service, 'createTrustedUrl').and.returnValue('fake-blob-url');
const change = new SimpleChange(null, blob, true);
expect(() => {
component.ngOnChanges({ 'blobFile': change });
}).not.toThrow(new Error('Attribute urlFile or blobFile is required'));
expect(component.urlFile).toEqual('fake-blob-url');
spyOn(service, 'createTrustedUrl').and.returnValue('fake-blob-url');
const change = new SimpleChange(null, blob, true);
expect(() => {
component.ngOnChanges({ 'blobFile': change });
}).not.toThrow(new Error('Attribute urlFile or blobFile is required'));
expect(component.urlFile).toEqual('fake-blob-url');
});
});
describe('Zoom customization', () => {
beforeEach(() => {
service = TestBed.get(ContentService);
fixture = TestBed.createComponent(ImgViewerComponent);
element = fixture.nativeElement;
component = fixture.componentInstance;
component.urlFile = 'fake-url-file.png';
fixture.detectChanges();
});
describe('default value', () => {
it('should use default zoom if is not present a custom zoom in the app.config', () => {

View File

@ -27,6 +27,7 @@ import {
} from '@angular/core';
import { ContentService } from '../../services/content.service';
import { AppConfigService } from './../../app-config/app-config.service';
import { DomSanitizer, SafeStyle } from '@angular/platform-browser';
@Component({
selector: 'adf-img-viewer',
@ -59,8 +60,8 @@ export class ImgViewerComponent implements OnInit, OnChanges, OnDestroy {
private drag = { x: 0, y: 0 };
private delta = { x: 0, y: 0 };
get transform(): string {
return `scale(${this.scaleX}, ${this.scaleY}) rotate(${this.rotate}deg) translate(${this.offsetX}px, ${this.offsetY}px)`;
get transform(): SafeStyle {
return this.sanitizer.bypassSecurityTrustStyle(`scale(${this.scaleX}, ${this.scaleY}) rotate(${this.rotate}deg) translate(${this.offsetX}px, ${this.offsetY}px)`);
}
get currentScaleText(): string {
@ -70,6 +71,7 @@ export class ImgViewerComponent implements OnInit, OnChanges, OnDestroy {
private element: HTMLElement;
constructor(
private sanitizer: DomSanitizer,
private appConfigService: AppConfigService,
private contentService: ContentService,
private el: ElementRef) {

View File

@ -39,7 +39,10 @@ import { HttpClientModule } from '@angular/common/http';
export class TestComponent implements OnChanges {
@Input() data: any;
public onChangesCalled = 0;
ngOnChanges(changes: SimpleChanges) { this.onChangesCalled ++; }
ngOnChanges(changes: SimpleChanges) {
this.onChangesCalled++;
}
}
describe('DynamicExtensionComponent', () => {
@ -51,16 +54,16 @@ describe('DynamicExtensionComponent', () => {
beforeEach(async(() => {
componentRegister = new ComponentRegisterService();
componentRegister.setComponents({'test-component': TestComponent});
componentRegister.setComponents({ 'test-component': TestComponent });
TestBed.configureTestingModule({
imports: [ HttpClientModule ],
declarations: [ DynamicExtensionComponent, TestComponent ],
providers: [ { provide: ComponentRegisterService, useValue: componentRegister } ]
imports: [HttpClientModule],
declarations: [DynamicExtensionComponent, TestComponent],
providers: [{ provide: ComponentRegisterService, useValue: componentRegister }]
});
TestBed.overrideModule(BrowserDynamicTestingModule, {
set: { entryComponents: [ TestComponent ] }
set: { entryComponents: [TestComponent] }
});
TestBed.compileComponents();