From 6145843e86cc41d71014803381d972aa202076de Mon Sep 17 00:00:00 2001 From: Pegah Sarram Date: Wed, 28 Feb 2018 13:38:00 -0800 Subject: [PATCH] [Inspector] Add check to prevent race condition before setting the scope composition. (#1931) Fixes #1918 --- .../src/controllers/ElementsController.js | 8 +++- .../controllers/ElementsControllerSpec.js | 46 ++++++++++++++++++- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/platform/commonUI/edit/src/controllers/ElementsController.js b/platform/commonUI/edit/src/controllers/ElementsController.js index d0c14c3807..821e9dc2da 100644 --- a/platform/commonUI/edit/src/controllers/ElementsController.js +++ b/platform/commonUI/edit/src/controllers/ElementsController.js @@ -88,11 +88,15 @@ define( * @private */ ElementsController.prototype.refreshComposition = function (domainObject) { - var selectedObjectComposition = domainObject && domainObject.useCapability('composition'); + var refreshTracker = {}; + this.currentRefresh = refreshTracker; + var selectedObjectComposition = domainObject && domainObject.useCapability('composition'); if (selectedObjectComposition) { selectedObjectComposition.then(function (composition) { - this.scope.composition = composition; + if (this.currentRefresh === refreshTracker) { + this.scope.composition = composition; + } }.bind(this)); } else { this.scope.composition = []; diff --git a/platform/commonUI/edit/test/controllers/ElementsControllerSpec.js b/platform/commonUI/edit/test/controllers/ElementsControllerSpec.js index 52480af741..15e0921564 100644 --- a/platform/commonUI/edit/test/controllers/ElementsControllerSpec.js +++ b/platform/commonUI/edit/test/controllers/ElementsControllerSpec.js @@ -31,11 +31,34 @@ define( mockSelection, mockDomainObject, mockMutationCapability, + mockCompositionCapability, + mockCompositionObjects, + mockComposition, mockUnlisten, selectable = [], controller; + function mockPromise(value) { + return { + then: function (thenFunc) { + return mockPromise(thenFunc(value)); + } + }; + } + + function createDomainObject() { + return { + useCapability: function () { + return mockCompositionCapability; + } + }; + } + beforeEach(function () { + mockComposition = ["a", "b"]; + mockCompositionObjects = mockComposition.map(createDomainObject); + mockCompositionCapability = mockPromise(mockCompositionObjects); + mockUnlisten = jasmine.createSpy('unlisten'); mockMutationCapability = jasmine.createSpyObj("mutationCapability", [ "listen" @@ -45,7 +68,7 @@ define( "getCapability", "useCapability" ]); - mockDomainObject.useCapability.andCallThrough(); + mockDomainObject.useCapability.andReturn(mockCompositionCapability); mockDomainObject.getCapability.andReturn(mockMutationCapability); mockScope = jasmine.createSpyObj("$scope", ['$on']); @@ -65,7 +88,7 @@ define( } }; - spyOn(ElementsController.prototype, 'refreshComposition'); + spyOn(ElementsController.prototype, 'refreshComposition').andCallThrough(); controller = new ElementsController(mockScope, mockOpenMCT); }); @@ -137,6 +160,25 @@ define( expect(mockDomainObject.getCapability).not.toHaveBeenCalledWith('mutation'); }); + + it("checks concurrent changes to composition", function () { + var secondMockComposition = ["a", "b", "c"], + secondMockCompositionObjects = secondMockComposition.map(createDomainObject), + firstCompositionCallback, + secondCompositionCallback; + + spyOn(mockCompositionCapability, "then").andCallThrough(); + + controller.refreshComposition(mockDomainObject); + controller.refreshComposition(mockDomainObject); + + firstCompositionCallback = mockCompositionCapability.then.calls[0].args[0]; + secondCompositionCallback = mockCompositionCapability.then.calls[1].args[0]; + secondCompositionCallback(secondMockCompositionObjects); + firstCompositionCallback(mockCompositionObjects); + + expect(mockScope.composition).toBe(secondMockCompositionObjects); + }); }); } );