Skip to content

Commit

Permalink
fix(modeling): handle close to {source,target} drop-on-flow
Browse files Browse the repository at this point in the history
Closes #1541
  • Loading branch information
nikku authored and fake-join[bot] committed Dec 3, 2021
1 parent 756617c commit 1ede893
Show file tree
Hide file tree
Showing 2 changed files with 165 additions and 43 deletions.
4 changes: 2 additions & 2 deletions lib/features/modeling/behavior/DropOnFlowBehavior.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,12 @@ export default function DropOnFlowBehavior(eventBus, bpmnRules, modeling) {
dockingPoint = intersection.bendpoint ? waypoints[intersection.index] : mid;

// if last waypointBefore is inside shape's bounds, ignore docking point
if (!isPointInsideBBox(shape, waypointsBefore[waypointsBefore.length-1])) {
if (waypointsBefore.length === 1 || !isPointInsideBBox(shape, waypointsBefore[waypointsBefore.length-1])) {
waypointsBefore.push(copy(dockingPoint));
}

// if first waypointAfter is inside shape's bounds, ignore docking point
if (!isPointInsideBBox(shape, waypointsAfter[0])) {
if (waypointsAfter.length === 1 || !isPointInsideBBox(shape, waypointsAfter[0])) {
waypointsAfter.unshift(copy(dockingPoint));
}
}
Expand Down
204 changes: 163 additions & 41 deletions test/spec/features/modeling/behavior/DropOnFlowBehaviorSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,60 +38,182 @@ describe('modeling/behavior - drop on connection', function() {

describe('create', function() {

it('should connect start -> target -> end', inject(
function(modeling, elementRegistry, elementFactory) {
describe('should connect start -> target -> end', function() {

// given
var intermediateThrowEvent = elementFactory.createShape({
type: 'bpmn:IntermediateThrowEvent'
});
it('connection middle', inject(
function(modeling, elementRegistry, elementFactory) {

var startEvent = elementRegistry.get('StartEvent'),
sequenceFlow = elementRegistry.get('SequenceFlow_1'),
task = elementRegistry.get('Task_1');
// given
var intermediateThrowEvent = elementFactory.createShape({
type: 'bpmn:IntermediateThrowEvent'
});

var originalWaypoints = sequenceFlow.waypoints;
var startEvent = elementRegistry.get('StartEvent'),
sequenceFlow = elementRegistry.get('SequenceFlow_1'),
task = elementRegistry.get('Task_1');

var dropPosition = { x: 340, y: 120 }; // first bendpoint
var originalWaypoints = sequenceFlow.waypoints;

// when
var newShape = modeling.createShape(
intermediateThrowEvent,
dropPosition,
sequenceFlow
);
var dropPosition = { x: 340, y: 120 }; // first bendpoint

// then
var targetConnection = newShape.outgoing[0];
// when
var newShape = modeling.createShape(
intermediateThrowEvent,
dropPosition,
sequenceFlow
);

// new incoming connection
expect(newShape.incoming).to.have.length(1);
expect(newShape.incoming[0]).to.eql(sequenceFlow);
// then
var targetConnection = newShape.outgoing[0];

// new outgoing connection
expect(newShape.outgoing).to.have.length(1);
expect(targetConnection).to.exist;
expect(targetConnection.type).to.equal('bpmn:SequenceFlow');
// new incoming connection
expect(newShape.incoming).to.have.length(1);
expect(newShape.incoming[0]).to.eql(sequenceFlow);

expect(startEvent.outgoing[0]).to.equal(newShape.incoming[0]);
expect(task.incoming[1]).to.equal(newShape.outgoing[0]);
// new outgoing connection
expect(newShape.outgoing).to.have.length(1);
expect(targetConnection).to.exist;
expect(targetConnection.type).to.equal('bpmn:SequenceFlow');

// split target at insertion point
expect(sequenceFlow).to.have.waypoints(flatten([
originalWaypoints.slice(0, 1),
{ x: 322, y: 120 }
]));
expect(startEvent.outgoing[0]).to.equal(newShape.incoming[0]);
expect(task.incoming[1]).to.equal(newShape.outgoing[0]);

expect(sequenceFlow).to.have.endDocking(dropPosition);
// split target at insertion point
expect(sequenceFlow).to.have.waypoints(flatten([
originalWaypoints.slice(0, 1),
{ x: 322, y: 120 }
]));

expect(sequenceFlow).to.have.endDocking(dropPosition);

expect(targetConnection).to.have.waypoints(flatten([
{ x: 340, y: 138 },
originalWaypoints.slice(2)
]));

expect(targetConnection).to.have.startDocking(dropPosition);
}
));


it('close to source', inject(
function(modeling, elementRegistry, elementFactory) {

// given
var dropElement = elementFactory.createShape({
type: 'bpmn:IntermediateThrowEvent'
});

var start = elementRegistry.get('Gateway_C'),
flow = elementRegistry.get('SequenceFlow_F'),
end = elementRegistry.get('Task_B');

var originalWaypoints = flow.waypoints.slice();

var dropPosition = { x: 495, y: 540 }; // overlapping source

// when
var newShape = modeling.createShape(
dropElement,
dropPosition,
flow
);

// then
var targetConnection = newShape.outgoing[0];

// new incoming connection
expect(newShape.incoming).to.have.length(1);
expect(newShape.incoming[0]).to.equal(flow);

// new outgoing connection
expect(newShape.outgoing).to.have.length(1);
expect(targetConnection).to.exist;
expect(targetConnection.type).to.equal('bpmn:SequenceFlow');

expect(start.outgoing[0]).to.equal(newShape.incoming[0]);
expect(end.incoming[0]).to.equal(newShape.outgoing[0]);

// split target at insertion point
expect(flow).to.have.waypoints(flatten([
originalWaypoints.slice(0, 1),
[
{ x: 477, y: 540 }
]
]));

expect(flow).to.have.endDocking(dropPosition);

expect(targetConnection).to.have.waypoints(flatten([
{ x: 513, y: 540 },
originalWaypoints.slice(1)
]));

expect(targetConnection).to.have.startDocking(dropPosition);
}
));


it('close to target', inject(
function(modeling, elementRegistry, elementFactory) {

// given
var dropElement = elementFactory.createShape({
type: 'bpmn:IntermediateThrowEvent'
});

var start = elementRegistry.get('Gateway_C'),
flow = elementRegistry.get('SequenceFlow_F'),
end = elementRegistry.get('Task_B');

var originalWaypoints = flow.waypoints.slice();

var dropPosition = { x: 625, y: 540 }; // overlapping target

// when
var newShape = modeling.createShape(
dropElement,
dropPosition,
flow
);

// then
var targetConnection = newShape.outgoing[0];

// new incoming connection
expect(newShape.incoming).to.have.length(1);
expect(newShape.incoming[0]).to.equal(flow);

// new outgoing connection
expect(newShape.outgoing).to.have.length(1);
expect(targetConnection).to.exist;
expect(targetConnection.type).to.equal('bpmn:SequenceFlow');

expect(start.outgoing[0]).to.equal(newShape.incoming[0]);
expect(end.incoming[0]).to.equal(newShape.outgoing[0]);

// split target at insertion point
expect(flow).to.have.waypoints(flatten([
originalWaypoints.slice(0, 1),
[
{ x: 607, y: 540 }
]
]));

expect(flow).to.have.endDocking(dropPosition);

expect(targetConnection).to.have.waypoints(flatten([
{ x: 643, y: 540 },
originalWaypoints.slice(1)
]));

expect(targetConnection).to.have.startDocking(dropPosition);
}
));

});

expect(targetConnection).to.have.waypoints(flatten([
{ x: 340, y: 138 },
originalWaypoints.slice(2)
]));

expect(targetConnection).to.have.startDocking(dropPosition);
}
));


it('should connect start -> target', inject(
Expand Down

0 comments on commit 1ede893

Please sign in to comment.