defineSuite([ 'Widgets/Viewer/viewerDragDropMixin', 'Core/defined', 'Core/TimeInterval', 'Specs/createViewer', 'Specs/DomEventSimulator', 'Specs/pollToPromise' ], function( viewerDragDropMixin, defined, TimeInterval, createViewer, DomEventSimulator, pollToPromise) { 'use strict'; var container; var viewer; beforeEach(function() { container = document.createElement('div'); container.id = 'container'; container.style.display = 'none'; document.body.appendChild(container); //Impersonate FileReader for drag and drop tests var fakeFileReader = jasmine.createSpyObj('FileReader', ['readAsText']); fakeFileReader.readAsText = function(file) { if (defined(file.czmlString)) { this.onload({ target : { result : file.czmlString } }); } else { this.onerror({ target : { error : file.errorMessage } }); } }; spyOn(window, 'FileReader').and.returnValue(fakeFileReader); }); afterEach(function() { if (viewer && !viewer.isDestroyed()) { viewer = viewer.destroy(); } document.body.removeChild(container); }); it('mixin sets default values', function() { viewer = createViewer(container); viewer.extend(viewerDragDropMixin); expect(viewer.dropTarget).toBe(viewer.container); expect(viewer.dropEnabled).toEqual(true); expect(viewer.clearOnDrop).toEqual(true); expect(viewer.clampToGround).toEqual(true); expect(viewer.flyToOnDrop).toEqual(true); }); it('clearOnDrop defaults to true when dataSourceBrowser is not used', function() { viewer = createViewer(container, { dataSourceBrowser : false }); viewer.extend(viewerDragDropMixin); expect(viewer.clearOnDrop).toEqual(true); }); it('mixin sets option values', function() { viewer = createViewer(container); viewer.extend(viewerDragDropMixin, { dropTarget : document.body, clearOnDrop : false, clampToGround : false, flyToOnDrop: false }); expect(viewer.dropTarget).toBe(document.body); expect(viewer.dropEnabled).toEqual(true); expect(viewer.clearOnDrop).toEqual(false); expect(viewer.clampToGround).toEqual(false); expect(viewer.flyToOnDrop).toEqual(false); }); it('mixin works with dropTarget id string', function() { viewer = createViewer(container); viewer.extend(viewerDragDropMixin, { dropTarget : 'container' }); expect(viewer.dropTarget).toBe(container); }); var czml1 = [{ id : 'document', version : '1.0', clock : { interval : '2000-01-01/2001-01-01' } }, { id : 'test' }]; var czml2 = [{ id : 'document', version : '1.0', clock : { interval : '2000-01-02/2001-01-02' } }, { id : 'test2' }]; it('handleDrop processes drop event', function() { var mockEvent = { dataTransfer : { files : [{ name : 'czml1.czml', czmlString : JSON.stringify(czml1) }] }, stopPropagation : function() { }, preventDefault : function() { } }; viewer = createViewer(container); viewer.extend(viewerDragDropMixin); DomEventSimulator.fireMockEvent(viewer._handleDrop, mockEvent); return pollToPromise(function() { return viewer.dataSources.length === 1; }).then(function() { var dataSource = viewer.dataSources.get(0); var interval = TimeInterval.fromIso8601({ iso8601 : czml1[0].clock.interval }); expect(dataSource.entities.getById('test')).toBeDefined(); expect(dataSource.clock.startTime).toEqual(interval.start); expect(dataSource.clock.stopTime).toEqual(interval.stop); }); }); it('handleDrop processes drop event with multiple files', function() { var mockEvent = { dataTransfer : { files : [{ name : 'czml1.czml', czmlString : JSON.stringify(czml1) }, { name : 'czml2.czml', czmlString : JSON.stringify(czml2) }] }, stopPropagation : function() { }, preventDefault : function() { } }; viewer = createViewer(container); viewer.extend(viewerDragDropMixin); DomEventSimulator.fireMockEvent(viewer._handleDrop, mockEvent); return pollToPromise(function() { return viewer.dataSources.length === 2; }).then(function() { var source1 = viewer.dataSources.get(0); var source2 = viewer.dataSources.get(1); expect(source1.entities.getById('test')).toBeDefined(); expect(source2.entities.getById('test2')).toBeDefined(); //Interval of first file should be used. var interval = TimeInterval.fromIso8601({ iso8601 : czml1[0].clock.interval }); expect(source1.clock.startTime).toEqual(interval.start); expect(source1.clock.stopTime).toEqual(interval.stop); }); }); it('handleDrop obeys clearOnDrop', function() { var mockEvent = { dataTransfer : { files : [{ name : 'czml1.czml', czmlString : JSON.stringify(czml1) }, { name : 'czml2.czml', czmlString : JSON.stringify(czml2) }] }, stopPropagation : function() { }, preventDefault : function() { } }; viewer = createViewer(container); viewer.extend(viewerDragDropMixin); DomEventSimulator.fireMockEvent(viewer._handleDrop, mockEvent); return pollToPromise(function() { return viewer.dataSources.length === 2; }).then(function() { var source1 = viewer.dataSources.get(0); var source2 = viewer.dataSources.get(1); expect(source1.entities.getById('test')).toBeDefined(); expect(source2.entities.getById('test2')).toBeDefined(); //Interval of first file should be used. var interval = TimeInterval.fromIso8601({ iso8601 : czml1[0].clock.interval }); expect(source1.clock.startTime).toEqual(interval.start); expect(source1.clock.stopTime).toEqual(interval.stop); viewer.clearOnDrop = false; DomEventSimulator.fireMockEvent(viewer._handleDrop, mockEvent); return pollToPromise(function() { return viewer.dataSources.length === 4; }).then(function() { var source1 = viewer.dataSources.get(0); var source2 = viewer.dataSources.get(1); var source3 = viewer.dataSources.get(2); var source4 = viewer.dataSources.get(3); expect(source1.entities.getById('test')).toBeDefined(); expect(source2.entities.getById('test2')).toBeDefined(); expect(source3.entities.getById('test')).toBeDefined(); expect(source4.entities.getById('test2')).toBeDefined(); viewer.clearOnDrop = true; DomEventSimulator.fireMockEvent(viewer._handleDrop, mockEvent); return pollToPromise(function() { return viewer.dataSources.length === 2; }).then(function() { var source1 = viewer.dataSources.get(0); var source2 = viewer.dataSources.get(1); expect(source1.entities.getById('test')).toBeDefined(); expect(source2.entities.getById('test2')).toBeDefined(); //Interval of first file should be used. var interval = TimeInterval.fromIso8601({ iso8601 : czml1[0].clock.interval }); expect(source1.clock.startTime).toEqual(interval.start); expect(source1.clock.stopTime).toEqual(interval.stop); }); }); }); }); it('dropError is raised on exception', function() { var mockEvent = { dataTransfer : { files : [{ name : 'czml1.czml', czmlString : 'bad JSON' }] }, stopPropagation : function() { }, preventDefault : function() { } }; viewer = createViewer(container); viewer.extend(viewerDragDropMixin); var spyListener = jasmine.createSpy('listener'); viewer.dropError.addEventListener(spyListener); DomEventSimulator.fireMockEvent(viewer._handleDrop, mockEvent); return pollToPromise(function() { return spyListener.calls.any(); }).then(function() { expect(spyListener).toHaveBeenCalledWith(viewer, 'czml1.czml', jasmine.any(SyntaxError)); viewer.dropError.removeEventListener(spyListener); }); }); it('dropError is raised FileReader error', function() { var mockEvent = { dataTransfer : { files : [{ name : 'czml1.czml', errorMessage : 'bad JSON' }] }, stopPropagation : function() { }, preventDefault : function() { } }; viewer = createViewer(container); viewer.extend(viewerDragDropMixin); var spyListener = jasmine.createSpy('listener'); viewer.dropError.addEventListener(spyListener); DomEventSimulator.fireMockEvent(viewer._handleDrop, mockEvent); return pollToPromise(function() { return spyListener.calls.any(); }).then(function() { expect(spyListener).toHaveBeenCalledWith(viewer, mockEvent.dataTransfer.files[0].name, mockEvent.dataTransfer.files[0].errorMessage); viewer.dropError.removeEventListener(spyListener); }); }); function MockContainer() { var events = {}; this.events = events; this.addEventListener = function(name, func, bubble) { events[name] = { func : func, bubble : bubble }; }; this.removeEventListener = function(name, func, bubble) { var subscribed = events[name]; expect(subscribed.func).toBe(func); expect(subscribed.bubble).toEqual(bubble); delete events[name]; }; } it('enable/disable subscribes to provided dropTarget.', function() { var dropTarget = new MockContainer(); viewer = createViewer(container); viewer.extend(viewerDragDropMixin, { dropTarget : dropTarget }); expect(dropTarget.events.drop).toBeDefined(); expect(dropTarget.events.dragenter).toBeDefined(); expect(dropTarget.events.dragover).toBeDefined(); expect(dropTarget.events.dragexit).toBeDefined(); viewer.dropEnabled = false; expect(dropTarget.events.drop).toBeUndefined(); expect(dropTarget.events.dragenter).toBeUndefined(); expect(dropTarget.events.dragover).toBeUndefined(); expect(dropTarget.events.dragexit).toBeUndefined(); viewer.dropEnabled = true; expect(dropTarget.events.drop).toBeDefined(); expect(dropTarget.events.dragenter).toBeDefined(); expect(dropTarget.events.dragover).toBeDefined(); expect(dropTarget.events.dragexit).toBeDefined(); }); it('can set new dropTarget.', function() { var dropTarget1 = new MockContainer(); var dropTarget2 = new MockContainer(); viewer = createViewer(container); viewer.extend(viewerDragDropMixin, { dropTarget : dropTarget1 }); expect(dropTarget1.events.drop).toBeDefined(); expect(dropTarget1.events.dragenter).toBeDefined(); expect(dropTarget1.events.dragover).toBeDefined(); expect(dropTarget1.events.dragexit).toBeDefined(); viewer.dropTarget = dropTarget2; expect(dropTarget1.events.drop).toBeUndefined(); expect(dropTarget1.events.dragenter).toBeUndefined(); expect(dropTarget1.events.dragover).toBeUndefined(); expect(dropTarget1.events.dragexit).toBeUndefined(); expect(dropTarget2.events.drop).toBeDefined(); expect(dropTarget2.events.dragenter).toBeDefined(); expect(dropTarget2.events.dragover).toBeDefined(); expect(dropTarget2.events.dragexit).toBeDefined(); }); it('can set proxy.', function() { var proxy = {}; viewer = createViewer(container); viewer.extend(viewerDragDropMixin, { proxy : proxy }); expect(viewer.proxy).toBe(proxy); }); it('throws with undefined viewer', function() { expect(function() { viewerDragDropMixin(undefined); }).toThrowDeveloperError(); }); it('throws with non-existant string container', function() { viewer = createViewer(container); expect(function() { viewer.extend(viewerDragDropMixin, { dropTarget : 'doesNotExist' }); }).toThrowDeveloperError(); }); it('throws if dropTarget property already added by another mixin.', function() { viewer = createViewer(container); viewer.dropTarget = true; expect(function() { viewer.extend(viewerDragDropMixin); }).toThrowDeveloperError(); }); it('throws if dropEnabled property already added by another mixin.', function() { viewer = createViewer(container); viewer.dropEnabled = true; expect(function() { viewer.extend(viewerDragDropMixin); }).toThrowDeveloperError(); }); it('throws if dropError property already added by another mixin.', function() { viewer = createViewer(container); viewer.dropError = true; expect(function() { viewer.extend(viewerDragDropMixin); }).toThrowDeveloperError(); }); it('throws if clearOnDrop property already added by another mixin.', function() { viewer = createViewer(container); viewer.clearOnDrop = true; expect(function() { viewer.extend(viewerDragDropMixin); }).toThrowDeveloperError(); }); it('throws if flyToOnDrop property already added by another mixin.', function() { viewer = createViewer(container); viewer.flyToOnDrop = true; expect(function() { viewer.extend(viewerDragDropMixin); }).toThrowDeveloperError(); }); it('setting dropTarget to undefined throws exception', function() { viewer = createViewer(container); viewer.extend(viewerDragDropMixin); expect(function() { viewer.dropTarget = undefined; }).toThrowDeveloperError(); }); }, 'WebGL');