Compare commits
	
		
			10 Commits
		
	
	
		
			readme-rel
			...
			tobiasbrow
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					cd6521db1c | ||
| 
						 | 
					cdb8652db7 | ||
| 
						 | 
					998e7b4f6a | ||
| 
						 | 
					7504d78ed2 | ||
| 
						 | 
					50af65de55 | ||
| 
						 | 
					178270e078 | ||
| 
						 | 
					e315a9546d | ||
| 
						 | 
					7ea387f54a | ||
| 
						 | 
					1fb64cb593 | ||
| 
						 | 
					ef4ac7c273 | 
@@ -188,6 +188,7 @@ define([
 | 
			
		||||
                    "name": "Remove",
 | 
			
		||||
                    "description": "Remove this object from its containing object.",
 | 
			
		||||
                    "depends": [
 | 
			
		||||
                        "dialogService",
 | 
			
		||||
                        "navigationService"
 | 
			
		||||
                    ]
 | 
			
		||||
                },
 | 
			
		||||
 
 | 
			
		||||
@@ -23,111 +23,119 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Module defining RemoveAction. Created by vwoeltje on 11/17/14.
 | 
			
		||||
 */
 | 
			
		||||
define(
 | 
			
		||||
    [],
 | 
			
		||||
    function () {
 | 
			
		||||
define([
 | 
			
		||||
    './RemoveDialog'
 | 
			
		||||
], function (
 | 
			
		||||
    RemoveDialog
 | 
			
		||||
) {
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Construct an action which will remove the provided object manifestation.
 | 
			
		||||
         * The object will be removed from its parent's composition; the parent
 | 
			
		||||
         * is looked up via the "context" capability (so this will be the
 | 
			
		||||
         * immediate ancestor by which this specific object was reached.)
 | 
			
		||||
         *
 | 
			
		||||
         * @param {DomainObject} object the object to be removed
 | 
			
		||||
         * @param {ActionContext} context the context in which this action is performed
 | 
			
		||||
         * @memberof platform/commonUI/edit
 | 
			
		||||
         * @constructor
 | 
			
		||||
         * @implements {Action}
 | 
			
		||||
    /**
 | 
			
		||||
     * Construct an action which will remove the provided object manifestation.
 | 
			
		||||
     * The object will be removed from its parent's composition; the parent
 | 
			
		||||
     * is looked up via the "context" capability (so this will be the
 | 
			
		||||
     * immediate ancestor by which this specific object was reached.)
 | 
			
		||||
     *
 | 
			
		||||
     * @param {DialogService} dialogService a service which will show the dialog
 | 
			
		||||
     * @param {NavigationService} navigationService a service that maintains the current navigation state
 | 
			
		||||
     * @param {ActionContext} context the context in which this action is performed
 | 
			
		||||
     * @memberof platform/commonUI/edit
 | 
			
		||||
     * @constructor
 | 
			
		||||
     * @implements {Action}
 | 
			
		||||
     */
 | 
			
		||||
    function RemoveAction(dialogService, navigationService, context) {
 | 
			
		||||
        this.domainObject = (context || {}).domainObject;
 | 
			
		||||
        this.dialogService = dialogService;
 | 
			
		||||
        this.navigationService = navigationService;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Perform this action.
 | 
			
		||||
     */
 | 
			
		||||
    RemoveAction.prototype.perform = function () {
 | 
			
		||||
        var dialog,
 | 
			
		||||
            dialogService = this.dialogService,
 | 
			
		||||
            domainObject = this.domainObject,
 | 
			
		||||
            navigationService = this.navigationService;
 | 
			
		||||
        /*
 | 
			
		||||
         * Check whether an object ID matches the ID of the object being
 | 
			
		||||
         * removed (used to filter a parent's composition to handle the
 | 
			
		||||
         * removal.)
 | 
			
		||||
         */
 | 
			
		||||
        function RemoveAction(navigationService, context) {
 | 
			
		||||
            this.domainObject = (context || {}).domainObject;
 | 
			
		||||
            this.navigationService = navigationService;
 | 
			
		||||
        function isNotObject(otherObjectId) {
 | 
			
		||||
            return otherObjectId !== domainObject.getId();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Perform this action.
 | 
			
		||||
         * @return {Promise} a promise which will be
 | 
			
		||||
         *         fulfilled when the action has completed.
 | 
			
		||||
        /*
 | 
			
		||||
         * Mutate a parent object such that it no longer contains the object
 | 
			
		||||
         * which is being removed.
 | 
			
		||||
         */
 | 
			
		||||
        RemoveAction.prototype.perform = function () {
 | 
			
		||||
            var navigationService = this.navigationService,
 | 
			
		||||
                domainObject = this.domainObject;
 | 
			
		||||
            /*
 | 
			
		||||
             * Check whether an object ID matches the ID of the object being
 | 
			
		||||
             * removed (used to filter a parent's composition to handle the
 | 
			
		||||
             * removal.)
 | 
			
		||||
             */
 | 
			
		||||
            function isNotObject(otherObjectId) {
 | 
			
		||||
                return otherObjectId !== domainObject.getId();
 | 
			
		||||
            }
 | 
			
		||||
        function doMutate(model) {
 | 
			
		||||
            model.composition = model.composition.filter(isNotObject);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * Mutate a parent object such that it no longer contains the object
 | 
			
		||||
             * which is being removed.
 | 
			
		||||
             */
 | 
			
		||||
            function doMutate(model) {
 | 
			
		||||
                model.composition = model.composition.filter(isNotObject);
 | 
			
		||||
            }
 | 
			
		||||
        /*
 | 
			
		||||
         * Checks current object and ascendants of current
 | 
			
		||||
         * object with object being removed, if the current
 | 
			
		||||
         * object or any in the current object's path is being removed,
 | 
			
		||||
         * navigate back to parent of removed object.
 | 
			
		||||
         */
 | 
			
		||||
        function checkObjectNavigation(object, parentObject) {
 | 
			
		||||
            // Traverse object starts at current location
 | 
			
		||||
            var traverseObject = (navigationService).getNavigation(),
 | 
			
		||||
                context;
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * Checks current object and ascendants of current
 | 
			
		||||
             * object with object being removed, if the current
 | 
			
		||||
             * object or any in the current object's path is being removed,
 | 
			
		||||
             * navigate back to parent of removed object.
 | 
			
		||||
             */
 | 
			
		||||
            function checkObjectNavigation(object, parentObject) {
 | 
			
		||||
                // Traverse object starts at current location
 | 
			
		||||
                var traverseObject = (navigationService).getNavigation(),
 | 
			
		||||
                    context;
 | 
			
		||||
 | 
			
		||||
                // Stop when object is not defined (above ROOT)
 | 
			
		||||
                while (traverseObject) {
 | 
			
		||||
                    // If object currently traversed to is object being removed
 | 
			
		||||
                    // navigate to parent of current object and then exit loop
 | 
			
		||||
                    if (traverseObject.getId() === object.getId()) {
 | 
			
		||||
                        navigationService.setNavigation(parentObject);
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                    // Traverses to parent of current object, moving
 | 
			
		||||
                    // up the ascendant path
 | 
			
		||||
                    context = traverseObject.getCapability('context');
 | 
			
		||||
                    traverseObject = context && context.getParent();
 | 
			
		||||
            // Stop when object is not defined (above ROOT)
 | 
			
		||||
            while (traverseObject) {
 | 
			
		||||
                // If object currently traversed to is object being removed
 | 
			
		||||
                // navigate to parent of current object and then exit loop
 | 
			
		||||
                if (traverseObject.getId() === object.getId()) {
 | 
			
		||||
                    navigationService.setNavigation(parentObject);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                // Traverses to parent of current object, moving
 | 
			
		||||
                // up the ascendant path
 | 
			
		||||
                context = traverseObject.getCapability('context');
 | 
			
		||||
                traverseObject = context && context.getParent();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
             * Remove the object from its parent, as identified by its context
 | 
			
		||||
             * capability. Based on object's location and selected object's location
 | 
			
		||||
             * user may be navigated to existing parent object
 | 
			
		||||
             */
 | 
			
		||||
            function removeFromContext(object) {
 | 
			
		||||
                var contextCapability = object.getCapability('context'),
 | 
			
		||||
                    parent = contextCapability.getParent();
 | 
			
		||||
        /*
 | 
			
		||||
         * Remove the object from its parent, as identified by its context
 | 
			
		||||
         * capability. Based on object's location and selected object's location
 | 
			
		||||
         * user may be navigated to existing parent object
 | 
			
		||||
         */
 | 
			
		||||
        function removeFromContext(object) {
 | 
			
		||||
            var contextCapability = object.getCapability('context'),
 | 
			
		||||
                parent = contextCapability.getParent();
 | 
			
		||||
 | 
			
		||||
                // If currently within path of removed object(s),
 | 
			
		||||
                // navigates to existing object up tree
 | 
			
		||||
                checkObjectNavigation(object, parent);
 | 
			
		||||
            // If currently within path of removed object(s),
 | 
			
		||||
            // navigates to existing object up tree
 | 
			
		||||
            checkObjectNavigation(object, parent);
 | 
			
		||||
 | 
			
		||||
                return parent.useCapability('mutation', doMutate);
 | 
			
		||||
            }
 | 
			
		||||
            return parent.useCapability('mutation', doMutate);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
            return removeFromContext(domainObject);
 | 
			
		||||
        };
 | 
			
		||||
        /*
 | 
			
		||||
         * Pass in the function to remove the domain object so it can be
 | 
			
		||||
         * associated with an 'OK' button press
 | 
			
		||||
         */
 | 
			
		||||
        dialog = new RemoveDialog(dialogService, domainObject, removeFromContext);
 | 
			
		||||
        dialog.show();
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
        // Object needs to have a parent for Remove to be applicable
 | 
			
		||||
        RemoveAction.appliesTo = function (context) {
 | 
			
		||||
            var object = (context || {}).domainObject,
 | 
			
		||||
                contextCapability = object && object.getCapability("context"),
 | 
			
		||||
                parent = contextCapability && contextCapability.getParent(),
 | 
			
		||||
                parentType = parent && parent.getCapability('type'),
 | 
			
		||||
                parentCreatable = parentType && parentType.hasFeature('creation');
 | 
			
		||||
    // Object needs to have a parent for Remove to be applicable
 | 
			
		||||
    RemoveAction.appliesTo = function (context) {
 | 
			
		||||
        var object = (context || {}).domainObject,
 | 
			
		||||
            contextCapability = object && object.getCapability("context"),
 | 
			
		||||
            parent = contextCapability && contextCapability.getParent(),
 | 
			
		||||
            parentType = parent && parent.getCapability('type'),
 | 
			
		||||
            parentCreatable = parentType && parentType.hasFeature('creation');
 | 
			
		||||
 | 
			
		||||
            // Only creatable types should be modifiable
 | 
			
		||||
            return parent !== undefined &&
 | 
			
		||||
                    Array.isArray(parent.getModel().composition) &&
 | 
			
		||||
                    parentCreatable;
 | 
			
		||||
        };
 | 
			
		||||
        // Only creatable types should be modifiable
 | 
			
		||||
        return parent !== undefined &&
 | 
			
		||||
                Array.isArray(parent.getModel().composition) &&
 | 
			
		||||
                parentCreatable;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
        return RemoveAction;
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
    return RemoveAction;
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										77
									
								
								platform/commonUI/edit/src/actions/RemoveDialog.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								platform/commonUI/edit/src/actions/RemoveDialog.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,77 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT, Copyright (c) 2014-2017, 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.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
define([], function () {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @callback removeCallback
 | 
			
		||||
     * @param {DomainObject} domainObject the domain object to be removed
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Construct a new Remove dialog.
 | 
			
		||||
     *
 | 
			
		||||
     * @param {DialogService} dialogService the service that shows the dialog
 | 
			
		||||
     * @param {DomainObject} domainObject the domain object to be removed
 | 
			
		||||
     * @param {removeCallback} removeCallback callback that handles removal of the domain object
 | 
			
		||||
     * @memberof platform/commonUI/edit
 | 
			
		||||
     * @constructor
 | 
			
		||||
     */
 | 
			
		||||
    function RemoveDialog(dialogService, domainObject, removeCallback) {
 | 
			
		||||
        this.dialogService = dialogService;
 | 
			
		||||
        this.domainObject = domainObject;
 | 
			
		||||
        this.removeCallback = removeCallback;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Display a dialog to confirm the removal of a domain object.
 | 
			
		||||
     */
 | 
			
		||||
    RemoveDialog.prototype.show = function () {
 | 
			
		||||
        var dialog,
 | 
			
		||||
            domainObject = this.domainObject,
 | 
			
		||||
            removeCallback = this.removeCallback,
 | 
			
		||||
            model = {
 | 
			
		||||
                title: 'Remove ' + domainObject.getModel().name,
 | 
			
		||||
                actionText: 'Warning! This action will permanently remove this object. Are you sure you want to continue?',
 | 
			
		||||
                severity: 'alert',
 | 
			
		||||
                primaryOption: {
 | 
			
		||||
                    label: 'OK',
 | 
			
		||||
                    callback: function () {
 | 
			
		||||
                        removeCallback(domainObject);
 | 
			
		||||
                        dialog.dismiss();
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                options: [
 | 
			
		||||
                    {
 | 
			
		||||
                        label: 'Cancel',
 | 
			
		||||
                        callback: function () {
 | 
			
		||||
                            dialog.dismiss();
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                ]
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
        dialog = this.dialogService.showBlockingMessage(model);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return RemoveDialog;
 | 
			
		||||
});
 | 
			
		||||
@@ -25,50 +25,37 @@ define(
 | 
			
		||||
    function (RemoveAction) {
 | 
			
		||||
 | 
			
		||||
        describe("The Remove action", function () {
 | 
			
		||||
            var mockQ,
 | 
			
		||||
                mockNavigationService,
 | 
			
		||||
                mockDomainObject,
 | 
			
		||||
                mockParent,
 | 
			
		||||
                mockChildObject,
 | 
			
		||||
                mockGrandchildObject,
 | 
			
		||||
                mockRootObject,
 | 
			
		||||
                mockContext,
 | 
			
		||||
                mockChildContext,
 | 
			
		||||
                mockGrandchildContext,
 | 
			
		||||
                mockRootContext,
 | 
			
		||||
                mockMutation,
 | 
			
		||||
                mockType,
 | 
			
		||||
            var action,
 | 
			
		||||
                actionContext,
 | 
			
		||||
                model,
 | 
			
		||||
                capabilities,
 | 
			
		||||
                action;
 | 
			
		||||
 | 
			
		||||
            function mockPromise(value) {
 | 
			
		||||
                return {
 | 
			
		||||
                    then: function (callback) {
 | 
			
		||||
                        return mockPromise(callback(value));
 | 
			
		||||
                    }
 | 
			
		||||
                };
 | 
			
		||||
            }
 | 
			
		||||
                mockContext,
 | 
			
		||||
                mockDialogService,
 | 
			
		||||
                mockDomainObject,
 | 
			
		||||
                mockMutation,
 | 
			
		||||
                mockNavigationService,
 | 
			
		||||
                mockParent,
 | 
			
		||||
                mockType,
 | 
			
		||||
                model;
 | 
			
		||||
 | 
			
		||||
            beforeEach(function () {
 | 
			
		||||
                mockDomainObject = jasmine.createSpyObj(
 | 
			
		||||
                    "domainObject",
 | 
			
		||||
                    ["getId", "getCapability"]
 | 
			
		||||
                    ["getId", "getCapability", "getModel"]
 | 
			
		||||
                );
 | 
			
		||||
                mockChildObject = jasmine.createSpyObj(
 | 
			
		||||
                    "domainObject",
 | 
			
		||||
                    ["getId", "getCapability"]
 | 
			
		||||
                );
 | 
			
		||||
                mockGrandchildObject = jasmine.createSpyObj(
 | 
			
		||||
                    "domainObject",
 | 
			
		||||
                    ["getId", "getCapability"]
 | 
			
		||||
                );
 | 
			
		||||
                mockRootObject = jasmine.createSpyObj(
 | 
			
		||||
                    "domainObject",
 | 
			
		||||
                    ["getId", "getCapability"]
 | 
			
		||||
                );
 | 
			
		||||
                mockQ = { when: mockPromise };
 | 
			
		||||
 | 
			
		||||
                mockMutation = jasmine.createSpyObj("mutation", ["invoke"]);
 | 
			
		||||
                mockType = jasmine.createSpyObj("type", ["hasFeature"]);
 | 
			
		||||
                mockType.hasFeature.and.returnValue(true);
 | 
			
		||||
 | 
			
		||||
                capabilities = {
 | 
			
		||||
                    mutation: mockMutation,
 | 
			
		||||
                    type: mockType
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                model = {
 | 
			
		||||
                    composition: ["a", "test", "b"]
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                mockParent = {
 | 
			
		||||
                    getModel: function () {
 | 
			
		||||
                        return model;
 | 
			
		||||
@@ -80,12 +67,12 @@ define(
 | 
			
		||||
                        return capabilities[k].invoke(v);
 | 
			
		||||
                    }
 | 
			
		||||
                };
 | 
			
		||||
                mockContext = jasmine.createSpyObj("context", ["getParent"]);
 | 
			
		||||
                mockChildContext = jasmine.createSpyObj("context", ["getParent"]);
 | 
			
		||||
                mockGrandchildContext = jasmine.createSpyObj("context", ["getParent"]);
 | 
			
		||||
                mockRootContext = jasmine.createSpyObj("context", ["getParent"]);
 | 
			
		||||
                mockMutation = jasmine.createSpyObj("mutation", ["invoke"]);
 | 
			
		||||
                mockType = jasmine.createSpyObj("type", ["hasFeature"]);
 | 
			
		||||
 | 
			
		||||
                mockDialogService = jasmine.createSpyObj(
 | 
			
		||||
                    "dialogService",
 | 
			
		||||
                    ["showBlockingMessage"]
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
                mockNavigationService = jasmine.createSpyObj(
 | 
			
		||||
                    "navigationService",
 | 
			
		||||
                    [
 | 
			
		||||
@@ -97,23 +84,19 @@ define(
 | 
			
		||||
                );
 | 
			
		||||
                mockNavigationService.getNavigation.and.returnValue(mockDomainObject);
 | 
			
		||||
 | 
			
		||||
                mockContext = jasmine.createSpyObj("context", ["getParent"]);
 | 
			
		||||
                mockContext.getParent.and.returnValue(mockParent);
 | 
			
		||||
 | 
			
		||||
                mockDomainObject.getId.and.returnValue("test");
 | 
			
		||||
                mockDomainObject.getCapability.and.returnValue(mockContext);
 | 
			
		||||
                mockDomainObject.getModel.and.returnValue({name: 'test object'});
 | 
			
		||||
 | 
			
		||||
                mockContext.getParent.and.returnValue(mockParent);
 | 
			
		||||
                mockType.hasFeature.and.returnValue(true);
 | 
			
		||||
 | 
			
		||||
                capabilities = {
 | 
			
		||||
                    mutation: mockMutation,
 | 
			
		||||
                    type: mockType
 | 
			
		||||
                };
 | 
			
		||||
                model = {
 | 
			
		||||
                    composition: ["a", "test", "b"]
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                actionContext = { domainObject: mockDomainObject };
 | 
			
		||||
 | 
			
		||||
                action = new RemoveAction(mockNavigationService, actionContext);
 | 
			
		||||
                action = new RemoveAction(mockDialogService, mockNavigationService, actionContext);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("only applies to objects with parents", function () {
 | 
			
		||||
@@ -127,83 +110,146 @@ define(
 | 
			
		||||
                expect(mockType.hasFeature).toHaveBeenCalledWith('creation');
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("mutates the parent when performed", function () {
 | 
			
		||||
                action.perform();
 | 
			
		||||
                expect(mockMutation.invoke)
 | 
			
		||||
                    .toHaveBeenCalledWith(jasmine.any(Function));
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("changes composition from its mutation function", function () {
 | 
			
		||||
                var mutator, result;
 | 
			
		||||
                action.perform();
 | 
			
		||||
                mutator = mockMutation.invoke.calls.mostRecent().args[0];
 | 
			
		||||
                result = mutator(model);
 | 
			
		||||
 | 
			
		||||
                // Should not have cancelled the mutation
 | 
			
		||||
                expect(result).not.toBe(false);
 | 
			
		||||
 | 
			
		||||
                // Simulate mutate's behavior (remove can either return a
 | 
			
		||||
                // new model or modify this one in-place)
 | 
			
		||||
                result = result || model;
 | 
			
		||||
 | 
			
		||||
                // Should have removed "test" - that was our
 | 
			
		||||
                // mock domain object's id.
 | 
			
		||||
                expect(result.composition).toEqual(["a", "b"]);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("removes parent of object currently navigated to", function () {
 | 
			
		||||
                // Navigates to child object
 | 
			
		||||
                mockNavigationService.getNavigation.and.returnValue(mockChildObject);
 | 
			
		||||
 | 
			
		||||
                // Test is id of object being removed
 | 
			
		||||
                // Child object has different id
 | 
			
		||||
                mockDomainObject.getId.and.returnValue("test");
 | 
			
		||||
                mockChildObject.getId.and.returnValue("not test");
 | 
			
		||||
 | 
			
		||||
                // Sets context for the child and domainObject
 | 
			
		||||
                mockDomainObject.getCapability.and.returnValue(mockContext);
 | 
			
		||||
                mockChildObject.getCapability.and.returnValue(mockChildContext);
 | 
			
		||||
 | 
			
		||||
                // Parents of child and domainObject are set
 | 
			
		||||
                mockContext.getParent.and.returnValue(mockParent);
 | 
			
		||||
                mockChildContext.getParent.and.returnValue(mockDomainObject);
 | 
			
		||||
 | 
			
		||||
                mockType.hasFeature.and.returnValue(true);
 | 
			
		||||
            it("shows a blocking message dialog", function () {
 | 
			
		||||
                mockParent = jasmine.createSpyObj(
 | 
			
		||||
                    "parent",
 | 
			
		||||
                    ["getModel", "getCapability", "useCapability"]
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
                action.perform();
 | 
			
		||||
 | 
			
		||||
                // Expects navigation to parent of domainObject (removed object)
 | 
			
		||||
                expect(mockNavigationService.setNavigation).toHaveBeenCalledWith(mockParent);
 | 
			
		||||
                expect(mockDialogService.showBlockingMessage).toHaveBeenCalled();
 | 
			
		||||
 | 
			
		||||
                // Also check that no mutation happens at this point
 | 
			
		||||
                expect(mockParent.useCapability).not.toHaveBeenCalledWith("mutation", jasmine.any(Function));
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("checks if removing object not in ascendent path (reaches ROOT)", function () {
 | 
			
		||||
                // Navigates to grandchild of ROOT
 | 
			
		||||
                mockNavigationService.getNavigation.and.returnValue(mockGrandchildObject);
 | 
			
		||||
            describe("after the remove callback is triggered", function () {
 | 
			
		||||
                var mockChildContext,
 | 
			
		||||
                    mockChildObject,
 | 
			
		||||
                    mockDialogHandle,
 | 
			
		||||
                    mockGrandchildContext,
 | 
			
		||||
                    mockGrandchildObject,
 | 
			
		||||
                    mockRootContext,
 | 
			
		||||
                    mockRootObject;
 | 
			
		||||
 | 
			
		||||
                // domainObject (grandparent) is set as ROOT, child and grandchild
 | 
			
		||||
                // are set objects not being removed
 | 
			
		||||
                mockDomainObject.getId.and.returnValue("test 1");
 | 
			
		||||
                mockRootObject.getId.and.returnValue("ROOT");
 | 
			
		||||
                mockChildObject.getId.and.returnValue("not test 2");
 | 
			
		||||
                mockGrandchildObject.getId.and.returnValue("not test 3");
 | 
			
		||||
                beforeEach(function () {
 | 
			
		||||
                    mockChildObject = jasmine.createSpyObj(
 | 
			
		||||
                        "domainObject",
 | 
			
		||||
                        ["getId", "getCapability"]
 | 
			
		||||
                    );
 | 
			
		||||
 | 
			
		||||
                // Sets context for the grandchild, child, and domainObject
 | 
			
		||||
                mockRootObject.getCapability.and.returnValue(mockRootContext);
 | 
			
		||||
                mockChildObject.getCapability.and.returnValue(mockChildContext);
 | 
			
		||||
                mockGrandchildObject.getCapability.and.returnValue(mockGrandchildContext);
 | 
			
		||||
                    mockDialogHandle = jasmine.createSpyObj(
 | 
			
		||||
                        "dialogHandle",
 | 
			
		||||
                        ["dismiss"]
 | 
			
		||||
                    );
 | 
			
		||||
 | 
			
		||||
                // Parents of grandchild and child are set
 | 
			
		||||
                mockChildContext.getParent.and.returnValue(mockRootObject);
 | 
			
		||||
                mockGrandchildContext.getParent.and.returnValue(mockChildObject);
 | 
			
		||||
                    mockGrandchildObject = jasmine.createSpyObj(
 | 
			
		||||
                        "domainObject",
 | 
			
		||||
                        ["getId", "getCapability"]
 | 
			
		||||
                    );
 | 
			
		||||
 | 
			
		||||
                mockType.hasFeature.and.returnValue(true);
 | 
			
		||||
                    mockRootObject = jasmine.createSpyObj(
 | 
			
		||||
                        "domainObject",
 | 
			
		||||
                        ["getId", "getCapability"]
 | 
			
		||||
                    );
 | 
			
		||||
 | 
			
		||||
                action.perform();
 | 
			
		||||
                    mockChildContext = jasmine.createSpyObj("context", ["getParent"]);
 | 
			
		||||
                    mockGrandchildContext = jasmine.createSpyObj("context", ["getParent"]);
 | 
			
		||||
                    mockRootContext = jasmine.createSpyObj("context", ["getParent"]);
 | 
			
		||||
 | 
			
		||||
                    mockDialogService.showBlockingMessage.and.returnValue(mockDialogHandle);
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                it("mutates the parent when performed", function () {
 | 
			
		||||
                    action.perform();
 | 
			
		||||
                    mockDialogService.showBlockingMessage.calls.mostRecent().args[0]
 | 
			
		||||
                        .primaryOption.callback();
 | 
			
		||||
 | 
			
		||||
                    expect(mockMutation.invoke)
 | 
			
		||||
                        .toHaveBeenCalledWith(jasmine.any(Function));
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                it("changes composition from its mutation function", function () {
 | 
			
		||||
                    var mutator, result;
 | 
			
		||||
 | 
			
		||||
                    action.perform();
 | 
			
		||||
                    mockDialogService.showBlockingMessage.calls.mostRecent().args[0]
 | 
			
		||||
                        .primaryOption.callback();
 | 
			
		||||
 | 
			
		||||
                    mutator = mockMutation.invoke.calls.mostRecent().args[0];
 | 
			
		||||
                    result = mutator(model);
 | 
			
		||||
 | 
			
		||||
                    // Should not have cancelled the mutation
 | 
			
		||||
                    expect(result).not.toBe(false);
 | 
			
		||||
 | 
			
		||||
                    // Simulate mutate's behavior (remove can either return a
 | 
			
		||||
                    // new model or modify this one in-place)
 | 
			
		||||
                    result = result || model;
 | 
			
		||||
 | 
			
		||||
                    // Should have removed "test" - that was our
 | 
			
		||||
                    // mock domain object's id.
 | 
			
		||||
                    expect(result.composition).toEqual(["a", "b"]);
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                it("removes parent of object currently navigated to", function () {
 | 
			
		||||
                    // Navigates to child object
 | 
			
		||||
                    mockNavigationService.getNavigation.and.returnValue(mockChildObject);
 | 
			
		||||
 | 
			
		||||
                    // Test is id of object being removed
 | 
			
		||||
                    // Child object has different id
 | 
			
		||||
                    mockDomainObject.getId.and.returnValue("test");
 | 
			
		||||
                    mockChildObject.getId.and.returnValue("not test");
 | 
			
		||||
 | 
			
		||||
                    // Sets context for the child and domainObject
 | 
			
		||||
                    mockDomainObject.getCapability.and.returnValue(mockContext);
 | 
			
		||||
                    mockChildObject.getCapability.and.returnValue(mockChildContext);
 | 
			
		||||
 | 
			
		||||
                    // Parents of child and domainObject are set
 | 
			
		||||
                    mockContext.getParent.and.returnValue(mockParent);
 | 
			
		||||
                    mockChildContext.getParent.and.returnValue(mockDomainObject);
 | 
			
		||||
 | 
			
		||||
                    mockType.hasFeature.and.returnValue(true);
 | 
			
		||||
 | 
			
		||||
                    action.perform();
 | 
			
		||||
                    mockDialogService.showBlockingMessage.calls.mostRecent().args[0]
 | 
			
		||||
                        .primaryOption.callback();
 | 
			
		||||
 | 
			
		||||
                    // Expects navigation to parent of domainObject (removed object)
 | 
			
		||||
                    expect(mockNavigationService.setNavigation).toHaveBeenCalledWith(mockParent);
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                it("checks if removing object not in ascendent path (reaches ROOT)", function () {
 | 
			
		||||
                    // Navigates to grandchild of ROOT
 | 
			
		||||
                    mockNavigationService.getNavigation.and.returnValue(mockGrandchildObject);
 | 
			
		||||
 | 
			
		||||
                    // domainObject (grandparent) is set as ROOT, child and grandchild
 | 
			
		||||
                    // are set objects not being removed
 | 
			
		||||
                    mockDomainObject.getId.and.returnValue("test 1");
 | 
			
		||||
                    mockRootObject.getId.and.returnValue("ROOT");
 | 
			
		||||
                    mockChildObject.getId.and.returnValue("not test 2");
 | 
			
		||||
                    mockGrandchildObject.getId.and.returnValue("not test 3");
 | 
			
		||||
 | 
			
		||||
                    // Sets context for the grandchild, child, and domainObject
 | 
			
		||||
                    mockRootObject.getCapability.and.returnValue(mockRootContext);
 | 
			
		||||
                    mockChildObject.getCapability.and.returnValue(mockChildContext);
 | 
			
		||||
                    mockGrandchildObject.getCapability.and.returnValue(mockGrandchildContext);
 | 
			
		||||
 | 
			
		||||
                    // Parents of grandchild and child are set
 | 
			
		||||
                    mockChildContext.getParent.and.returnValue(mockRootObject);
 | 
			
		||||
                    mockGrandchildContext.getParent.and.returnValue(mockChildObject);
 | 
			
		||||
 | 
			
		||||
                    mockType.hasFeature.and.returnValue(true);
 | 
			
		||||
 | 
			
		||||
                    action.perform();
 | 
			
		||||
                    mockDialogService.showBlockingMessage.calls.mostRecent().args[0]
 | 
			
		||||
                        .primaryOption.callback();
 | 
			
		||||
 | 
			
		||||
                    // Expects no navigation to occur
 | 
			
		||||
                    expect(mockNavigationService.setNavigation).not.toHaveBeenCalled();
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // Expects no navigation to occur
 | 
			
		||||
                expect(mockNavigationService.setNavigation).not.toHaveBeenCalled();
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user