Skip to content

Commit

Permalink
feat: lint zeebe:bindingType
Browse files Browse the repository at this point in the history
  • Loading branch information
philippfromme committed Aug 1, 2024
1 parent fda8c18 commit 5f3ab3f
Show file tree
Hide file tree
Showing 7 changed files with 315 additions and 1 deletion.
8 changes: 7 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const camundaCloud10Rules = withConfig({
'executable-process': 'error',
'loop-characteristics': 'error',
'message-reference': 'error',
'no-binding-type': 'error',
'no-candidate-users': 'error',
'no-execution-listeners': 'error',
'no-expression': 'error',
Expand Down Expand Up @@ -77,7 +78,11 @@ const camundaCloud85Rules = withConfig({
}, { version: '8.5' });

const camundaCloud86Rules = withConfig({
...omit(camundaCloud85Rules, [ 'inclusive-gateway', 'no-execution-listeners' ]),
...omit(camundaCloud85Rules, [
'inclusive-gateway',
'no-binding-type',
'no-execution-listeners'
]),
'duplicate-execution-listeners': 'error',
'execution-listener': 'error'
}, { version: '8.6' });
Expand Down Expand Up @@ -124,6 +129,7 @@ const rules = {
'link-event': './rules/camunda-cloud/link-event',
'loop-characteristics': './rules/camunda-cloud/loop-characteristics',
'message-reference': './rules/camunda-cloud/message-reference',
'no-binding-type': './rules/camunda-cloud/no-binding-type',
'no-candidate-users': './rules/camunda-cloud/no-candidate-users',
'no-execution-listeners': './rules/camunda-cloud/no-execution-listeners',
'no-expression': './rules/camunda-cloud/no-expression',
Expand Down
44 changes: 44 additions & 0 deletions rules/camunda-cloud/no-binding-type.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const { isAny } = require('bpmnlint-utils');

const { hasProperties, findExtensionElement } = require('../utils/element');

const { reportErrors } = require('../utils/reporter');

const { skipInNonExecutableProcess } = require('../utils/rule');

module.exports = skipInNonExecutableProcess(function() {
function check(node, reporter) {
if (!isAny(node, [
'bpmn:BusinessRuleTask',
'bpmn:CallActivity',
'bpmn:UserTask'
])) {
return;
}

const extensionElement = findExtensionElement(node, [
'zeebe:CalledDecision',
'zeebe:CalledElement',
'zeebe:FormDefinition'
]);

if (!extensionElement) {
return;
}

const errors = hasProperties(extensionElement, {
bindingType: {
allowed: (value) => !value || value === 'latest',
allowedVersion: '8.6'
}
}, node);

if (errors && errors.length) {
reportErrors(node, reporter, errors);
}
}

return {
check
};
});
25 changes: 25 additions & 0 deletions test/camunda-cloud/integration/no-binding-type-errors.bpmn
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?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:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:zeebe="http://camunda.org/schema/zeebe/1.0" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.23.0" modeler:executionPlatform="Camunda Cloud" modeler:executionPlatformVersion="8.5.0">
<bpmn:process id="Process_1" isExecutable="true">
<bpmn:callActivity id="CallActivity_1">
<bpmn:extensionElements>
<zeebe:calledElement processId="foo" propagateAllChildVariables="false" />
</bpmn:extensionElements>
</bpmn:callActivity>
<bpmn:callActivity id="CallActivity_2">
<bpmn:extensionElements>
<zeebe:calledElement processId="bar" propagateAllChildVariables="false" bindingType="deployment" />
</bpmn:extensionElements>
</bpmn:callActivity>
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
<bpmndi:BPMNShape id="Activity_0vsypvy_di" bpmnElement="CallActivity_1">
<dc:Bounds x="160" y="77" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_11gjd39_di" bpmnElement="CallActivity_2">
<dc:Bounds x="300" y="77" width="100" height="80" />
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
25 changes: 25 additions & 0 deletions test/camunda-cloud/integration/no-binding-type.bpmn
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?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:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:zeebe="http://camunda.org/schema/zeebe/1.0" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.23.0" modeler:executionPlatform="Camunda Cloud" modeler:executionPlatformVersion="8.5.0">
<bpmn:process id="Process_1" isExecutable="true">
<bpmn:callActivity id="CallActivity_1">
<bpmn:extensionElements>
<zeebe:calledElement processId="foo" propagateAllChildVariables="false" />
</bpmn:extensionElements>
</bpmn:callActivity>
<bpmn:callActivity id="CallActivity_2">
<bpmn:extensionElements>
<zeebe:calledElement processId="bar" propagateAllChildVariables="false" bindingType="latest" />
</bpmn:extensionElements>
</bpmn:callActivity>
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
<bpmndi:BPMNShape id="Activity_0vsypvy_di" bpmnElement="CallActivity_1">
<dc:Bounds x="160" y="77" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_11gjd39_di" bpmnElement="CallActivity_2">
<dc:Bounds x="300" y="77" width="100" height="80" />
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
77 changes: 77 additions & 0 deletions test/camunda-cloud/integration/no-binding-type.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
const { expect } = require('chai');

const Linter = require('bpmnlint/lib/linter');

const NodeResolver = require('bpmnlint/lib/resolver/node-resolver');

const { readModdle } = require('../../helper');

const versions = [
'1.0',
'1.1',
'1.2',
'1.3',
'8.0',
'8.1',
'8.2',
'8.3',
'8.4',
'8.5'
];

describe('integration - no-binding-type', function() {

versions.forEach(function(version) {

let linter;

beforeEach(function() {
linter = new Linter({
config: {
extends: `plugin:camunda-compat/camunda-cloud-${ version.replace('.', '-') }`
},
resolver: new NodeResolver()
});
});


describe(`Camunda Cloud ${ version }`, function() {

describe('no errors', function() {

it('should not have errors', async function() {

// given
const { root } = await readModdle('test/camunda-cloud/integration/no-binding-type.bpmn');

// when
const reports = await linter.lint(root);

// then
expect(reports[ 'camunda-compat/no-binding-type' ]).not.to.exist;
});

});


describe('errors', function() {

it('should have errors', async function() {

// given
const { root } = await readModdle('test/camunda-cloud/integration/no-binding-type-errors.bpmn');

// when
const reports = await linter.lint(root);

// then
expect(reports[ 'camunda-compat/no-binding-type' ]).to.exist;
});

});

});

});

});
126 changes: 126 additions & 0 deletions test/camunda-cloud/no-binding-type.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
const RuleTester = require('bpmnlint/lib/testers/rule-tester');

const rule = require('../../rules/camunda-cloud/no-binding-type');

const {
createDefinitions,
createModdle,
createProcess
} = require('../helper');

const { ERROR_TYPES } = require('../../rules/utils/element');

const valid = [
{
name: 'called element (latest)',
moddleElement: createModdle(createProcess(`
<bpmn:callActivity id="CallActivity_1">
<bpmn:extensionElements>
<zeebe:calledElement bindingType="latest" />
</bpmn:extensionElements>
</bpmn:callActivity>
`))
},
{
name: 'called element (deployment) (non-executable process)',
config: { version: '8.2' },
moddleElement: createModdle(createDefinitions(`
<bpmn:process id="Process_1">
<bpmn:callActivity id="CallActivity_1">
<bpmn:extensionElements>
<zeebe:calledElement bindingType="deployment" />
</bpmn:extensionElements>
</bpmn:callActivity>
</bpmn:process>
`))
}
];

const invalid = [
{
name: 'called decision (deployment)',
moddleElement: createModdle(createProcess(`
<bpmn:businessRuleTask id="BusinessRuleTask_1">
<bpmn:extensionElements>
<zeebe:calledDecision bindingType="deployment" />
</bpmn:extensionElements>
</bpmn:businessRuleTask>
`)),
report: {
id: 'BusinessRuleTask_1',
message: 'Property value of <deployment> only allowed by Camunda 8.6 or newer',
path: [
'extensionElements',
'values',
0,
'bindingType'
],
data: {
type: ERROR_TYPES.PROPERTY_VALUE_NOT_ALLOWED,
node: 'zeebe:CalledDecision',
parentNode: 'BusinessRuleTask_1',
property: 'bindingType',
allowedVersion: '8.6'
}
}
},
{
name: 'called element (deployment)',
moddleElement: createModdle(createProcess(`
<bpmn:callActivity id="CallActivity_1">
<bpmn:extensionElements>
<zeebe:calledElement bindingType="deployment" />
</bpmn:extensionElements>
</bpmn:callActivity>
`)),
report: {
id: 'CallActivity_1',
message: 'Property value of <deployment> only allowed by Camunda 8.6 or newer',
path: [
'extensionElements',
'values',
0,
'bindingType'
],
data: {
type: ERROR_TYPES.PROPERTY_VALUE_NOT_ALLOWED,
node: 'zeebe:CalledElement',
parentNode: 'CallActivity_1',
property: 'bindingType',
allowedVersion: '8.6'
}
}
},
{
name: 'form definition (deployment)',
moddleElement: createModdle(createProcess(`
<bpmn:userTask id="UserTask_1">
<bpmn:extensionElements>
<zeebe:formDefinition bindingType="deployment" />
</bpmn:extensionElements>
</bpmn:userTask>
`)),
report: {
id: 'UserTask_1',
message: 'Property value of <deployment> only allowed by Camunda 8.6 or newer',
path: [
'extensionElements',
'values',
0,
'bindingType'
],
data: {
type: ERROR_TYPES.PROPERTY_VALUE_NOT_ALLOWED,
node: 'zeebe:FormDefinition',
parentNode: 'UserTask_1',
property: 'bindingType',
allowedVersion: '8.6'
}
}
}
];

RuleTester.verify('no-binding-type', rule, {
valid,
invalid
});
Loading

0 comments on commit 5f3ab3f

Please sign in to comment.