diff --git a/lib/features/rules/BpmnRules.js b/lib/features/rules/BpmnRules.js index ec9da597..895421b8 100644 --- a/lib/features/rules/BpmnRules.js +++ b/lib/features/rules/BpmnRules.js @@ -895,6 +895,10 @@ function includes(elements, element) { } function canCopy(elements, element) { + if (isLabel(element)) { + return true; + } + if (is(element, 'bpmn:Lane') && !includes(elements, element.parent)) { return false; } diff --git a/test/spec/features/rules/BpmnRulesSpec.js b/test/spec/features/rules/BpmnRulesSpec.js index e758651e..a0bd74cf 100644 --- a/test/spec/features/rules/BpmnRulesSpec.js +++ b/test/spec/features/rules/BpmnRulesSpec.js @@ -5,10 +5,11 @@ import { import { expectCanConnect, + expectCanCopy, + expectCanCreate, expectCanDrop, - expectCanMove, expectCanInsert, - expectCanCreate + expectCanMove } from './Helper'; import modelingModule from 'lib/features/modeling'; @@ -83,6 +84,81 @@ describe('features/modeling/rules - BpmnRules', function() { }); + describe('copy elements', function() { + + var testXML = require('./BpmnRules.process.bpmn'); + + beforeEach(bootstrapModeler(testXML, { modules: testModules })); + + + it('copy task', inject(function(elementFactory) { + + // given + var task1 = elementFactory.createShape({ type: 'bpmn:Task' }); + + // then + expectCanCopy(task1, [ task1 ], true); + })); + + + it('copy label', inject(function(elementFactory) { + + // given + var task = elementFactory.createShape({ type: 'bpmn:Task' }), + label = elementFactory.createLabel({ labelTarget: task }); + + // then + // copying labels should always be allowed + expectCanCopy(label, [], true); + })); + + + it('copy lane with parent participant', inject(function(elementFactory) { + + // given + var participant = elementFactory.createShape({ type: 'bpmn:Participant' }), + lane = elementFactory.createShape({ type: 'bpmn:Lane', parent: participant }); + + // then + expectCanCopy(lane, [ participant ], true); + })); + + + it('copy lane without parent participant', inject(function(elementFactory) { + + // given + var participant = elementFactory.createShape({ type: 'bpmn:Participant' }), + lane = elementFactory.createShape({ type: 'bpmn:Lane', parent: participant }); + + // then + expectCanCopy(lane, [], false); + })); + + + it('copy boundary event with host', inject(function(elementFactory) { + + // given + var task = elementFactory.createShape({ type: 'bpmn:Task' }), + boundaryEvent = elementFactory.createShape({ type: 'bpmn:BoundaryEvent', host: task }); + + // then + expectCanCopy(boundaryEvent, [ task ], true); + })); + + + it('copy boundary event without host', inject(function(elementFactory) { + + // given + var task = elementFactory.createShape({ type: 'bpmn:Task' }), + boundaryEvent = elementFactory.createShape({ type: 'bpmn:BoundaryEvent', host: task }); + + // then + expectCanCopy(boundaryEvent, [], false); + })); + + }); + + describe('on process diagram', function() { var testXML = require('./BpmnRules.process.bpmn'); diff --git a/test/spec/features/rules/Helper.js b/test/spec/features/rules/Helper.js index 1c2eedca..56620878 100644 --- a/test/spec/features/rules/Helper.js +++ b/test/spec/features/rules/Helper.js @@ -70,6 +70,19 @@ export function expectCanCreate(shape, target, expectedResult) { } +export function expectCanCopy(element, elements, expectedResult) { + + var result = getBpmnJS().invoke(function(rules) { + return rules.allowed('element.copy', { + element: element, + elements: elements + }); + }); + + expect(result).to.eql(expectedResult); +} + + export function expectCanInsert(element, target, expectedResult) { var result = getBpmnJS().invoke(function(bpmnRules) {