fix(modeling): unset gateway default on default flow delete

Closes #505
This commit is contained in:
Vladimirs Katusenoks 2016-04-04 16:11:34 +02:00 committed by Nico Rehwaldt
parent 23048cac7b
commit 60720c8ae7
4 changed files with 184 additions and 0 deletions

View File

@ -0,0 +1,55 @@
'use strict';
var inherits = require('inherits');
var CommandInterceptor = require('diagram-js/lib/command/CommandInterceptor');
var is = require('../../../util/ModelUtil').is,
getBusinessObject = require('../../../util/ModelUtil').getBusinessObject;
/**
* A behavior that unsets the Default property of
* sequence flow source on element delete, if the
* removed element is the Gateway or Task's default flow.
*
* @param {EventBus} eventBus
* @param {Modeling} modeling
*/
function DeleteSequenceFlowBehavior(eventBus, modeling) {
CommandInterceptor.call(this, eventBus);
this.preExecute('connection.delete', function(event) {
var context = event.context,
connection = context.connection,
source = connection.source;
if (isDefaultFlow(connection, source)) {
modeling.updateProperties(source, {
'default': null
});
}
});
}
inherits(DeleteSequenceFlowBehavior, CommandInterceptor);
DeleteSequenceFlowBehavior.$inject = [ 'eventBus', 'modeling' ];
module.exports = DeleteSequenceFlowBehavior;
/////// helpers ///////////////////////////
function isDefaultFlow(connection, source) {
if (!is(connection, 'bpmn:SequenceFlow')) {
return false;
}
var sourceBo = getBusinessObject(source),
sequenceFlow = getBusinessObject(connection);
return sourceBo.get('default') === sequenceFlow;
}

View File

@ -13,6 +13,7 @@ module.exports = {
'replaceConnectionBehavior', 'replaceConnectionBehavior',
'replaceElementBehaviour', 'replaceElementBehaviour',
'resizeLaneBehavior', 'resizeLaneBehavior',
'unsetDefaultFlowBehavior',
'updateFlowNodeRefsBehavior' 'updateFlowNodeRefsBehavior'
], ],
appendBehavior: [ 'type', require('./AppendBehavior') ], appendBehavior: [ 'type', require('./AppendBehavior') ],
@ -28,5 +29,6 @@ module.exports = {
replaceConnectionBehavior: [ 'type', require('./ReplaceConnectionBehavior') ], replaceConnectionBehavior: [ 'type', require('./ReplaceConnectionBehavior') ],
replaceElementBehaviour: [ 'type', require('./ReplaceElementBehaviour') ], replaceElementBehaviour: [ 'type', require('./ReplaceElementBehaviour') ],
resizeLaneBehavior: [ 'type', require('./ResizeLaneBehavior') ], resizeLaneBehavior: [ 'type', require('./ResizeLaneBehavior') ],
unsetDefaultFlowBehavior: [ 'type', require('./UnsetDefaultFlowBehavior') ],
updateFlowNodeRefsBehavior: [ 'type', require('./UpdateFlowNodeRefsBehavior') ] updateFlowNodeRefsBehavior: [ 'type', require('./UpdateFlowNodeRefsBehavior') ]
}; };

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn">
<bpmn:process id="Process_1" isExecutable="false">
<bpmn:exclusiveGateway id="exclusive-gateway" default="flow-default">
<bpmn:outgoing>flow-default</bpmn:outgoing>
<bpmn:outgoing>flow-normal</bpmn:outgoing>
</bpmn:exclusiveGateway>
<bpmn:task id="task-default">
<bpmn:incoming>flow-default</bpmn:incoming>
</bpmn:task>
<bpmn:sequenceFlow id="flow-default" sourceRef="exclusive-gateway" targetRef="task-default" />
<bpmn:task id="task-normal">
<bpmn:incoming>flow-normal</bpmn:incoming>
</bpmn:task>
<bpmn:sequenceFlow id="flow-normal" sourceRef="exclusive-gateway" targetRef="task-normal" />
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
<bpmndi:BPMNShape id="ExclusiveGateway_1kqn7y5_di" bpmnElement="exclusive-gateway" isMarkerVisible="true">
<dc:Bounds x="312" y="105" width="50" height="50" />
<bpmndi:BPMNLabel>
<dc:Bounds x="292" y="155" width="90" height="20" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Task_000sfne_di" bpmnElement="task-default">
<dc:Bounds x="561" y="90" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_0xihk8q_di" bpmnElement="flow-default">
<di:waypoint xsi:type="dc:Point" x="362" y="130" />
<di:waypoint xsi:type="dc:Point" x="561" y="130" />
<bpmndi:BPMNLabel>
<dc:Bounds x="416.5" y="120" width="90" height="20" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Task_08sfs0b_di" bpmnElement="task-normal">
<dc:Bounds x="561" y="272" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="SequenceFlow_07cihrc_di" bpmnElement="flow-normal">
<di:waypoint xsi:type="dc:Point" x="337" y="155" />
<di:waypoint xsi:type="dc:Point" x="337" y="312" />
<di:waypoint xsi:type="dc:Point" x="561" y="312" />
<bpmndi:BPMNLabel>
<dc:Bounds x="292" y="223.5" width="90" height="20" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>

View File

@ -0,0 +1,79 @@
'use strict';
/* global bootstrapModeler, inject */
var modelingModule = require('../../../../../lib/features/modeling'),
coreModule = require('../../../../../lib/core');
describe('features/modeling - delete default connection', function() {
var testModules = [ coreModule, modelingModule ];
var processDiagramXML = require('./UnsetDefaultFlowBehaviorSpec.bpmn');
beforeEach(bootstrapModeler(processDiagramXML, { modules: testModules }));
var gateway,
defaultConnection,
defaultTask,
normalConnection;
beforeEach(inject(function(elementRegistry) {
gateway = elementRegistry.get('exclusive-gateway');
defaultConnection = elementRegistry.get('flow-default');
defaultTask = elementRegistry.get('task-default');
normalConnection = elementRegistry.get('flow-normal');
}));
it('should remove default connection', inject(function(modeling) {
// when
modeling.removeConnection(defaultConnection);
// then
expect(defaultConnection.parent).to.be.null;
expect(gateway.businessObject.default).to.be.null; //.property('default');
}));
it('should revert default connection', inject(function(modeling, commandStack) {
// given
modeling.removeConnection(defaultConnection);
// when
commandStack.undo();
// then
expect(defaultConnection.parent).to.be.not.null;
expect(gateway.businessObject.default).to.eql(defaultConnection.businessObject);
}));
it('should NOT remove default connection on removing other connections', inject(function(modeling) {
// when
modeling.removeConnection(normalConnection);
// then
expect(normalConnection.parent).to.be.null;
expect(defaultConnection.parent).to.be.not.null;
expect(gateway.businessObject.default).to.eql(defaultConnection.businessObject);
}));
it('should NOT remove default connection on restoring other connections', inject(function(modeling, commandStack) {
// given
modeling.removeConnection(normalConnection);
// when
commandStack.undo();
// then
expect(normalConnection.parent).to.be.not.null;
expect(defaultConnection.parent).to.be.not.null;
expect(gateway.businessObject.default).to.eql(defaultConnection.businessObject);
}));
});