diff --git a/lib/features/replace/BpmnReplace.js b/lib/features/replace/BpmnReplace.js index f848be98..51eef1b1 100644 --- a/lib/features/replace/BpmnReplace.js +++ b/lib/features/replace/BpmnReplace.js @@ -43,7 +43,7 @@ var CUSTOM_PROPERTIES = [ * @param {PopupMenu} popupMenu * @param {Replace} replace */ -function BpmnReplace(bpmnFactory, moddle, popupMenu, replace, selection, modeling, eventBus) { +function BpmnReplace(bpmnFactory, moddle, popupMenu, replace, selection, modeling, eventBus, rules) { var self = this, currentElement; @@ -224,6 +224,10 @@ function BpmnReplace(bpmnFactory, moddle, popupMenu, replace, selection, modelin this.getReplaceOptions = function(element) { + if (!rules.allowed('shape.replace', { element: element })) { + return []; + } + var menuEntries = []; var businessObject = element.businessObject; @@ -383,12 +387,10 @@ function BpmnReplace(bpmnFactory, moddle, popupMenu, replace, selection, modelin // Add entries to replace menu forEach(filteredEntries, function(definition) { var entry = addMenuEntry(definition); - menuEntries.push(entry); }); } - function addMenuEntry(definition, action) { var menuEntry = { @@ -446,6 +448,6 @@ function BpmnReplace(bpmnFactory, moddle, popupMenu, replace, selection, modelin this.replaceElement = replaceElement; } -BpmnReplace.$inject = [ 'bpmnFactory', 'moddle', 'popupMenu', 'replace', 'selection', 'modeling', 'eventBus' ]; +BpmnReplace.$inject = [ 'bpmnFactory', 'moddle', 'popupMenu', 'replace', 'selection', 'modeling', 'eventBus', 'rules' ]; module.exports = BpmnReplace; diff --git a/test/spec/features/context-pad/ContextPadProviderSpec.js b/test/spec/features/context-pad/ContextPadProviderSpec.js index 934fcf46..92f42aed 100644 --- a/test/spec/features/context-pad/ContextPadProviderSpec.js +++ b/test/spec/features/context-pad/ContextPadProviderSpec.js @@ -14,7 +14,7 @@ var contextPadModule = require('../../../../lib/features/context-pad'), modelingModule = require('../../../../lib/features/modeling'), popupModule = require('diagram-js/lib/features/popup-menu'), replaceModule = require('diagram-js/lib/features/replace'), - rulesModule = require('./rules'); + rulesModule = require('../../../util/custom-rules'); describe('features - context-pad', function() { diff --git a/test/spec/features/replace/BpmnReplaceSpec.js b/test/spec/features/replace/BpmnReplaceSpec.js index be28662e..d35b7e41 100644 --- a/test/spec/features/replace/BpmnReplaceSpec.js +++ b/test/spec/features/replace/BpmnReplaceSpec.js @@ -7,7 +7,8 @@ var TestHelper = require('../../../TestHelper'); var modelingModule = require('../../../../lib/features/modeling'), replaceModule = require('../../../../lib/features/replace'), moveModule = require('diagram-js/lib/features/move'), - coreModule = require('../../../../lib/core'); + coreModule = require('../../../../lib/core'), + customRulesModule = require('../../../util/custom-rules'); var is = require('../../../../lib/util/ModelUtil').is, isExpanded = require('../../../../lib/util/DiUtil').isExpanded, @@ -1416,4 +1417,89 @@ describe('features/replace', function() { })); }); + describe('getReplaceOptions', function () { + + var diagramXML = require('../../../fixtures/bpmn/basic.bpmn'); + + beforeEach(bootstrapModeler(diagramXML, { modules: testModules.concat([ customRulesModule ]) })); + + it('should get replacement options by default', inject(function(elementRegistry, bpmnReplace) { + + // given + var startEvent = elementRegistry.get('StartEvent_1'); + + // when + var options = bpmnReplace.getReplaceOptions(startEvent); + + // then + expect(options).to.have.length.above(0); + })); + + it('should get replacement options when custom rule returns true', inject(function(elementRegistry, bpmnReplace, customRules) { + + // given + var startEvent = elementRegistry.get('StartEvent_1'); + + customRules.addRule('shape.replace', function () { + return true; + }); + + // when + var options = bpmnReplace.getReplaceOptions(startEvent); + + // then + expect(options).to.have.length.above(0); + })); + + it('should get no replacement options when custom rule returns false', inject(function(elementRegistry, bpmnReplace, customRules) { + + // given + var startEvent = elementRegistry.get('StartEvent_1'); + + customRules.addRule('shape.replace', function () { + return false; + }); + + // when + var options = bpmnReplace.getReplaceOptions(startEvent); + + // then + expect(options).to.have.length(0); + })); + + it('should provide element to custom rules', inject(function(elementRegistry, bpmnReplace, customRules) { + + // given + var startEvent = elementRegistry.get('StartEvent_1'); + var actual; + + customRules.addRule('shape.replace', function (context) { + actual = context.element; + }); + + // when + bpmnReplace.getReplaceOptions(startEvent); + + // then + expect(actual).to.equal(startEvent); + })); + + it('should evaluate rule once', inject(function(elementRegistry, bpmnReplace, customRules) { + + // given + var callCount = 0; + var startEvent = elementRegistry.get('StartEvent_1'); + + customRules.addRule('shape.replace', function () { + callCount++; + }); + + // when + bpmnReplace.getReplaceOptions(startEvent); + + // then + expect(callCount).to.equal(1); + })); + }); + }); diff --git a/test/spec/features/context-pad/rules/CustomRules.js b/test/util/custom-rules/CustomRules.js similarity index 74% rename from test/spec/features/context-pad/rules/CustomRules.js rename to test/util/custom-rules/CustomRules.js index 8d606b27..0a69e81b 100644 --- a/test/spec/features/context-pad/rules/CustomRules.js +++ b/test/util/custom-rules/CustomRules.js @@ -12,4 +12,8 @@ CustomRules.$inject = [ 'eventBus' ]; inherits(CustomRules, RuleProvider); +CustomRules.prototype.init = function () { + // placeholder +}; + module.exports = CustomRules; \ No newline at end of file diff --git a/test/spec/features/context-pad/rules/index.js b/test/util/custom-rules/index.js similarity index 100% rename from test/spec/features/context-pad/rules/index.js rename to test/util/custom-rules/index.js