diff --git a/platform/containment/bundle.json b/platform/containment/bundle.json index a31eb60c4a..e61085f66f 100644 --- a/platform/containment/bundle.json +++ b/platform/containment/bundle.json @@ -7,6 +7,11 @@ "depends": [ "$injector" ], "message": "Objects of this type cannot contain objects of that type." }, + { + "category": "composition", + "implementation": "CompositionMutabilityPolicy.js", + "message": "Objects of this type cannot be modified." + }, { "category": "action", "implementation": "ComposeActionPolicy.js", diff --git a/platform/containment/src/CompositionMutabilityPolicy.js b/platform/containment/src/CompositionMutabilityPolicy.js new file mode 100644 index 0000000000..21dc02fafc --- /dev/null +++ b/platform/containment/src/CompositionMutabilityPolicy.js @@ -0,0 +1,30 @@ +/*global define*/ + +define( + [], + function () { + "use strict"; + + /** + * Disallow composition changes to objects which are not mutable. + * @constructor + */ + function CompositionMutabilityPolicy() { + return { + /** + * Is the type identified by the candidate allowed to + * contain the type described by the context? + * @param {Type} candidate the type of domain object + */ + allow: function (candidate) { + // Equate creatability with mutability; that is, users + // can only modify objects of types they can create, and + // vice versa. + return candidate.hasFeature('creation'); + } + }; + } + + return CompositionMutabilityPolicy; + } +); \ No newline at end of file diff --git a/platform/containment/test/CompositionMutabilityPolicySpec.js b/platform/containment/test/CompositionMutabilityPolicySpec.js new file mode 100644 index 0000000000..460f8b6870 --- /dev/null +++ b/platform/containment/test/CompositionMutabilityPolicySpec.js @@ -0,0 +1,26 @@ +/*global define,Promise,describe,it,expect,beforeEach,waitsFor,jasmine*/ + +define( + ["../src/CompositionMutabilityPolicy"], + function (CompositionMutabilityPolicy) { + "use strict"; + + describe("The composition mutability policy", function () { + var mockType, + policy; + + beforeEach(function () { + mockType = jasmine.createSpyObj('type', ['hasFeature']); + policy = new CompositionMutabilityPolicy(); + }); + + it("only allows composition for types which will have a composition capability", function () { + expect(policy.allow(mockType)).toBeFalsy(); + mockType.hasFeature.andReturn(true); + expect(policy.allow(mockType)).toBeTruthy(); + expect(mockType.hasFeature).toHaveBeenCalledWith('creation'); + }); + }); + + } +); \ No newline at end of file diff --git a/platform/containment/test/suite.json b/platform/containment/test/suite.json index a82d203c53..987ef9a86c 100644 --- a/platform/containment/test/suite.json +++ b/platform/containment/test/suite.json @@ -1,6 +1,7 @@ [ "CapabilityTable", "ComposeActionPolicy", + "CompositionMutabilityPolicy", "CompositionPolicy", "ContainmentTable" ] \ No newline at end of file