/***************************************************************************** * Open MCT, Copyright (c) 2014-2018, United States Government * as represented by the Administrator of the National Aeronautics and Space * Administration. All rights reserved. * * Open MCT is licensed under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0. * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. * * Open MCT includes source code licensed under additional open source * licenses. See the Open Source Licenses file (LICENSES.md) included with * this source code distribution or the Licensing information page available * at runtime from the About dialog for additional information. *****************************************************************************/ /** * DropGestureSpec. Created by vwoeltje on 11/6/14. */ define( ["../../src/gestures/DropGesture"], function (DropGesture) { // Methods to mock var JQLITE_FUNCTIONS = ["on", "off", "attr", "removeAttr", "scope"], DOMAIN_OBJECT_METHODS = ["getId", "getModel", "getCapability", "hasCapability", "useCapability"], TEST_ID = "test-id", DROP_ID = "drop-id"; describe("The drop gesture", function () { var mockDndService, mockQ, mockElement, mockDomainObject, mockPersistence, mockAction, mockEvent, mockScope, mockUnwrappedElement, mockDraggedObject, mockCompose, testModel, testRect, gesture, callbacks; function mockPromise(value) { return (value && value.then) ? value : { then: function (callback) { return mockPromise(callback(value)); } }; } beforeEach(function () { testModel = { composition: [] }; testRect = {}; mockDndService = jasmine.createSpyObj('dndService', ['getData']); mockQ = { when: mockPromise }; mockElement = jasmine.createSpyObj("element", JQLITE_FUNCTIONS); mockDomainObject = jasmine.createSpyObj("domainObject", DOMAIN_OBJECT_METHODS); mockDraggedObject = jasmine.createSpyObj("draggedObject", DOMAIN_OBJECT_METHODS); mockPersistence = jasmine.createSpyObj("persistence", ["persist"]); mockEvent = jasmine.createSpyObj("event", ["preventDefault"]); mockEvent.dataTransfer = jasmine.createSpyObj("dataTransfer", ["getData"]); mockScope = jasmine.createSpyObj("$scope", ["$broadcast"]); mockUnwrappedElement = jasmine.createSpyObj("unwrapped", ["getBoundingClientRect"]); mockAction = jasmine.createSpyObj('action', ['getActions']); mockCompose = jasmine.createSpyObj('compose', ['perform']); mockDomainObject.getId.and.returnValue(TEST_ID); mockDomainObject.getModel.and.returnValue(testModel); mockDomainObject.getCapability.and.callFake(function (c) { return { persistence: mockPersistence, action: mockAction }[c]; }); mockDomainObject.useCapability.and.returnValue(true); mockEvent.dataTransfer.getData.and.returnValue(DROP_ID); mockElement[0] = mockUnwrappedElement; mockElement.scope.and.returnValue(mockScope); mockUnwrappedElement.getBoundingClientRect.and.returnValue(testRect); mockDndService.getData.and.returnValue(mockDraggedObject); mockAction.getActions.and.returnValue([mockCompose]); gesture = new DropGesture( mockDndService, mockQ, mockElement, mockDomainObject ); // Get a reference to all callbacks registered during constructor callbacks = {}; mockElement.on.calls.all().forEach(function (call) { callbacks[call.args[0]] = call.args[1]; }); }); it("attaches dragover and drop listeners", function () { expect(callbacks.dragover).toBeDefined(); expect(callbacks.drop).toBeDefined(); }); it("removes all listeners when destroyed", function () { // Verify precondition expect(mockElement.off).not.toHaveBeenCalled(); // Destroy gesture.destroy(); // Verify all callbacks were unregistered Object.keys(callbacks).forEach(function (k) { expect(mockElement.off).toHaveBeenCalledWith(k, callbacks[k]); }); }); it("accepts data transfer and prevents default behavior on dragover", function () { expect(callbacks.dragover(mockEvent)).toEqual(false); expect(mockEvent.preventDefault).toHaveBeenCalled(); expect(mockEvent.dataTransfer.dropEffect).toBeDefined(); }); it("invokes compose on drop in edit mode", function () { // Set the mockDomainObject to have the editor capability mockDomainObject.hasCapability.and.returnValue(true); callbacks.dragover(mockEvent); expect(mockAction.getActions).toHaveBeenCalledWith({ key: 'compose', selectedObject: mockDraggedObject }); callbacks.drop(mockEvent); expect(mockCompose.perform).toHaveBeenCalled(); }); it("invokes compose on drop in browse mode for folders", function () { // Set the mockDomainObject to not have the editor capability mockDomainObject.hasCapability.and.returnValue(false); // Set the mockDomainObject to have a type of folder mockDomainObject.getModel.and.returnValue({type: 'folder'}); callbacks.dragover(mockEvent); expect(mockAction.getActions).toHaveBeenCalledWith({ key: 'compose', selectedObject: mockDraggedObject }); callbacks.drop(mockEvent); expect(mockCompose.perform).toHaveBeenCalled(); }); it("broadcasts drop position (in edit mode)", function () { // Set the mockDomainObject to have the editor capability mockDomainObject.hasCapability.and.returnValue(true); testRect.left = 42; testRect.top = 36; mockEvent.pageX = 52; mockEvent.pageY = 64; callbacks.drop(mockEvent); expect(mockScope.$broadcast).toHaveBeenCalledWith( 'mctDrop', DROP_ID, { x: 10, y: 28 } ); }); it("invokes preventDefault on drop", function () { callbacks.drop(mockEvent); expect(mockEvent.preventDefault).toHaveBeenCalled(); }); }); } );