diff --git a/platform/commonUI/general/test/controllers/SelectorControllerSpec.js b/platform/commonUI/general/test/controllers/SelectorControllerSpec.js index 30648a1d8e..0f03e72c45 100644 --- a/platform/commonUI/general/test/controllers/SelectorControllerSpec.js +++ b/platform/commonUI/general/test/controllers/SelectorControllerSpec.js @@ -8,6 +8,9 @@ define( describe("The controller for the 'selector' control", function () { var mockObjectService, mockScope, + mockDomainObject, + mockType, + mockDomainObjects, controller; function promiseOf(v) { @@ -18,6 +21,15 @@ define( }; } + function makeMockObject(id) { + var mockObject = jasmine.createSpyObj( + 'object-' + id, + [ 'getId' ] + ); + mockObject.getId.andReturn(id); + return mockObject; + } + beforeEach(function () { mockObjectService = jasmine.createSpyObj( 'objectService', @@ -27,8 +39,24 @@ define( '$scope', ['$watch', '$watchCollection'] ); + mockDomainObject = jasmine.createSpyObj( + 'domainObject', + [ 'getCapability', 'hasCapability' ] + ); + mockType = jasmine.createSpyObj( + 'type', + [ 'instanceOf' ] + ); + mockDomainObjects = {}; - mockObjectService.getObjects.andReturn(promiseOf({})); + [ "ROOT", "abc", "def", "xyz" ].forEach(function (id) { + mockDomainObjects[id] = makeMockObject(id); + }); + + mockDomainObject.getCapability.andReturn(mockType); + mockObjectService.getObjects.andReturn(promiseOf(mockDomainObjects)); + mockScope.field = "testField"; + mockScope.ngModel = {}; controller = new SelectorController( mockObjectService, @@ -40,6 +68,96 @@ define( expect(mockObjectService.getObjects) .toHaveBeenCalledWith(["ROOT"]); }); + + it("watches for changes in selection in left-hand tree", function () { + var testObject = { a: 123, b: 456 }; + // This test is sensitive to ordering of watch calls + expect(mockScope.$watch.calls.length).toEqual(1); + // Make sure we're watching the correct object + controller.treeModel.selectedObject = testObject; + expect(mockScope.$watch.calls[0].args[0]()).toBe(testObject); + }); + + it("watches for changes in controlled property", function () { + var testValue = [ "a", "b", 1, 2 ]; + // This test is sensitive to ordering of watch calls + expect(mockScope.$watchCollection.calls.length).toEqual(1); + // Make sure we're watching the correct object + mockScope.ngModel = { testField: testValue }; + expect(mockScope.$watchCollection.calls[0].args[0]()).toBe(testValue); + }); + + it("rejects selection of incorrect types", function () { + mockScope.structure = { type: "someType" }; + mockType.instanceOf.andReturn(false); + controller.treeModel.selectedObject = mockDomainObject; + // Fire the watch + mockScope.$watch.calls[0].args[1](mockDomainObject); + // Should have cleared the selection + expect(controller.treeModel.selectedObject).toBeUndefined(); + // Verify interaction (that instanceOf got a useful argument) + expect(mockType.instanceOf).toHaveBeenCalledWith("someType"); + }); + + it("permits selection of matching types", function () { + mockScope.structure = { type: "someType" }; + mockType.instanceOf.andReturn(true); + controller.treeModel.selectedObject = mockDomainObject; + // Fire the watch + mockScope.$watch.calls[0].args[1](mockDomainObject); + // Should have preserved the selection + expect(controller.treeModel.selectedObject).toEqual(mockDomainObject); + // Verify interaction (that instanceOf got a useful argument) + expect(mockType.instanceOf).toHaveBeenCalledWith("someType"); + }); + + it("loads objects when the underlying list changes", function () { + var testIds = [ "abc", "def", "xyz" ]; + // This test is sensitive to ordering of watch calls + expect(mockScope.$watchCollection.calls.length).toEqual(1); + // Make sure we're watching the correct object + mockScope.ngModel = { testField: testIds }; + // Fire the watch + mockScope.$watchCollection.calls[0].args[1](testIds); + // Should have loaded the corresponding objects + expect(mockObjectService.getObjects).toHaveBeenCalledWith(testIds); + }); + + it("exposes the root object to populate the left-hand tree", function () { + expect(controller.root()).toEqual(mockDomainObjects.ROOT); + }); + + it("adds objects to the underlying model", function () { + expect(mockScope.ngModel.testField).toBeUndefined(); + controller.select(mockDomainObjects.def); + expect(mockScope.ngModel.testField).toEqual(["def"]); + controller.select(mockDomainObjects.abc); + expect(mockScope.ngModel.testField).toEqual(["def", "abc"]); + }); + + it("removes objects to the underlying model", function () { + controller.select(mockDomainObjects.def); + controller.select(mockDomainObjects.abc); + expect(mockScope.ngModel.testField).toEqual(["def", "abc"]); + controller.deselect(mockDomainObjects.def); + expect(mockScope.ngModel.testField).toEqual(["abc"]); + }); + + it("provides a list of currently-selected objects", function () { + // Verify precondition + expect(controller.selected()).toEqual([]); + // Select some objects + controller.select(mockDomainObjects.def); + controller.select(mockDomainObjects.abc); + // Fire the watch for the id changes... + mockScope.$watchCollection.calls[0].args[1]( + mockScope.$watchCollection.calls[0].args[0]() + ); + // Should have loaded and exposed those objects + expect(controller.selected()).toEqual( + [mockDomainObjects.def, mockDomainObjects.abc] + ); + }); }); } );