diff --git a/index.js b/index.js index 6fdc492..20c5838 100644 --- a/index.js +++ b/index.js @@ -91,7 +91,8 @@ const camundaCloud86Rules = withConfig({ 'duplicate-execution-listeners': 'error', 'execution-listener': 'error', 'priority-definition': 'error', - 'version-tag': 'error' + 'version-tag': 'error', + 'zeebe-user-task': 'warn', }, { version: '8.6' }); const camundaCloud87Rules = withConfig({ @@ -162,6 +163,7 @@ const rules = { 'no-zeebe-properties': './rules/camunda-cloud/no-zeebe-properties', 'no-zeebe-user-task': './rules/camunda-cloud/no-zeebe-user-task', 'priority-definition': './rules/camunda-cloud/priority-definition', + 'zeebe-user-task': './rules/camunda-cloud/zeebe-user-task', 'secrets': './rules/camunda-cloud/secrets', 'sequence-flow-condition': './rules/camunda-cloud/sequence-flow-condition', 'signal-reference': './rules/camunda-cloud/signal-reference', diff --git a/rules/camunda-cloud/zeebe-user-task.js b/rules/camunda-cloud/zeebe-user-task.js new file mode 100644 index 0000000..97e1f7f --- /dev/null +++ b/rules/camunda-cloud/zeebe-user-task.js @@ -0,0 +1,25 @@ +const { is } = require('bpmnlint-utils'); + +const { reportErrors } = require('../utils/reporter'); + +const { skipInNonExecutableProcess } = require('../utils/rule'); + +const { hasExtensionElement } = require('../utils/element'); + +module.exports = skipInNonExecutableProcess(function() { + function check(node, reporter) { + if (!is(node, 'bpmn:UserTask')) { + return; + } + + const errors = hasExtensionElement(node, 'zeebe:UserTask', node); + + if (errors && errors.length) { + reportErrors(node, reporter, errors); + } + } + + return { + check + }; +}); diff --git a/test/camunda-cloud/integration/zeebe-user-task-errors.bpmn b/test/camunda-cloud/integration/zeebe-user-task-errors.bpmn new file mode 100644 index 0000000..03c9c1a --- /dev/null +++ b/test/camunda-cloud/integration/zeebe-user-task-errors.bpmn @@ -0,0 +1,18 @@ + + + + + + + + + + + diff --git a/test/camunda-cloud/integration/zeebe-user-task.bpmn b/test/camunda-cloud/integration/zeebe-user-task.bpmn new file mode 100644 index 0000000..97895fb --- /dev/null +++ b/test/camunda-cloud/integration/zeebe-user-task.bpmn @@ -0,0 +1,17 @@ + + + + + + + + + + diff --git a/test/camunda-cloud/integration/zeebe-user-task.spec.js b/test/camunda-cloud/integration/zeebe-user-task.spec.js new file mode 100644 index 0000000..238afb6 --- /dev/null +++ b/test/camunda-cloud/integration/zeebe-user-task.spec.js @@ -0,0 +1,75 @@ +const { expect } = require('chai'); + +const Linter = require('bpmnlint/lib/linter'); + +const NodeResolver = require('bpmnlint/lib/resolver/node-resolver'); + +const { readModdle } = require('../../helper'); + +const versions = [ + '8.6', + '8.7' +]; + +describe('integration - zeebe-user-task', 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/zeebe-user-task.bpmn'); + + // when + const reports = await linter.lint(root); + + // then + expect(reports[ 'camunda-compat/zeebe-user-task' ]).to.be.undefined; + }); + + }); + + + describe('errors', function() { + + it('should have errors', async function() { + + // given + const { root } = await readModdle('test/camunda-cloud/integration/zeebe-user-task-errors.bpmn'); + + // when + const reports = await linter.lint(root); + + // then + expect(reports[ 'camunda-compat/zeebe-user-task' ]).to.exist; + expect(reports[ 'camunda-compat/zeebe-user-task' ]).to.have.lengthOf(1); + + const [ error ] = reports[ 'camunda-compat/zeebe-user-task' ]; + + expect(error.message).to.equal('Element of type must have one extension element of type '); + expect(error.id).to.equal('UserTask_1'); + }); + + }); + + }); + + }); + +}); diff --git a/test/camunda-cloud/zeebe-user-task.spec.js b/test/camunda-cloud/zeebe-user-task.spec.js new file mode 100644 index 0000000..95efe9e --- /dev/null +++ b/test/camunda-cloud/zeebe-user-task.spec.js @@ -0,0 +1,52 @@ +const RuleTester = require('bpmnlint/lib/testers/rule-tester'); + +const rule = require('../../rules/camunda-cloud/zeebe-user-task'); + +const { + createModdle, + createProcess, +} = require('../helper'); + +const { ERROR_TYPES } = require('../../rules/utils/element'); + +const valid = [ + { + name: 'UserTask with one zeebe:UserTask extension element', + moddleElement: createModdle(createProcess(` + + + + + + `)) + } +]; + +const invalid = [ + { + name: 'UserTask with no zeebe:UserTask extension element (invalid if required)', + moddleElement: createModdle(createProcess(` + + + + + + `)), + report: { + id: 'UserTask_5', + message: 'Element of type must have one extension element of type ', + path: [], + data: { + type: ERROR_TYPES.EXTENSION_ELEMENT_REQUIRED, + node: 'UserTask_5', + parentNode: null, + requiredExtensionElement: 'zeebe:UserTask' + } + } + } +]; + +RuleTester.verify('zeebe-user-task', rule, { + valid, + invalid +}); diff --git a/test/config/configs.spec.js b/test/config/configs.spec.js index 290536b..8e97d75 100644 --- a/test/config/configs.spec.js +++ b/test/config/configs.spec.js @@ -385,6 +385,7 @@ describe('configs', function() { 'no-multiple-none-start-events' : [ 'error', { version: '8.6' } ], 'no-task-listeners': [ 'error', { version: '8.6' } ], 'priority-definition': [ 'error', { version: '8.6' } ], + 'zeebe-user-task': [ 'warn', { version: '8.6' } ], 'secrets': [ 'warn', { version: '8.6' } ], 'sequence-flow-condition': [ 'error', { version: '8.6' } ], 'signal-reference': [ 'error', { version: '8.6' } ], @@ -420,6 +421,7 @@ describe('configs', function() { 'no-loop': [ 'error', { version: '8.7' } ], 'no-multiple-none-start-events' : [ 'error', { version: '8.7' } ], 'priority-definition': [ 'error', { version: '8.7' } ], + 'zeebe-user-task': [ 'warn', { version: '8.7' } ], 'secrets': [ 'warn', { version: '8.7' } ], 'sequence-flow-condition': [ 'error', { version: '8.7' } ], 'signal-reference': [ 'error', { version: '8.7' } ], @@ -495,6 +497,7 @@ describe('configs', function() { 'no-zeebe-properties': 'error', 'no-zeebe-user-task': 'error', 'priority-definition': 'error', + 'zeebe-user-task': 'warn', 'secrets': 'warn', 'sequence-flow-condition': 'error', 'signal-reference': 'error',