Skip to content

Commit

Permalink
feat: add candidate users rule
Browse files Browse the repository at this point in the history
  • Loading branch information
philippfromme committed Jan 20, 2023
1 parent 0d3a7d4 commit bb275d6
Show file tree
Hide file tree
Showing 7 changed files with 260 additions and 1 deletion.
3 changes: 2 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const camundaCloud10Rules = {
'executable-process': 'error',
'loop-characteristics': 'error',
'message-reference': 'error',
'no-candidate-users': 'error',
'no-expression': [ 'error', { version: '1.0' } ],
'no-template': 'error',
'no-zeebe-properties': 'error',
Expand Down Expand Up @@ -62,7 +63,7 @@ const camundaCloud81Rules = {
};

const camundaCloud82Rules = {
...camundaCloud81Rules,
...omit(camundaCloud81Rules, 'no-candidate-users'),
'implementation': [ 'error', { version: '8.2' } ],
'element-type': [ 'error', { version: '8.2' } ],
'no-expression': [ 'error', { version: '8.2' } ],
Expand Down
37 changes: 37 additions & 0 deletions rules/no-candidate-users.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
const { is } = require('bpmnlint-utils');

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

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

module.exports = function() {
function check(node, reporter) {
if (!is(node, 'bpmn:UserTask')) {
return;
}

const assignmentDefinition = findExtensionElement(node, 'zeebe:AssignmentDefinition');

if (!assignmentDefinition) {
return;
}

const errors = hasProperties(assignmentDefinition, {
candidateUsers: {
allowed: false,
allowedVersion: '8.2'
}
}, node);

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

return {
check
};
};
17 changes: 17 additions & 0 deletions test/camunda-cloud/integration/no-candidate-users-errors.bpmn
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?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_0pauhry" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.7.0" modeler:executionPlatform="Camunda Cloud" modeler:executionPlatformVersion="8.1.0">
<bpmn:process id="Process_1" isExecutable="true">
<bpmn:userTask id="UserTask_1">
<bpmn:extensionElements>
<zeebe:assignmentDefinition candidateUsers="foo" />
</bpmn:extensionElements>
</bpmn:userTask>
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
<bpmndi:BPMNShape id="Activity_1wvucw6_di" bpmnElement="UserTask_1">
<dc:Bounds x="160" y="80" width="100" height="80" />
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
17 changes: 17 additions & 0 deletions test/camunda-cloud/integration/no-candidate-users.bpmn
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?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_0pauhry" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.7.0" modeler:executionPlatform="Camunda Cloud" modeler:executionPlatformVersion="8.1.0">
<bpmn:process id="Process_1" isExecutable="true">
<bpmn:userTask id="UserTask_1">
<bpmn:extensionElements>
<zeebe:assignmentDefinition candidateGroups="foo" />
</bpmn:extensionElements>
</bpmn:userTask>
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
<bpmndi:BPMNShape id="Activity_1wvucw6_di" bpmnElement="UserTask_1">
<dc:Bounds x="160" y="80" width="100" height="80" />
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
123 changes: 123 additions & 0 deletions test/camunda-cloud/integration/no-candidate-users.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
const { expect } = require('chai');

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

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

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

describe('integration - no-candidate-users', function() {

[
'1.0',
'1.1',
'1.2',
'1.3',
'8.0',
'8.1'
].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-candidate-users.bpmn');

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

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

});


describe('errors', function() {

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

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

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

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

});

});

});


[
'8.2'
].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-candidate-users.bpmn');

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

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


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

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

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

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

});

});

});

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

const rule = require('../../rules/no-candidate-users');

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

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

const valid = [
{
name: 'user task',
moddleElement: createModdle(createProcess(`
<bpmn:userTask id="UserTask_1">
<bpmn:extensionElements>
<zeebe:assignmentDefinition candidateGroups="foo" />
</bpmn:extensionElements>
</bpmn:userTask>
`))
}
];

const invalid = [
{
name: 'user task',
moddleElement: createModdle(createProcess(`
<bpmn:userTask id="UserTask_1">
<bpmn:extensionElements>
<zeebe:assignmentDefinition candidateUsers="foo" />
</bpmn:extensionElements>
</bpmn:userTask>
`)),
report: {
id: 'UserTask_1',
message: 'Property <candidateUsers> only allowed by Camunda Platform 8.2 or newer',
path: [
'extensionElements',
'values',
0,
'candidateUsers'
],
data: {
type: ERROR_TYPES.PROPERTY_NOT_ALLOWED,
node: 'zeebe:AssignmentDefinition',
parentNode: 'UserTask_1',
property: 'candidateUsers',
allowedVersion: '8.2'
}
}
}
];

RuleTester.verify('no-candidate-users', rule, {
valid,
invalid
});
6 changes: 6 additions & 0 deletions test/config/configs.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ describe('configs', function() {
'feel': 'error',
'loop-characteristics': 'error',
'message-reference': 'error',
'no-candidate-users': 'error',
'no-expression': [ 'error', { version: '1.0' } ],
'no-template': 'error',
'no-zeebe-properties': 'error',
Expand All @@ -36,6 +37,7 @@ describe('configs', function() {
'feel': 'error',
'loop-characteristics': 'error',
'message-reference': 'error',
'no-candidate-users': 'error',
'no-expression': [ 'error', { version: '1.1' } ],
'no-template': 'error',
'no-zeebe-properties': 'error',
Expand All @@ -57,6 +59,7 @@ describe('configs', function() {
'feel': 'error',
'loop-characteristics': 'error',
'message-reference': 'error',
'no-candidate-users': 'error',
'no-expression': [ 'error', { version: '1.2' } ],
'no-template': 'error',
'no-zeebe-properties': 'error',
Expand All @@ -78,6 +81,7 @@ describe('configs', function() {
'feel': 'error',
'loop-characteristics': 'error',
'message-reference': 'error',
'no-candidate-users': 'error',
'no-expression': [ 'error', { version: '1.3' } ],
'no-template': 'error',
'no-zeebe-properties': 'error',
Expand All @@ -99,6 +103,7 @@ describe('configs', function() {
'feel': 'error',
'loop-characteristics': 'error',
'message-reference': 'error',
'no-candidate-users': 'error',
'no-expression': [ 'error', { version: '8.0' } ],
'no-zeebe-properties': 'error',
'sequence-flow-condition': 'error',
Expand All @@ -120,6 +125,7 @@ describe('configs', function() {
'inclusive-gateway': 'error',
'loop-characteristics': 'error',
'message-reference': 'error',
'no-candidate-users': 'error',
'no-expression': [ 'error', { version: '8.1' } ],
'sequence-flow-condition': 'error',
'subscription': 'error',
Expand Down

0 comments on commit bb275d6

Please sign in to comment.