import 'reflect-metadata'; import { ComponentRef, ViewContainerRef, } from '@angular/core'; import { ComponentFactoryResolver, } from '@angular/core'; import { DropZoneComponent, } from './../../../elements/drop-zone/drop-zone.component'; import { DropZoneOnDragOverDirective, } from './drop-zone-on-drag-over.directive'; const initDropZoneOnDragOverDirective = ( viewContainerRef?: ViewContainerRef, componentFactoryResolver?: ComponentFactoryResolver, ) => { return new DropZoneOnDragOverDirective( viewContainerRef, componentFactoryResolver, ); }; describe('dragover', () => { test('If beingDraggedOver is false sets beingDraggedOver to true', () => { const dropZoneOnDragOverDirective = initDropZoneOnDragOverDirective(); dropZoneOnDragOverDirective.beingDraggedOver = false; dropZoneOnDragOverDirective.addDropZoneToPage = jest.fn(); dropZoneOnDragOverDirective.dragover(); expect(dropZoneOnDragOverDirective.beingDraggedOver).toBe(true); }); test('Calls addDropZoneToPage if beingDraggedOver is false', () => { const dropZoneOnDragOverDirective = initDropZoneOnDragOverDirective(); dropZoneOnDragOverDirective.beingDraggedOver = false; dropZoneOnDragOverDirective.addDropZoneToPage = jest.fn(); dropZoneOnDragOverDirective.dragover(); expect(dropZoneOnDragOverDirective.addDropZoneToPage) .toHaveBeenCalled(); }); test('Does not call addDropZoneToPage if beingDraggedOver is true', () => { const dropZoneOnDragOverDirective = initDropZoneOnDragOverDirective(); dropZoneOnDragOverDirective.beingDraggedOver = true; dropZoneOnDragOverDirective.addDropZoneToPage = jest.fn(); dropZoneOnDragOverDirective.dragover(); expect(dropZoneOnDragOverDirective.addDropZoneToPage) .not.toHaveBeenCalled(); }); }); describe('addDropZoneToPage', () => { test('Calls resolveComponentFactory', () => { const dropZoneComponentRef = { instance: { onDragLeave: {}, onDropFiles: {}, }, location: { nativeElement: { style: {}, }, }, } as ComponentRef; const viewContainerRef = { element: { nativeElement: { appendChild: jest.fn(), }, }, } as ViewContainerRef; viewContainerRef.createComponent = jest.fn() .mockReturnValue(dropZoneComponentRef); const componentFactoryResolver = {} as ComponentFactoryResolver; componentFactoryResolver.resolveComponentFactory = jest.fn(); const dropZoneOnDragOverDirective = initDropZoneOnDragOverDirective( viewContainerRef, componentFactoryResolver, ); dropZoneOnDragOverDirective.addDropZoneToPage(); expect(componentFactoryResolver.resolveComponentFactory) .toHaveBeenCalled(); }); test('Calls viewContainerRef createComponent', () => { const dropZoneComponentRef = { instance: { onDragLeave: {}, onDropFiles: {}, }, location: { nativeElement: { style: {}, }, }, } as ComponentRef; const viewContainerRef = { element: { nativeElement: { appendChild: jest.fn(), }, }, } as ViewContainerRef; viewContainerRef.createComponent = jest.fn() .mockReturnValue(dropZoneComponentRef); const componentFactoryResolver = {} as ComponentFactoryResolver; const resolvedComponentFactory = {}; componentFactoryResolver.resolveComponentFactory = jest.fn() .mockReturnValue(resolvedComponentFactory); const dropZoneOnDragOverDirective = initDropZoneOnDragOverDirective( viewContainerRef, componentFactoryResolver, ); dropZoneOnDragOverDirective.dropZoneComponent = null; dropZoneOnDragOverDirective.addDropZoneToPage(); expect(viewContainerRef.createComponent) .toHaveBeenCalledWith(resolvedComponentFactory); }); test('Sets dropZoneComponent to the generated component ref', () => { const dropZoneComponentRef = { instance: { onDragLeave: {}, onDropFiles: {}, }, location: { nativeElement: { style: {}, }, }, } as ComponentRef; const viewContainerRef = { element: { nativeElement: { appendChild: jest.fn(), }, }, } as ViewContainerRef; viewContainerRef.createComponent = jest.fn() .mockReturnValue(dropZoneComponentRef); const componentFactoryResolver = {} as ComponentFactoryResolver; componentFactoryResolver.resolveComponentFactory = jest.fn(); const dropZoneOnDragOverDirective = initDropZoneOnDragOverDirective( viewContainerRef, componentFactoryResolver, ); dropZoneOnDragOverDirective.dropZoneComponent = null; dropZoneOnDragOverDirective.addDropZoneToPage(); expect(dropZoneOnDragOverDirective.dropZoneComponent) .toBe(dropZoneComponentRef); }); const checkSetsStyles = ({ styleName, expectedValue, }: { styleName: string, expectedValue: string | number, }) => { const dropZoneComponentRef = { instance: { onDragLeave: {}, onDropFiles: {}, }, location: { nativeElement: { style: {}, }, }, } as ComponentRef; const viewContainerRef = { element: { nativeElement: { appendChild: jest.fn(), }, }, } as ViewContainerRef; viewContainerRef.createComponent = jest.fn() .mockReturnValue(dropZoneComponentRef); const componentFactoryResolver = {} as ComponentFactoryResolver; componentFactoryResolver.resolveComponentFactory = jest.fn(); const dropZoneOnDragOverDirective = initDropZoneOnDragOverDirective( viewContainerRef, componentFactoryResolver, ); dropZoneOnDragOverDirective.dropZoneComponent = null; dropZoneOnDragOverDirective.addDropZoneToPage(); expect(dropZoneComponentRef.location.nativeElement.style[styleName]) .toBe(expectedValue); }; test('Sets the style of the added dropzone to position absolute', () => { checkSetsStyles({ expectedValue: 'absolute', styleName: 'position', }); }); test('Sets the style of the added dropzone to top 0', () => { checkSetsStyles({ expectedValue: 0, styleName: 'top', }); }); test('Sets the style of the added dropzone to left 0', () => { checkSetsStyles({ expectedValue: 0, styleName: 'left', }); }); test('Sets the style of the added dropzone to width 100%', () => { checkSetsStyles({ expectedValue: '100%', styleName: 'width', }); }); test('Sets the style of the added dropzone to height 100%', () => { checkSetsStyles({ expectedValue: '100%', styleName: 'height', }); }); test('Appends the created element to the view item', () => { const dropZoneComponentRef = { instance: { onDragLeave: {}, onDropFiles: {}, }, location: { nativeElement: { style: {}, }, }, } as ComponentRef; const viewContainerRef = { element: { nativeElement: { appendChild: jest.fn(), }, }, } as ViewContainerRef; viewContainerRef.createComponent = jest.fn() .mockReturnValue(dropZoneComponentRef); const componentFactoryResolver = {} as ComponentFactoryResolver; componentFactoryResolver.resolveComponentFactory = jest.fn(); const dropZoneOnDragOverDirective = initDropZoneOnDragOverDirective( viewContainerRef, componentFactoryResolver, ); dropZoneOnDragOverDirective.dropZoneComponent = null; dropZoneOnDragOverDirective.addDropZoneToPage(); expect(viewContainerRef.element.nativeElement.appendChild) .toHaveBeenCalledWith( dropZoneComponentRef.location.nativeElement, ); }); // tslint:disable-next-line test('Calls onDragLeave when onDragLeave is triggered on the component', () => { const dropZoneComponentRef = { instance: { onDragLeave: {}, onDropFiles: {}, }, location: { nativeElement: { style: {}, }, }, } as ComponentRef; const viewContainerRef = { element: { nativeElement: { appendChild: jest.fn(), }, }, } as ViewContainerRef; viewContainerRef.createComponent = jest.fn() .mockReturnValue(dropZoneComponentRef); const componentFactoryResolver = {} as ComponentFactoryResolver; componentFactoryResolver.resolveComponentFactory = jest.fn(); const dropZoneOnDragOverDirective = initDropZoneOnDragOverDirective( viewContainerRef, componentFactoryResolver, ); dropZoneOnDragOverDirective.dropZoneComponent = null; dropZoneOnDragOverDirective.onDragLeave = jest.fn(); dropZoneOnDragOverDirective.addDropZoneToPage(); dropZoneComponentRef.instance.onDragLeave.emit(); expect( dropZoneOnDragOverDirective.onDragLeave, ).toHaveBeenCalled(); }); // tslint:disable-next-line test('Calls onDragLeave when onDropFiles is triggered on the component', () => { const dropZoneComponentRef = { instance: { onDragLeave: {}, onDropFiles: {}, }, location: { nativeElement: { style: {}, }, }, } as ComponentRef; const viewContainerRef = { element: { nativeElement: { appendChild: jest.fn(), }, }, } as ViewContainerRef; viewContainerRef.createComponent = jest.fn() .mockReturnValue(dropZoneComponentRef); const componentFactoryResolver = {} as ComponentFactoryResolver; componentFactoryResolver.resolveComponentFactory = jest.fn(); const dropZoneOnDragOverDirective = initDropZoneOnDragOverDirective( viewContainerRef, componentFactoryResolver, ); dropZoneOnDragOverDirective.dropZoneComponent = null; dropZoneOnDragOverDirective.onDragLeave = jest.fn(); dropZoneOnDragOverDirective.addDropZoneToPage(); dropZoneComponentRef.instance.onDropFiles.emit(); expect( dropZoneOnDragOverDirective.onDragLeave, ).toHaveBeenCalled(); }); // tslint:disable-next-line test('Calls onDropFiles.emit when onDropFiles is triggered on the component', () => { const dropZoneComponentRef = { instance: { onDragLeave: {}, onDropFiles: {}, }, location: { nativeElement: { style: {}, }, }, } as ComponentRef; const viewContainerRef = { element: { nativeElement: { appendChild: jest.fn(), }, }, } as ViewContainerRef; viewContainerRef.createComponent = jest.fn() .mockReturnValue(dropZoneComponentRef); const componentFactoryResolver = {} as ComponentFactoryResolver; componentFactoryResolver.resolveComponentFactory = jest.fn(); const dropZoneOnDragOverDirective = initDropZoneOnDragOverDirective( viewContainerRef, componentFactoryResolver, ); dropZoneOnDragOverDirective.dropZoneComponent = null; dropZoneOnDragOverDirective.onDragLeave = jest.fn(); dropZoneOnDragOverDirective.onDropFiles.emit = jest.fn(); dropZoneOnDragOverDirective.addDropZoneToPage(); dropZoneComponentRef.instance.onDropFiles.emit(); expect( dropZoneOnDragOverDirective.onDropFiles.emit, ).toHaveBeenCalled(); }); }); describe('onDragLeave', () => { test('If beingDraggedOver is true sets beingDraggedOver to false', () => { const dropZoneOnDragOverDirective = initDropZoneOnDragOverDirective(); dropZoneOnDragOverDirective.beingDraggedOver = true; dropZoneOnDragOverDirective.removeDropZoneFromPage = jest.fn(); dropZoneOnDragOverDirective.onDragLeave(); expect( dropZoneOnDragOverDirective.beingDraggedOver, ).toBe(false); }); test('If beingDraggedOver is true calls removeDropZoneFromPage', () => { const dropZoneOnDragOverDirective = initDropZoneOnDragOverDirective(); dropZoneOnDragOverDirective.beingDraggedOver = true; dropZoneOnDragOverDirective.removeDropZoneFromPage = jest.fn(); dropZoneOnDragOverDirective.onDragLeave(); expect( dropZoneOnDragOverDirective.removeDropZoneFromPage, ).toHaveBeenCalled(); }); // tslint:disable-next-line test('If beingDraggedOver is false does not call removeDropZoneFromPage', () => { const dropZoneOnDragOverDirective = initDropZoneOnDragOverDirective(); dropZoneOnDragOverDirective.beingDraggedOver = false; dropZoneOnDragOverDirective.removeDropZoneFromPage = jest.fn(); dropZoneOnDragOverDirective.onDragLeave(); expect( dropZoneOnDragOverDirective.removeDropZoneFromPage, ).not.toHaveBeenCalled(); }); }); describe('removeDropZoneFromPage', () => { test('Removes the dropzone element', () => { const dropZoneOnDragOverDirective = initDropZoneOnDragOverDirective(); dropZoneOnDragOverDirective.dropZoneComponent = { location: { nativeElement: { remove: jest.fn(), }, }, } as ComponentRef; dropZoneOnDragOverDirective.removeDropZoneFromPage(); expect( dropZoneOnDragOverDirective.dropZoneComponent .location.nativeElement.remove, ).toHaveBeenCalled(); }); });