diff --git a/src/file-upload/file-drop.directive.ts b/src/file-upload/file-drop.directive.ts index 6c1c4ff..b04ae51 100644 --- a/src/file-upload/file-drop.directive.ts +++ b/src/file-upload/file-drop.directive.ts @@ -1,29 +1,29 @@ import { Directive, EventEmitter, ElementRef, HostListener, Input, Output } from '@angular/core'; -import { FileUploader } from './file-uploader.class'; +import { FileUploader, FileUploaderOptions } from './file-uploader.class'; -@Directive({selector: '[ng2FileDrop]'}) +@Directive({ selector: '[ng2FileDrop]' }) export class FileDropDirective { - @Input() public uploader:FileUploader; - @Output() public fileOver:EventEmitter = new EventEmitter(); - @Output() public onFileDrop:EventEmitter = new EventEmitter(); + @Input() public uploader: FileUploader; + @Output() public fileOver: EventEmitter = new EventEmitter(); + @Output() public onFileDrop: EventEmitter = new EventEmitter(); - protected element:ElementRef; + protected element: ElementRef; - public constructor(element:ElementRef) { + public constructor(element: ElementRef) { this.element = element; } - public getOptions():any { + public getOptions(): FileUploaderOptions { return this.uploader.options; } - public getFilters():any { + public getFilters(): any { return {}; } - @HostListener('drop', ['$event']) - public onDrop(event:any):void { + @HostListener('drop', [ '$event' ]) + public onDrop(event: any): void { let transfer = this._getTransfer(event); if (!transfer) { return; @@ -37,8 +37,8 @@ export class FileDropDirective { this.onFileDrop.emit(transfer.files); } - @HostListener('dragover', ['$event']) - public onDragOver(event:any):void { + @HostListener('dragover', [ '$event' ]) + public onDragOver(event: any): void { let transfer = this._getTransfer(event); if (!this._haveFiles(transfer.types)) { return; @@ -49,10 +49,10 @@ export class FileDropDirective { this.fileOver.emit(true); } - @HostListener('dragleave', ['$event']) - public onDragLeave(event:any):any { + @HostListener('dragleave', [ '$event' ]) + public onDragLeave(event: any): any { if ((this as any).element) { - if (event.currentTarget === (this as any).element[0]) { + if (event.currentTarget === (this as any).element[ 0 ]) { return; } } @@ -61,16 +61,16 @@ export class FileDropDirective { this.fileOver.emit(false); } - protected _getTransfer(event:any):any { + protected _getTransfer(event: any): any { return event.dataTransfer ? event.dataTransfer : event.originalEvent.dataTransfer; // jQuery fix; } - protected _preventAndStop(event:any):any { + protected _preventAndStop(event: any): any { event.preventDefault(); event.stopPropagation(); } - protected _haveFiles(types:any):any { + protected _haveFiles(types: any): any { if (!types) { return false; } @@ -83,13 +83,4 @@ export class FileDropDirective { return false; } } - - /* - _addOverClass(item:any):any { - item.addOverClass(); - } - - _removeOverClass(item:any):any { - item.removeOverClass(); - }*/ } diff --git a/src/spec/file-drop.directive.spec.ts b/src/spec/file-drop.directive.spec.ts index 6b5a268..5734bd8 100644 --- a/src/spec/file-drop.directive.spec.ts +++ b/src/spec/file-drop.directive.spec.ts @@ -1,28 +1,147 @@ -import { Component } from '@angular/core'; +import { Component, DebugElement } from '@angular/core'; +import { By } from '@angular/platform-browser'; import { inject, ComponentFixture, TestBed } from '@angular/core/testing'; import { FileUploader } from '../file-upload/file-uploader.class'; import { FileUploadModule } from '../file-upload/file-upload.module'; +import { FileDropDirective } from '../file-upload/file-drop.directive'; @Component({ selector: 'container', - template: `` + template: `` }) export class ContainerComponent { - public uploader:FileUploader = new FileUploader({url: 'localhost:3000'}); + public get url(): string { return 'localhost:3000'; } + public uploader: FileUploader = new FileUploader({ url: this.url }); } describe('Directive: FileSelectDirective', () => { + let fixture: ComponentFixture; + let hostComponent: ContainerComponent; + let directiveElement: DebugElement; + let fileDropDirective: FileDropDirective; + beforeEach(() => { TestBed.configureTestingModule({ - imports: [FileUploadModule], - declarations: [ContainerComponent], - providers: [ContainerComponent] + imports: [ FileUploadModule ], + declarations: [ ContainerComponent ], + providers: [ ContainerComponent ] }); }); - it('should be fine', inject([ContainerComponent], (fixture:ComponentFixture) => { - expect(fixture).not.toBeNull(); - })); + beforeEach(() => { + fixture = TestBed.createComponent(ContainerComponent); + hostComponent = fixture.componentInstance; + + fixture.detectChanges(); + + directiveElement = fixture.debugElement.query(By.directive(FileDropDirective)); + fileDropDirective = directiveElement.injector.get(FileDropDirective) as FileDropDirective; + }); + + it('can be initialized', () => { + expect(fixture).toBeDefined(); + expect(hostComponent).toBeDefined(); + expect(fileDropDirective).toBeDefined(); + }); + + it('can set file uploader', () => { + expect(fileDropDirective.uploader).toBe(hostComponent.uploader); + }); + + it('can get uploader options', () => { + const options = fileDropDirective.getOptions(); + + // Check url set through binding + expect(options.url).toBe(hostComponent.url); + + // Check default options + expect(options.autoUpload).toBeFalsy(); + expect(options.isHTML5).toBeTruthy(); + expect(options.removeAfterUpload).toBeFalsy(); + expect(options.disableMultipart).toBeFalsy(); + }); + + it('can get filters', () => { + const filters = fileDropDirective.getFilters(); + + // TODO: Update test once implemented + expect(filters).toEqual({}); + }); + + it('handles drop event', () => { + spyOn(fileDropDirective, 'onDrop'); + + directiveElement.triggerEventHandler('drop', getFakeEvent()); + + expect(fileDropDirective.onDrop).toHaveBeenCalled(); + }); + + it('adds file to upload', () => { + spyOn(fileDropDirective.uploader, 'addToQueue'); + + let fileOverData; + fileDropDirective.fileOver.subscribe((data: any) => fileOverData = data); + + let fileDropData; + fileDropDirective.onFileDrop.subscribe((data: File[]) => fileDropData = data); + + fileDropDirective.onDrop(getFakeEvent()); + + const uploadedFiles = getFakeEvent().dataTransfer.files; + const expectedArguments = [ uploadedFiles, fileDropDirective.getOptions(), fileDropDirective.getFilters() ]; + + expect(fileDropDirective.uploader.addToQueue).toHaveBeenCalledWith(...expectedArguments); + expect(fileOverData).toBeFalsy(); + expect(fileDropData).toEqual(uploadedFiles); + }); + + it('handles dragover event', () => { + spyOn(fileDropDirective, 'onDragOver'); + + directiveElement.triggerEventHandler('dragover', getFakeEvent()); + + expect(fileDropDirective.onDragOver).toHaveBeenCalled(); + }); + + it('handles file over', () => { + let fileOverData; + fileDropDirective.fileOver.subscribe((data: any) => fileOverData = data); + + fileDropDirective.onDragOver(getFakeEvent()); + + expect(fileOverData).toBeTruthy(); + }); + + it('handles dragleave event', () => { + spyOn(fileDropDirective, 'onDragLeave'); + + directiveElement.triggerEventHandler('dragleave', getFakeEvent()); + + expect(fileDropDirective.onDragLeave).toHaveBeenCalled(); + }); + + it('handles file over leave', () => { + let fileOverData; + fileDropDirective.fileOver.subscribe((data: any) => fileOverData = data); + + fileDropDirective.onDragLeave(getFakeEvent()); + + expect(fileOverData).toBeFalsy(); + }); }); + +function getFakeEvent(): any { + return { + dataTransfer: { + files: [ 'foo.bar' ], + types: [ 'Files' ] + }, + preventDefault: () => undefined, + stopPropagation: () => undefined + } +}