From 60f2f9fb6c50e19348f264cb3aae4f3baeea15a5 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 6 Oct 2015 16:08:48 -0700 Subject: [PATCH 1/6] [Location] Add getOriginal method Add a getOriginal method to the location capability, to simplify loading of original versions of objects. nasa/openmctweb#147 --- platform/entanglement/bundle.json | 3 +- .../src/capabilities/LocationCapability.js | 38 ++++++++++++++++--- .../capabilities/LocationCapabilitySpec.js | 17 ++++++++- 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/platform/entanglement/bundle.json b/platform/entanglement/bundle.json index 61c3d90539..52a65071a8 100644 --- a/platform/entanglement/bundle.json +++ b/platform/entanglement/bundle.json @@ -52,7 +52,8 @@ "key": "location", "name": "Location Capability", "description": "Provides a capability for retrieving the location of an object based upon it's context.", - "implementation": "capabilities/LocationCapability" + "implementation": "capabilities/LocationCapability", + "depends": [ "$q", "$injector" ] } ], "services": [ diff --git a/platform/entanglement/src/capabilities/LocationCapability.js b/platform/entanglement/src/capabilities/LocationCapability.js index 17d678f57e..38974ecb0f 100644 --- a/platform/entanglement/src/capabilities/LocationCapability.js +++ b/platform/entanglement/src/capabilities/LocationCapability.js @@ -12,11 +12,41 @@ define( * * @constructor */ - function LocationCapability(domainObject) { + function LocationCapability($q, $injector, domainObject) { this.domainObject = domainObject; + this.$q = $q; + this.$injector = $injector; return this; } + /** + * Get an instance of this domain object in its original location. + * + * @returns {Promise.} a promise for the original + * instance of this domain object + */ + LocationCapability.prototype.getOriginal = function () { + var id; + + if (this.isOriginal()) { + return this.$q.when(this.domainObject); + } + + id = this.domainObject.getId(); + + this.objectService = + this.objectService || this.$injector.get("objectService"); + + // Assume that an object will be correctly contextualized when + // loaded directly from the object service; this is true + // so long as LocatingObjectDecorator is present, and that + // decorator is also contained in this bundle. + return this.objectService.getObjects([id]) + .then(function (objects) { + return objects[id]; + }); + }; + /** * Set the primary location (the parent id) of the current domain * object. @@ -78,10 +108,6 @@ define( return !this.isLink(); }; - function createLocationCapability(domainObject) { - return new LocationCapability(domainObject); - } - - return createLocationCapability; + return LocationCapability; } ); diff --git a/platform/entanglement/test/capabilities/LocationCapabilitySpec.js b/platform/entanglement/test/capabilities/LocationCapabilitySpec.js index 9cbfcc1bea..497158a67e 100644 --- a/platform/entanglement/test/capabilities/LocationCapabilitySpec.js +++ b/platform/entanglement/test/capabilities/LocationCapabilitySpec.js @@ -7,6 +7,7 @@ define( '../ControlledPromise' ], function (LocationCapability, domainObjectFactory, ControlledPromise) { + 'use strict'; describe("LocationCapability", function () { @@ -14,13 +15,16 @@ define( var locationCapability, persistencePromise, mutationPromise, + mockQ, + mockInjector, + mockObjectService, domainObject; beforeEach(function () { domainObject = domainObjectFactory({ capabilities: { context: { - getParent: function() { + getParent: function () { return domainObjectFactory({id: 'root'}); } }, @@ -35,6 +39,11 @@ define( } }); + mockQ = jasmine.createSpyObj("$q", ["when"]); + mockInjector = jasmine.createSpyObj("$injector", ["get"]); + mockObjectService = + jasmine.createSpyObj("objectService", ["getObjects"]); + persistencePromise = new ControlledPromise(); domainObject.capabilities.persistence.persist.andReturn( persistencePromise @@ -49,7 +58,11 @@ define( } ); - locationCapability = new LocationCapability(domainObject); + locationCapability = new LocationCapability( + mockQ, + mockObjectService, + domainObject + ); }); it("returns contextual location", function () { From e3afaf0842afa5abb3f3991f65a20f39c937f0a5 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 6 Oct 2015 16:22:16 -0700 Subject: [PATCH 2/6] [Entanglement] Add Go To Original nasa/openmctweb#147 --- platform/entanglement/bundle.json | 8 +++ .../src/actions/GoToOriginalAction.js | 62 +++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 platform/entanglement/src/actions/GoToOriginalAction.js diff --git a/platform/entanglement/bundle.json b/platform/entanglement/bundle.json index 52a65071a8..d8cde0ada6 100644 --- a/platform/entanglement/bundle.json +++ b/platform/entanglement/bundle.json @@ -30,6 +30,14 @@ "category": "contextual", "implementation": "actions/LinkAction.js", "depends": ["locationService", "linkService"] + }, + { + "key": "follow", + "name": "Go To Original", + "description": "Go to the original, un-linked instance of this object.", + "glyph": "\u00F4", + "category": "contextual", + "implementation": "actions/GoToOriginalAction.js" } ], "components": [ diff --git a/platform/entanglement/src/actions/GoToOriginalAction.js b/platform/entanglement/src/actions/GoToOriginalAction.js new file mode 100644 index 0000000000..9722915ad6 --- /dev/null +++ b/platform/entanglement/src/actions/GoToOriginalAction.js @@ -0,0 +1,62 @@ +/***************************************************************************** + * Open MCT Web, Copyright (c) 2014-2015, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT Web 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 Web 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. + *****************************************************************************/ + +/*global define */ +define( + function () { + "use strict"; + + /** + * Implements the "Go To Original" action, which follows a link back + * to an original instance of an object. + * + * @implements {Action} + * @constructor + * @private + * @memberof platform/entanglement + * @param {ActionContext} context the context in which the action + * will be performed + */ + function GoToOriginalAction(context) { + this.domainObject = context.domainObject; + } + + GoToOriginalAction.prototype.perform = function () { + return this.domainObject.getCapability("location").getOriginal() + .then(function (originalObject) { + var actionCapability = + originalObject.getCapability("action"); + return actionCapability && + actionCapability.perform("navigate"); + }); + }; + + GoToOriginalAction.appliesTo = function (context) { + var domainObject = context.domainObject; + return domainObject && domainObject.hasCapability("location") + && domainObject.getCapability("location").isLink(); + }; + + return GoToOriginalAction; + } +); + From 70bbd3cf97f43914572df00783763b208cbf08fa Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 6 Oct 2015 16:37:37 -0700 Subject: [PATCH 3/6] [Entanglement] Add test cases for Go To Original --- .../test/actions/GoToOriginalActionSpec.js | 95 +++++++++++++++++++ platform/entanglement/test/suite.json | 1 + 2 files changed, 96 insertions(+) create mode 100644 platform/entanglement/test/actions/GoToOriginalActionSpec.js diff --git a/platform/entanglement/test/actions/GoToOriginalActionSpec.js b/platform/entanglement/test/actions/GoToOriginalActionSpec.js new file mode 100644 index 0000000000..40c2f213ce --- /dev/null +++ b/platform/entanglement/test/actions/GoToOriginalActionSpec.js @@ -0,0 +1,95 @@ +/***************************************************************************** + * Open MCT Web, Copyright (c) 2014-2015, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT Web 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 Web 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. + *****************************************************************************/ + +/*global define,describe,beforeEach,it,jasmine,expect */ + +define( + [ + '../../src/actions/GoToOriginalAction', + '../DomainObjectFactory', + '../ControlledPromise' + ], + function (GoToOriginalAction, domainObjectFactory, ControlledPromise) { + 'use strict'; + + describe("The 'go to original' action", function () { + var testContext, + originalDomainObject, + mockLocationCapability, + mockOriginalActionCapability, + originalPromise, + action; + + beforeEach(function () { + mockLocationCapability = jasmine.createSpyObj( + 'location', + [ 'isLink', 'isOriginal', 'getOriginal' ] + ); + mockOriginalActionCapability = jasmine.createSpyObj( + 'action', + [ 'perform', 'getActions' ] + ); + originalPromise = new ControlledPromise(); + mockLocationCapability.getOriginal.andReturn(originalPromise); + mockLocationCapability.isLink.andReturn(true); + mockLocationCapability.isOriginal.andCallFake(function () { + return !mockLocationCapability.isLink(); + }); + testContext = { + domainObject: domainObjectFactory({ + capabilities: { + location: mockLocationCapability + } + }) + }; + originalDomainObject = domainObjectFactory({ + capabilities: { + action: mockOriginalActionCapability + } + }); + + action = new GoToOriginalAction(testContext); + }); + + it("is applicable to links", function () { + expect(GoToOriginalAction.appliesTo(testContext)) + .toBeTruthy(); + }); + + it("is not applicable to originals", function () { + mockLocationCapability.isLink.andReturn(false); + expect(GoToOriginalAction.appliesTo(testContext)) + .toBeFalsy(); + }); + + it("navigates to original objects when performed", function () { + expect(mockOriginalActionCapability.perform) + .not.toHaveBeenCalled(); + action.perform(); + originalPromise.resolve(originalDomainObject); + expect(mockOriginalActionCapability.perform) + .toHaveBeenCalledWith('navigate'); + }); + + }); + } +); diff --git a/platform/entanglement/test/suite.json b/platform/entanglement/test/suite.json index 12831b407a..2ce90499e8 100644 --- a/platform/entanglement/test/suite.json +++ b/platform/entanglement/test/suite.json @@ -1,5 +1,6 @@ [ "actions/AbstractComposeAction", + "actions/GoToOriginalAction", "services/CopyService", "services/LinkService", "services/MoveService", From a4944717a1eb1bcbe385dd3ddc7321ea8805ab34 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 6 Oct 2015 16:47:37 -0700 Subject: [PATCH 4/6] [Location] Test getOriginal method --- .../capabilities/LocationCapabilitySpec.js | 54 ++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/platform/entanglement/test/capabilities/LocationCapabilitySpec.js b/platform/entanglement/test/capabilities/LocationCapabilitySpec.js index 497158a67e..938f0d843c 100644 --- a/platform/entanglement/test/capabilities/LocationCapabilitySpec.js +++ b/platform/entanglement/test/capabilities/LocationCapabilitySpec.js @@ -22,6 +22,7 @@ define( beforeEach(function () { domainObject = domainObjectFactory({ + id: "testObject", capabilities: { context: { getParent: function () { @@ -60,7 +61,7 @@ define( locationCapability = new LocationCapability( mockQ, - mockObjectService, + mockInjector, domainObject ); }); @@ -101,6 +102,57 @@ define( expect(whenComplete).toHaveBeenCalled(); }); + describe("when used to load an original instance", function () { + var objectPromise, + qPromise, + originalObjects, + mockCallback; + + function resolvePromises() { + if (mockQ.when.calls.length > 0) { + qPromise.resolve(mockQ.when.mostRecentCall.args[0]); + } + if (mockObjectService.getObjects.calls.length > 0) { + objectPromise.resolve(originalObjects); + } + } + + beforeEach(function () { + objectPromise = new ControlledPromise(); + qPromise = new ControlledPromise(); + originalObjects = { + testObject: domainObjectFactory() + }; + + mockInjector.get.andCallFake(function (key) { + return key === 'objectService' && mockObjectService; + }); + mockObjectService.getObjects.andReturn(objectPromise); + mockQ.when.andReturn(qPromise); + + mockCallback = jasmine.createSpy('callback'); + }); + + it("provides originals directly", function () { + domainObject.model.location = 'root'; + locationCapability.getOriginal().then(mockCallback); + expect(mockCallback).not.toHaveBeenCalled(); + resolvePromises(); + expect(mockCallback) + .toHaveBeenCalledWith(domainObject); + }); + + it("loads from the object service for links", function () { + domainObject.model.location = 'some-other-root'; + locationCapability.getOriginal().then(mockCallback); + expect(mockCallback).not.toHaveBeenCalled(); + resolvePromises(); + expect(mockCallback) + .toHaveBeenCalledWith(originalObjects.testObject); + }); + }); + + }); }); } From bf41d82a78282fdac3acaed1845188bf69eed651 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 6 Oct 2015 16:50:35 -0700 Subject: [PATCH 5/6] [Entanglement] Restore missing specs Restore specs which had been omitted from suite.json (but currently succeed for the relevant scripts); done in the context of nasa/openmctweb#147 --- platform/entanglement/test/suite.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/platform/entanglement/test/suite.json b/platform/entanglement/test/suite.json index 2ce90499e8..89c082f9c8 100644 --- a/platform/entanglement/test/suite.json +++ b/platform/entanglement/test/suite.json @@ -1,6 +1,9 @@ [ "actions/AbstractComposeAction", + "actions/CopyAction", "actions/GoToOriginalAction", + "actions/LinkAction", + "actions/MoveAction", "services/CopyService", "services/LinkService", "services/MoveService", From 8e2a2eeba5db5c9c14769c75bfe67fcfb63491a9 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Mon, 19 Oct 2015 12:08:49 -0700 Subject: [PATCH 6/6] [Entanglement] Add license headers ...per code review feedback from nasa/openmctweb#175 --- .../src/capabilities/LocationCapability.js | 22 +++++++++++++++++++ .../capabilities/LocationCapabilitySpec.js | 22 +++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/platform/entanglement/src/capabilities/LocationCapability.js b/platform/entanglement/src/capabilities/LocationCapability.js index 38974ecb0f..27e1f74c74 100644 --- a/platform/entanglement/src/capabilities/LocationCapability.js +++ b/platform/entanglement/src/capabilities/LocationCapability.js @@ -1,3 +1,25 @@ +/***************************************************************************** + * Open MCT Web, Copyright (c) 2014-2015, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT Web 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 Web 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. + *****************************************************************************/ + /*global define */ define( diff --git a/platform/entanglement/test/capabilities/LocationCapabilitySpec.js b/platform/entanglement/test/capabilities/LocationCapabilitySpec.js index 938f0d843c..442bfe20aa 100644 --- a/platform/entanglement/test/capabilities/LocationCapabilitySpec.js +++ b/platform/entanglement/test/capabilities/LocationCapabilitySpec.js @@ -1,3 +1,25 @@ +/***************************************************************************** + * Open MCT Web, Copyright (c) 2014-2015, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT Web 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 Web 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. + *****************************************************************************/ + /*global define,describe,it,expect,beforeEach,jasmine */ define(