-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: pasting compensation activity without boundary event
Closes #2070
- Loading branch information
1 parent
afdd676
commit 4359f18
Showing
5 changed files
with
195 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
67 changes: 67 additions & 0 deletions
67
lib/features/modeling/behavior/SetCompensationActivityAfterPasteBehavior.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import inherits from 'inherits-browser'; | ||
|
||
import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor'; | ||
|
||
import { getBusinessObject, is } from '../../../util/ModelUtil'; | ||
|
||
import { hasEventDefinition } from '../../../util/DiUtil'; | ||
|
||
/** | ||
* @typedef {import('diagram-js/lib/core/EventBus').default} EventBus | ||
* @typedef {import('../../rules/BpmnRules').default} BpmnRules | ||
* @typedef {import('../Modeling').default} Modeling | ||
*/ | ||
|
||
|
||
/** | ||
* A behavior that sets the property of Compensation Activity after paste operation | ||
* | ||
* @param {EventBus} eventBus | ||
* @param {Modeling} modeling | ||
*/ | ||
export default function SetCompensationActivityAfterPasteBehavior(eventBus, modeling) { | ||
|
||
CommandInterceptor.call(this, eventBus); | ||
|
||
this.postExecuted('elements.create', function(event) { | ||
const context = event.context, | ||
elements = context.elements; | ||
|
||
// check if compensation activity is connected to compensation boundary event | ||
for (const element of elements) { | ||
if (isForCompensation(element) && !isConnectedToCompensationBoundaryEvent(element)) { | ||
modeling.updateProperties(element, { isForCompensation: undefined }); | ||
} | ||
} | ||
}); | ||
} | ||
|
||
inherits(SetCompensationActivityAfterPasteBehavior, CommandInterceptor); | ||
|
||
SetCompensationActivityAfterPasteBehavior.$inject = [ | ||
'eventBus', | ||
'modeling' | ||
]; | ||
|
||
|
||
// helpers ////////////////////// | ||
|
||
function isForCompensation(element) { | ||
const bo = getBusinessObject(element); | ||
return bo && bo.isForCompensation; | ||
} | ||
|
||
function isCompensationBoundaryEvent(element) { | ||
return element && is(element, 'bpmn:BoundaryEvent') && | ||
hasEventDefinition(element, 'bpmn:CompensateEventDefinition'); | ||
} | ||
|
||
function isConnectedToCompensationBoundaryEvent(element) { | ||
const compensationAssociations = element.incoming.filter( | ||
connection => isCompensationBoundaryEvent(connection.source) | ||
); | ||
if (compensationAssociations.length > 0) { | ||
return true; | ||
} | ||
return false; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 42 additions & 0 deletions
42
test/spec/features/modeling/behavior/SetCompensationActivityAfterPasteBehaviorSpec.bpmn
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.25.0"> | ||
<bpmn:process id="Process_1" isExecutable="false"> | ||
<bpmn:startEvent id="Event_0wuaar2"> | ||
<bpmn:outgoing>Flow_1ank1yi</bpmn:outgoing> | ||
</bpmn:startEvent> | ||
<bpmn:task id="Compensation_Boundary_Task"> | ||
<bpmn:incoming>Flow_1ank1yi</bpmn:incoming> | ||
</bpmn:task> | ||
<bpmn:sequenceFlow id="Flow_1ank1yi" sourceRef="Event_0wuaar2" targetRef="Compensation_Boundary_Task" /> | ||
<bpmn:boundaryEvent id="Compensation_Boundary_Event" attachedToRef="Compensation_Boundary_Task"> | ||
<bpmn:compensateEventDefinition id="CompensateEventDefinition_0ibh5ku" /> | ||
</bpmn:boundaryEvent> | ||
<bpmn:task id="Compensation_Activity" isForCompensation="true" /> | ||
<bpmn:association id="Association_0x72gur" associationDirection="One" sourceRef="Compensation_Boundary_Event" targetRef="Compensation_Activity" /> | ||
</bpmn:process> | ||
<bpmndi:BPMNDiagram id="BPMNDiagram_1"> | ||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1"> | ||
<bpmndi:BPMNShape id="Event_0wuaar2_di" bpmnElement="Event_0wuaar2"> | ||
<dc:Bounds x="152" y="112" width="36" height="36" /> | ||
</bpmndi:BPMNShape> | ||
<bpmndi:BPMNShape id="Compensation_Boundary_Task_di" bpmnElement="Compensation_Boundary_Task"> | ||
<dc:Bounds x="240" y="90" width="100" height="80" /> | ||
</bpmndi:BPMNShape> | ||
<bpmndi:BPMNShape id="Compensation_Activity_di" bpmnElement="Compensation_Activity"> | ||
<dc:Bounds x="370" y="210" width="100" height="80" /> | ||
</bpmndi:BPMNShape> | ||
<bpmndi:BPMNEdge id="Association_0x72gur_di" bpmnElement="Association_0x72gur"> | ||
<di:waypoint x="300" y="188" /> | ||
<di:waypoint x="300" y="250" /> | ||
<di:waypoint x="370" y="250" /> | ||
</bpmndi:BPMNEdge> | ||
<bpmndi:BPMNShape id="Event_0njauji_di" bpmnElement="Compensation_Boundary_Event"> | ||
<dc:Bounds x="282" y="152" width="36" height="36" /> | ||
</bpmndi:BPMNShape> | ||
<bpmndi:BPMNEdge id="Flow_1ank1yi_di" bpmnElement="Flow_1ank1yi"> | ||
<di:waypoint x="188" y="130" /> | ||
<di:waypoint x="240" y="130" /> | ||
</bpmndi:BPMNEdge> | ||
</bpmndi:BPMNPlane> | ||
</bpmndi:BPMNDiagram> | ||
</bpmn:definitions> |
80 changes: 80 additions & 0 deletions
80
test/spec/features/modeling/behavior/SetCompensationActivityAfterPasteBehaviorSpec.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import { | ||
bootstrapModeler, | ||
inject | ||
} from 'test/TestHelper'; | ||
|
||
import modelingModule from 'lib/features/modeling'; | ||
import coreModule from 'lib/core'; | ||
import { is } from 'lib/util/ModelUtil'; | ||
import copyPasteModule from 'lib/features/copy-paste'; | ||
|
||
import diagramXML from './SetCompensationActivityAfterPasteBehaviorSpec.bpmn'; | ||
|
||
|
||
describe('features/modeling/behavior - compensation activity after paste', function() { | ||
|
||
const testModules = [ | ||
copyPasteModule, | ||
coreModule, | ||
modelingModule | ||
]; | ||
|
||
beforeEach(bootstrapModeler(diagramXML, { modules: testModules })); | ||
|
||
|
||
describe('copy/paste compensation activity', function() { | ||
|
||
it('without boundary event', inject(function(canvas, elementRegistry, copyPaste) { | ||
|
||
// given | ||
copyPaste.copy([ elementRegistry.get('Compensation_Activity') ]); | ||
|
||
// when | ||
var copiedElements = copyPaste.paste({ | ||
element: canvas.getRootElement(), | ||
point: { | ||
x: 100, | ||
y: 100 | ||
} | ||
}); | ||
|
||
// then | ||
expect(copiedElements).to.have.lengthOf(1); | ||
const taskElement = copiedElements.find(element => is(element, 'bpmn:Task')); | ||
expect(taskElement.businessObject.isForCompensation).to.be.false; | ||
})); | ||
|
||
|
||
it('with boundary event', inject(function(canvas, elementRegistry, copyPaste) { | ||
|
||
// given | ||
copyPaste.copy([ | ||
elementRegistry.get('Compensation_Boundary_Task'), | ||
elementRegistry.get('Compensation_Activity') ]); | ||
|
||
// when | ||
var copiedElements = copyPaste.paste({ | ||
element: canvas.getRootElement(), | ||
point: { | ||
x: 100, | ||
y: 100 | ||
} | ||
}); | ||
|
||
// then | ||
expect(copiedElements).to.have.lengthOf(4); | ||
expect(copiedElements.filter(element => is(element, 'bpmn:Association'))).to.have.length(1); | ||
expect(copiedElements.filter(element => is(element, 'bpmn:BoundaryEvent'))).to.have.length(1); | ||
expect(copiedElements.filter(element => is(element, 'bpmn:Task'))).to.have.length(2); | ||
|
||
// verify that for every Task element, if businessObject.isForCompensation exists, it should be true | ||
copiedElements.filter(element => is(element, 'bpmn:Task')).forEach(taskElement => { | ||
if (Object.prototype.hasOwnProperty.call(taskElement.businessObject, 'isForCompensation')) { | ||
expect(taskElement.businessObject.isForCompensation).to.be.true; | ||
} | ||
}); | ||
})); | ||
|
||
}); | ||
|
||
}); |