Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: lint zeebe:bindingType #169

Merged
merged 1 commit into from
Aug 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading