From 9b68cb3af62c2fe88f21705ac2786b4a228e0dc3 Mon Sep 17 00:00:00 2001 From: Josh Wulf Date: Thu, 15 Jun 2023 21:55:32 +1200 Subject: [PATCH] Test Refactor ## Proposed Changes Refactor tests to use Operate --- jest.config.js | 1 + package-lock.json | 74 +++++++++++++++++++ package.json | 1 + src/__tests__/ lib/cancelProcesses.ts | 25 +++++++ .../Client-BroadcastSignal.spec.ts | 19 +++-- .../integration/Client-BrokenBpmn.spec.ts | 8 +- ...nt-CreateProcessInstanceWithResult.spec.ts | 55 +++++--------- .../integration/Client-DeployProcess.spec.ts | 14 +--- .../integration/Client-DeployResource.spec.ts | 36 ++++----- .../integration/Client-MessageStart.spec.ts | 30 +++----- .../Client-ModifyProcessInstance.spec.ts | 12 ++- .../integration/Client-PublishMessage.spec.ts | 30 +++----- .../integration/Client-ThrowError.spec.ts | 30 +++----- .../integration/Client-integration.spec.ts | 46 ++++-------- .../integration/Client-setVariables.spec.ts | 42 ++++------- .../integration/Client-startProcess.spec.ts | 55 +++++++------- src/lib/MockWorker.ts | 44 +++++++++++ 17 files changed, 297 insertions(+), 225 deletions(-) create mode 100644 src/__tests__/ lib/cancelProcesses.ts create mode 100644 src/lib/MockWorker.ts diff --git a/jest.config.js b/jest.config.js index 4b4cf68c..4a3f21f2 100644 --- a/jest.config.js +++ b/jest.config.js @@ -2,4 +2,5 @@ module.exports = { preset: 'ts-jest', testEnvironment: 'node', testPathIgnorePatterns: ['node_modules', 'dist'], + collectCoverageFrom: ['!src/__tests__/lib/cancelProcesses.ts'] } diff --git a/package-lock.json b/package-lock.json index 4cb73f56..1c5d13f0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,6 +43,7 @@ "jest": "^27.2.3", "jest-environment-node-debug": "^2.0.0", "lint-staged": "^11.0.0", + "operate-api-client": "^1.1.3", "prettier": "^1.19.1", "remark": "^13.0.0", "remark-cli": "^9.0.0", @@ -2535,6 +2536,25 @@ "node": ">=6" } }, + "node_modules/camunda-8-credentials-from-env": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/camunda-8-credentials-from-env/-/camunda-8-credentials-from-env-1.2.2.tgz", + "integrity": "sha512-uj2PY5/IoAgu0cHmeEUp+qmSXCtpQafStzGJ8ORYvyupBN/gVpdP9X+A+UlQRCGmApcaIuPUw8/9FsXig5NWXg==", + "dev": true, + "dependencies": { + "neon-env": "^0.1.1" + } + }, + "node_modules/camunda-saas-oauth": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/camunda-saas-oauth/-/camunda-saas-oauth-1.2.2.tgz", + "integrity": "sha512-Lll8YDmtjObiQf4k47rgacjeIEpIPqs2cY6guQmrg61UBcXSbcRWELK8fyq+fjEIL50msuo5B4IuHI5hKCb08w==", + "dev": true, + "dependencies": { + "camunda-8-credentials-from-env": "^1.2.2", + "got": "^11.8.5" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001448", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001448.tgz", @@ -7471,6 +7491,15 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, + "node_modules/neon-env": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/neon-env/-/neon-env-0.1.3.tgz", + "integrity": "sha512-Zo+L6Nm19gJrjyfhxn/ZDm8eIIDzr75o64ZhijBau4LNuhLzjEAteRg3gchIvgaN8XTo5BxN6iTNP5clZQ0agA==", + "dev": true, + "engines": { + "node": "^14.18 || >=16.0.0" + } + }, "node_modules/node-cleanup": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/node-cleanup/-/node-cleanup-2.1.2.tgz", @@ -7556,6 +7585,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/operate-api-client": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/operate-api-client/-/operate-api-client-1.1.3.tgz", + "integrity": "sha512-pOCVncvBfR0R9m5s0t1EqlIC/pqYOooyBdPP2ObphniTyIWYcXIw6xW9zgVi/uJznpkFtP/9m2kvaUmP0gOpgg==", + "dev": true, + "dependencies": { + "camunda-saas-oauth": "^1.2.0", + "got": "^11.8.5" + } + }, "node_modules/optionator": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", @@ -12415,6 +12454,25 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, + "camunda-8-credentials-from-env": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/camunda-8-credentials-from-env/-/camunda-8-credentials-from-env-1.2.2.tgz", + "integrity": "sha512-uj2PY5/IoAgu0cHmeEUp+qmSXCtpQafStzGJ8ORYvyupBN/gVpdP9X+A+UlQRCGmApcaIuPUw8/9FsXig5NWXg==", + "dev": true, + "requires": { + "neon-env": "^0.1.1" + } + }, + "camunda-saas-oauth": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/camunda-saas-oauth/-/camunda-saas-oauth-1.2.2.tgz", + "integrity": "sha512-Lll8YDmtjObiQf4k47rgacjeIEpIPqs2cY6guQmrg61UBcXSbcRWELK8fyq+fjEIL50msuo5B4IuHI5hKCb08w==", + "dev": true, + "requires": { + "camunda-8-credentials-from-env": "^1.2.2", + "got": "^11.8.5" + } + }, "caniuse-lite": { "version": "1.0.30001448", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001448.tgz", @@ -16102,6 +16160,12 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, + "neon-env": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/neon-env/-/neon-env-0.1.3.tgz", + "integrity": "sha512-Zo+L6Nm19gJrjyfhxn/ZDm8eIIDzr75o64ZhijBau4LNuhLzjEAteRg3gchIvgaN8XTo5BxN6iTNP5clZQ0agA==", + "dev": true + }, "node-cleanup": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/node-cleanup/-/node-cleanup-2.1.2.tgz", @@ -16169,6 +16233,16 @@ "mimic-fn": "^2.1.0" } }, + "operate-api-client": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/operate-api-client/-/operate-api-client-1.1.3.tgz", + "integrity": "sha512-pOCVncvBfR0R9m5s0t1EqlIC/pqYOooyBdPP2ObphniTyIWYcXIw6xW9zgVi/uJznpkFtP/9m2kvaUmP0gOpgg==", + "dev": true, + "requires": { + "camunda-saas-oauth": "^1.2.0", + "got": "^11.8.5" + } + }, "optionator": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", diff --git a/package.json b/package.json index 0d7f5e0c..547fd629 100644 --- a/package.json +++ b/package.json @@ -93,6 +93,7 @@ "jest": "^27.2.3", "jest-environment-node-debug": "^2.0.0", "lint-staged": "^11.0.0", + "operate-api-client": "^1.1.3", "prettier": "^1.19.1", "remark": "^13.0.0", "remark-cli": "^9.0.0", diff --git a/src/__tests__/ lib/cancelProcesses.ts b/src/__tests__/ lib/cancelProcesses.ts new file mode 100644 index 00000000..7609ef55 --- /dev/null +++ b/src/__tests__/ lib/cancelProcesses.ts @@ -0,0 +1,25 @@ +import { OperateApiClient } from 'operate-api-client' + +const operate = new OperateApiClient() + +export async function cancelProcesses(processDefinitionKey: string) { + const processes = await operate.searchProcessInstances({ + filter: { + processDefinitionKey: +processDefinitionKey + } + }) + await Promise.all(processes.items.map(item => + operate.deleteProcessInstance(+item.bpmnProcessId) + )) +} + + +function createClient() { + try { + return new OperateApiClient() + } catch (e) { + console.log(e.message) + console.log(`Running without access to Operate`) + return null + } +} diff --git a/src/__tests__/integration/Client-BroadcastSignal.spec.ts b/src/__tests__/integration/Client-BroadcastSignal.spec.ts index cf5d90f1..50a8411e 100644 --- a/src/__tests__/integration/Client-BroadcastSignal.spec.ts +++ b/src/__tests__/integration/Client-BroadcastSignal.spec.ts @@ -1,3 +1,4 @@ +import { cancelProcesses } from '../ lib/cancelProcesses' import { ZBClient } from '../..' // import { createUniqueTaskType } from '../../lib/createUniqueTaskType' import { CreateProcessInstanceResponse } from '../../lib/interfaces-grpc-1.0' @@ -6,11 +7,16 @@ process.env.ZEEBE_NODE_LOG_LEVEL = process.env.ZEEBE_NODE_LOG_LEVEL || 'NONE' jest.setTimeout(60000) -let zbc: ZBClient +const zbc = new ZBClient() +let pid: string let wf: CreateProcessInstanceResponse | undefined -beforeEach(() => { - zbc = new ZBClient() +beforeAll(async () => { + const res = await zbc.deployResource({ + processFilename: `./src/__tests__/testdata/Signal.bpmn` + }) + pid = res.deployments[0].process.bpmnProcessId + await cancelProcesses(pid) }) afterEach(async () => { @@ -20,11 +26,14 @@ afterEach(async () => { } } catch (e: any) { // console.log('Caught NOT FOUND') // @DEBUG - } finally { - await zbc.close() // Makes sure we don't forget to close connection } }) +afterAll(async () => { + await zbc.close() + await cancelProcesses(pid) +}) + test('Can start a process with a signal', () => new Promise(async resolve => { zbc.createWorker({ taskType: 'signal-service-task', diff --git a/src/__tests__/integration/Client-BrokenBpmn.spec.ts b/src/__tests__/integration/Client-BrokenBpmn.spec.ts index bd7e05c8..7d69e2bb 100644 --- a/src/__tests__/integration/Client-BrokenBpmn.spec.ts +++ b/src/__tests__/integration/Client-BrokenBpmn.spec.ts @@ -2,13 +2,9 @@ import { ZBClient } from '../..' process.env.ZEEBE_NODE_LOG_LEVEL = process.env.ZEEBE_NODE_LOG_LEVEL || 'NONE' -let zbc: ZBClient +const zbc = new ZBClient() -beforeEach(async () => { - zbc = new ZBClient() -}) - -afterEach(async () => { +afterAll(async () => { await zbc.close() // Makes sure we don't forget to close connection }) diff --git a/src/__tests__/integration/Client-CreateProcessInstanceWithResult.spec.ts b/src/__tests__/integration/Client-CreateProcessInstanceWithResult.spec.ts index 1e207746..0b7130c4 100644 --- a/src/__tests__/integration/Client-CreateProcessInstanceWithResult.spec.ts +++ b/src/__tests__/integration/Client-CreateProcessInstanceWithResult.spec.ts @@ -1,29 +1,32 @@ -import { ZBClient } from '../..' -import { createUniqueTaskType } from '../../lib/createUniqueTaskType' +import { cancelProcesses } from '../ lib/cancelProcesses' +import { DeployProcessResponse, ZBClient } from '../..' process.env.ZEEBE_NODE_LOG_LEVEL = process.env.ZEEBE_NODE_LOG_LEVEL || 'NONE' jest.setTimeout(25000) -let zbc: ZBClient +const zbc = new ZBClient() +let test1: DeployProcessResponse +let test2: DeployProcessResponse +let test3: DeployProcessResponse -beforeEach(async () => { - zbc = new ZBClient() +beforeAll(async () => { + test1 = await zbc.deployProcess('./src/__tests__/testdata/await-outcome.bpmn') + test2 = await zbc.deployProcess('./src/__tests__/testdata/await-outcome-long.bpmn') + test3 = await zbc.deployProcess('./src/__tests__/testdata/await-outcome.bpmn') + await cancelProcesses(test1.processes[0].bpmnProcessId) + await cancelProcesses(test2.processes[0].bpmnProcessId) + await cancelProcesses(test3.processes[0].bpmnProcessId) }) -afterEach(async () => { +afterAll(async () => { await zbc.close() // Makes sure we don't forget to close connection + await cancelProcesses(test1.processes[0].bpmnProcessId) + await cancelProcesses(test2.processes[0].bpmnProcessId) + await cancelProcesses(test3.processes[0].bpmnProcessId) }) test('Awaits a process outcome', async () => { - const { processId, bpmn } = createUniqueTaskType({ - bpmnFilePath: './src/__tests__/testdata/await-outcome.bpmn', - messages: [], - taskTypes: [], - }) - await zbc.deployProcess({ - definition: bpmn, - name: `Await-outcome-${processId}.bpmn`, - }) + const processId = test1.processes[0].bpmnProcessId const result = await zbc.createProcessInstanceWithResult(processId, { sourceValue: 5, }) @@ -31,15 +34,7 @@ test('Awaits a process outcome', async () => { }) test('can override the gateway timeout', async () => { - const { bpmn, processId } = createUniqueTaskType({ - bpmnFilePath: './src/__tests__/testdata/await-outcome-long.bpmn', - messages: [], - taskTypes: [], - }) - await zbc.deployProcess({ - definition: bpmn, - name: `Await-outcome-long-${processId}.bpmn`, - }) + const processId = test2.processes[0].bpmnProcessId const result = await zbc.createProcessInstanceWithResult({ bpmnProcessId: processId, requestTimeout: 25000, @@ -52,16 +47,7 @@ test('can override the gateway timeout', async () => { }) test('fetches a subset of variables', async () => { - zbc = new ZBClient() - const { bpmn, processId } = createUniqueTaskType({ - bpmnFilePath: './src/__tests__/testdata/await-outcome.bpmn', - messages: [], - taskTypes: [], - }) - await zbc.deployProcess({ - definition: bpmn, - name: `Await-outcome-${processId}.bpmn`, - }) + const processId = test3.processes[0].bpmnProcessId const result = await zbc.createProcessInstanceWithResult({ bpmnProcessId: processId, fetchVariables: ['otherValue'], @@ -70,7 +56,6 @@ test('fetches a subset of variables', async () => { sourceValue: 5, }, }) - // @TODO - uncomment when https://github.com/zeebe-io/zeebe/pull/3253 gets merged expect(result.variables.sourceValue).toBe(undefined) expect(result.variables.otherValue).toBe('rome') }) diff --git a/src/__tests__/integration/Client-DeployProcess.spec.ts b/src/__tests__/integration/Client-DeployProcess.spec.ts index 1c5c5159..1138570d 100644 --- a/src/__tests__/integration/Client-DeployProcess.spec.ts +++ b/src/__tests__/integration/Client-DeployProcess.spec.ts @@ -1,18 +1,10 @@ import { ZBClient } from '../../index' -import { createUniqueTaskType } from '../../lib/createUniqueTaskType' process.env.ZEEBE_NODE_LOG_LEVEL = process.env.ZEEBE_NODE_LOG_LEVEL || 'NONE' jest.setTimeout(20000) + test('deploys a process', async () => { const zbc = new ZBClient() - const { bpmn, processId } = createUniqueTaskType({ - bpmnFilePath: `./src/__tests__/testdata/Client-DeployWorkflow.bpmn`, - messages: [], - taskTypes: [], - }) - const result = await zbc.deployProcess({ - definition: bpmn, - name: `Client-DeployProcess-${processId}.bpmn`, - }) + const result = await zbc.deployProcess(`./src/__tests__/testdata/Client-DeployWorkflow.bpmn`) await zbc.close() - expect(result.processes[0].bpmnProcessId).toBe(processId) + expect(result.processes[0].bpmnProcessId).toBeTruthy() }) diff --git a/src/__tests__/integration/Client-DeployResource.spec.ts b/src/__tests__/integration/Client-DeployResource.spec.ts index d8df117f..3970991f 100644 --- a/src/__tests__/integration/Client-DeployResource.spec.ts +++ b/src/__tests__/integration/Client-DeployResource.spec.ts @@ -1,40 +1,41 @@ -import { ZBClient } from '../../index' -import { createUniqueTaskType } from '../../lib/createUniqueTaskType' +import { cancelProcesses } from '../ lib/cancelProcesses' +import { ZBClient, BpmnParser } from '../../index' import fs from 'fs' process.env.ZEEBE_NODE_LOG_LEVEL = process.env.ZEEBE_NODE_LOG_LEVEL || 'NONE' jest.setTimeout(20000) + +const zbc = new ZBClient() +const bpmnString = fs.readFileSync(`./src/__tests__/testdata/Client-DeployWorkflow.bpmn`, 'utf8') +const expectedPid = BpmnParser.getProcessId(bpmnString) + +beforeAll(async () => + await cancelProcesses(expectedPid) +) + +afterAll(async () => + await zbc.close() +) + test('deploys a process', async () => { - const zbc = new ZBClient() - const { bpmn, processId } = createUniqueTaskType({ - bpmnFilePath: `./src/__tests__/testdata/Client-DeployWorkflow.bpmn`, - messages: [], - taskTypes: [], - }) const result = await zbc.deployResource({ - process: bpmn, - name: `Client-DeployProcess-${processId}.bpmn`, + process: Buffer.from(bpmnString), + name: `Client-DeployWorkflow.bpmn`, }) - await zbc.close() - expect(result.deployments[0].process.bpmnProcessId).toBe(processId) + expect(result.deployments[0].process.bpmnProcessId).toBe(expectedPid) }) test('deploys a process from a file', async () => { - const zbc = new ZBClient() const result = await zbc.deployResource({ processFilename: `./src/__tests__/testdata/Client-DeployWorkflow.bpmn`, }) - await zbc.close() expect(result.deployments[0].process.version).toBeGreaterThanOrEqual(1) }) test('deploys a DMN table from a filename', async () => { - const zbc = new ZBClient() const result = await zbc.deployResource({ decisionFilename: './src/__tests__/testdata/quarantine-duration.dmn', }) - await zbc.close() expect(result.deployments[0].decision.decisionKey).not.toBeNull() }) test('deploys a DMN table', async () => { - const zbc = new ZBClient() const decision = fs.readFileSync( './src/__tests__/testdata/quarantine-duration.dmn' ) @@ -42,6 +43,5 @@ test('deploys a DMN table', async () => { decision, name: 'quarantine-duration.dmn', }) - await zbc.close() expect(result.deployments[0].decision.decisionKey).not.toBeNull() }) diff --git a/src/__tests__/integration/Client-MessageStart.spec.ts b/src/__tests__/integration/Client-MessageStart.spec.ts index aa82e939..28b0cf57 100644 --- a/src/__tests__/integration/Client-MessageStart.spec.ts +++ b/src/__tests__/integration/Client-MessageStart.spec.ts @@ -1,32 +1,24 @@ import { v4 as uuid } from 'uuid' -import { ZBClient } from '../..' -import { createUniqueTaskType } from '../../lib/createUniqueTaskType' +import { DeployProcessResponse, ZBClient } from '../..' +import { cancelProcesses } from '../ lib/cancelProcesses' process.env.ZEEBE_NODE_LOG_LEVEL = process.env.ZEEBE_NODE_LOG_LEVEL || 'NONE' jest.setTimeout(45000) -let zbc: ZBClient +let test1: DeployProcessResponse +const zbc = new ZBClient() -beforeEach(async () => { - zbc = new ZBClient() +beforeAll(async () => { + test1 = await zbc.deployProcess('./src/__tests__/testdata/Client-MessageStart.bpmn') + await cancelProcesses(test1.processes[0].bpmnProcessId) }) -afterEach(async () => { +afterAll(async () => { await zbc.close() + await cancelProcesses(test1.processes[0].bpmnProcessId) }) test('Can start a process with a message', () => new Promise(async done => { - const { bpmn, taskTypes, processId, messages } = createUniqueTaskType({ - bpmnFilePath: './src/__tests__/testdata/Client-MessageStart.bpmn', - messages: ['MSG-START_JOB'], - taskTypes: ['console-log-msg-start'], - }) - - const deploy = await zbc.deployProcess({ - definition: bpmn, - name: `Client-MessageStart-${processId}.bpmn`, - }) - expect(deploy.key).toBeTruthy() const randomId = uuid() @@ -34,7 +26,7 @@ test('Can start a process with a message', () => await new Promise(res => setTimeout(() => res(null), 1000)) await zbc.publishStartMessage({ - name: messages['MSG-START_JOB'], + name:'MSG-START_JOB', timeToLive: 2000, variables: { testKey: randomId, @@ -42,7 +34,7 @@ test('Can start a process with a message', () => }) zbc.createWorker({ - taskType: taskTypes['console-log-msg-start'], + taskType: 'console-log-msg-start', taskHandler: async job => { const res = await job.complete() expect(job.variables.testKey).toBe(randomId) // Makes sure the worker isn't responding to another message diff --git a/src/__tests__/integration/Client-ModifyProcessInstance.spec.ts b/src/__tests__/integration/Client-ModifyProcessInstance.spec.ts index 21ff6226..dadc72fa 100644 --- a/src/__tests__/integration/Client-ModifyProcessInstance.spec.ts +++ b/src/__tests__/integration/Client-ModifyProcessInstance.spec.ts @@ -1,13 +1,19 @@ -import { ZBClient } from "../../index"; +import { cancelProcesses } from "../ lib/cancelProcesses"; +import { DeployProcessResponse, ZBClient } from "../../index"; process.env.ZEEBE_NODE_LOG_LEVEL = process.env.ZEEBE_NODE_LOG_LEVEL || 'NONE' -let zbc: ZBClient +const zbc = new ZBClient() let pid: string -beforeEach(() => (zbc = new ZBClient())) +let test1: DeployProcessResponse + +beforeAll(async () => { + test1 = await zbc.deployProcess('./src/__tests__/testdata/Client-SkipFirstTask.bpmn') +}) afterEach(async () => { zbc.cancelProcessInstance(pid).catch(_ => _) await zbc.close() + await cancelProcesses(test1.processes[0].bpmnProcessId) }) test('Modify Process Instance', done =>{ diff --git a/src/__tests__/integration/Client-PublishMessage.spec.ts b/src/__tests__/integration/Client-PublishMessage.spec.ts index 2d063404..9f068712 100644 --- a/src/__tests__/integration/Client-PublishMessage.spec.ts +++ b/src/__tests__/integration/Client-PublishMessage.spec.ts @@ -1,40 +1,30 @@ import { v4 as uuid } from 'uuid' -import { ZBClient } from '../..' -import { createUniqueTaskType } from '../../lib/createUniqueTaskType' +import { DeployProcessResponse, ZBClient } from '../..' +import { cancelProcesses } from '../ lib/cancelProcesses' process.env.ZEEBE_NODE_LOG_LEVEL = process.env.ZEEBE_NODE_LOG_LEVEL || 'NONE' jest.setTimeout(45000) -let zbc: ZBClient +const zbc = new ZBClient() +let deploy: DeployProcessResponse -beforeEach(async () => { - zbc = new ZBClient() +beforeAll(async () => { + deploy = await zbc.deployProcess('./src/__tests__/testdata/Client-MessageStart.bpmn') }) -afterEach(async () => { +afterAll(async () => { await zbc.close() + await cancelProcesses(deploy.processes[0].bpmnProcessId) }) test('Can publish a message', () => new Promise(async done => { - const { bpmn, taskTypes, processId, messages } = createUniqueTaskType({ - bpmnFilePath: './src/__tests__/testdata/Client-MessageStart.bpmn', - messages: ['MSG-START_JOB'], - taskTypes: ['console-log-msg-start'], - }) - - const deploy = await zbc.deployProcess({ - definition: bpmn, - name: `Client-MessageStart-${processId}.bpmn`, - }) - expect(deploy.key).toBeTruthy() - const randomId = uuid() // Wait 1 second to make sure the deployment is complete await new Promise(res => setTimeout(() => res(null), 1000)) await zbc.publishMessage({ - name: messages['MSG-START_JOB'], + name: 'MSG-START_JOB', variables: { testKey: randomId, }, @@ -42,7 +32,7 @@ test('Can publish a message', () => }) zbc.createWorker({ - taskType: taskTypes['console-log-msg-start'], + taskType: 'console-log-msg-start', taskHandler: async job => { const res = await job.complete() expect(job.variables.testKey).toBe(randomId) // Makes sure the worker isn't responding to another message diff --git a/src/__tests__/integration/Client-ThrowError.spec.ts b/src/__tests__/integration/Client-ThrowError.spec.ts index cc992560..6100def5 100644 --- a/src/__tests__/integration/Client-ThrowError.spec.ts +++ b/src/__tests__/integration/Client-ThrowError.spec.ts @@ -1,39 +1,33 @@ import { Duration } from 'typed-duration' import { ZBClient } from '../..' -import { createUniqueTaskType } from '../../lib/createUniqueTaskType' +import { cancelProcesses } from '../ lib/cancelProcesses' process.env.ZEEBE_NODE_LOG_LEVEL = process.env.ZEEBE_NODE_LOG_LEVEL || 'NONE' jest.setTimeout(25000) -let zbc: ZBClient +let processId: string -beforeEach(async () => { - zbc = new ZBClient() +const zbc = new ZBClient() + +beforeAll(async () => { + processId = (await zbc.deployProcess('./src/__tests__/testdata/Client-ThrowError.bpmn')).processes[0].bpmnProcessId + cancelProcesses(processId) }) -afterEach(async () => { - await zbc.close() // Makes sure we don't forget to close connection +afterAll(async () => { + await zbc.close() + cancelProcesses(processId) }) test('Throws a business error that is caught in the process', async () => { - const { bpmn, taskTypes, processId } = createUniqueTaskType({ - bpmnFilePath: './src/__tests__/testdata/Client-ThrowError.bpmn', - messages: [], - taskTypes: ['throw-bpmn-error-task', 'sad-flow'], - }) - - await zbc.deployProcess({ - definition: bpmn, - name: `error-throw-bpmn-error-${processId}.bpmn`, - }) zbc.createWorker({ taskHandler: job => job.error('BUSINESS_ERROR', "Well, that didn't work"), - taskType: taskTypes['throw-bpmn-error-task'], + taskType: 'throw-bpmn-error-task', timeout: Duration.seconds.of(30), }) zbc.createWorker({ - taskType: taskTypes['sad-flow'], + taskType: 'sad-flow', taskHandler: job => job.complete({ bpmnErrorCaught: true, diff --git a/src/__tests__/integration/Client-integration.spec.ts b/src/__tests__/integration/Client-integration.spec.ts index a46998a9..b151c71a 100644 --- a/src/__tests__/integration/Client-integration.spec.ts +++ b/src/__tests__/integration/Client-integration.spec.ts @@ -1,22 +1,29 @@ +import { cancelProcesses } from '../ lib/cancelProcesses' import { ZBClient } from '../../index' -import { createUniqueTaskType } from '../../lib/createUniqueTaskType' -import { CreateProcessInstanceResponse } from '../../lib/interfaces-grpc-1.0' +import { CreateProcessInstanceResponse, DeployProcessResponse } from '../../lib/interfaces-grpc-1.0' process.env.ZEEBE_NODE_LOG_LEVEL = process.env.ZEEBE_NODE_LOG_LEVEL || 'NONE' jest.setTimeout(30000) -let zbc: ZBClient +const zbc = new ZBClient() let wf: CreateProcessInstanceResponse +let test1: DeployProcessResponse -beforeEach(() => { - zbc = new ZBClient() +beforeAll(async () => { + test1 = await zbc.deployProcess('./src/__tests__/testdata/hello-world.bpmn') + await cancelProcesses(test1.processes[0].bpmnProcessId) }) afterEach(async() => { if (wf && wf.processInstanceKey) { await zbc.cancelProcessInstance(wf.processInstanceKey).catch(e => e) // Cleanup any active processes } + await cancelProcesses(test1.processes[0].bpmnProcessId) +}) + +afterAll(async () => { await zbc.close() + await cancelProcesses(test1.processes[0].bpmnProcessId) }) test('Can get the broker topology', async () => { @@ -24,21 +31,6 @@ test('Can get the broker topology', async () => { expect(res?.brokers).toBeTruthy() }) -test('Deploys a single process', async () => { - const { bpmn, processId } = createUniqueTaskType({ - bpmnFilePath: './src/__tests__/testdata/hello-world.bpmn', - messages: [], - taskTypes: ['console-log-complete'], - }) - const res = await zbc.deployProcess({ - definition: bpmn, - name: `single-hello-world-${processId}.bpmn`, - }) - - expect(res.processes.length).toBe(1) - expect(res.processes[0].bpmnProcessId).toBe(processId) -}) - test('Can create a worker', async() => { const zb = new ZBClient() const worker = zb.createWorker({ @@ -51,21 +43,11 @@ test('Can create a worker', async() => { }) test('Can cancel a process', async () => { - const { bpmn, processId } = createUniqueTaskType({ - bpmnFilePath: './src/__tests__/testdata/hello-world.bpmn', - messages: [], - taskTypes: ['console-log'], - }) - const res = await zbc.deployProcess({ - definition: bpmn, - name: `cancel-hello-world-${processId}.bpmn`, - }) - wf = await zbc.createProcessInstance(processId, {}) + + const wf = await zbc.createProcessInstance(test1.processes[0].bpmnProcessId, {}) const wfi = wf.processInstanceKey expect(wfi).toBeTruthy() - expect(res.processes.length).toBe(1) - expect(res.processes[0].bpmnProcessId).toBe(processId) await zbc.cancelProcessInstance(wfi) try { diff --git a/src/__tests__/integration/Client-setVariables.spec.ts b/src/__tests__/integration/Client-setVariables.spec.ts index 1d03ea9b..f11a5986 100644 --- a/src/__tests__/integration/Client-setVariables.spec.ts +++ b/src/__tests__/integration/Client-setVariables.spec.ts @@ -1,6 +1,6 @@ +import { cancelProcesses } from '../ lib/cancelProcesses' import { ZBClient } from '../..' -import { createUniqueTaskType } from '../../lib/createUniqueTaskType' -import { CreateProcessInstanceResponse } from '../../lib/interfaces-grpc-1.0' +import { CreateProcessInstanceResponse, DeployProcessResponse } from '../../lib/interfaces-grpc-1.0' process.env.ZEEBE_NODE_LOG_LEVEL = process.env.ZEEBE_NODE_LOG_LEVEL || 'NONE' jest.setTimeout(30000) @@ -11,14 +11,18 @@ const trace = async (result: T) => { return result } -let zbc: ZBClient +const zbc = new ZBClient() let wf: CreateProcessInstanceResponse +let deploy: DeployProcessResponse +let processId: string -beforeEach(async () => { - zbc = new ZBClient() +beforeAll(async () => { + deploy = await zbc.deployProcess('./src/__tests__/testdata/conditional-pathway.bpmn') + processId = deploy.processes[0].bpmnProcessId + await cancelProcesses(processId) }) -afterEach( +afterAll( () => new Promise(async done => { try { @@ -29,6 +33,7 @@ afterEach( await zbc.close() // Makes sure we don't forget to close connection done(null) } + await cancelProcesses(processId) }) ) @@ -36,24 +41,6 @@ test('Can update process variables with setVariables', () => new Promise(async done => { jest.setTimeout(30000) - const { bpmn, taskTypes, processId } = createUniqueTaskType({ - bpmnFilePath: './src/__tests__/testdata/conditional-pathway.bpmn', - messages: [], - taskTypes: ['pathB', 'wait'], - }) - - // deepcode ignore PromiseNotCaughtNode: test - const res = await zbc - .deployProcess({ - definition: bpmn, - name: `conditional-pathway-${processId}.bpmn`, - }) - .then(trace) - - expect(res?.processes?.length).toBe(1) - expect(res?.processes?.[0]?.bpmnProcessId).toBe(processId) - - // deepcode ignore PromiseNotCaughtNode: test wf = await zbc .createProcessInstance(processId, { conditionVariable: true, @@ -63,7 +50,6 @@ test('Can update process variables with setVariables', () => const wfi = wf?.processInstanceKey expect(wfi).toBeTruthy() - // deepcode ignore PromiseNotCaughtNode: test zbc.setVariables({ elementInstanceKey: wfi, local: false, @@ -71,9 +57,9 @@ test('Can update process variables with setVariables', () => conditionVariable: false, }, }).then(trace) - trace('Creating wait worker') + zbc.createWorker({ - taskType: taskTypes.wait, + taskType: 'wait', taskHandler: async job => { expect(job?.processInstanceKey).toBe(wfi) trace(`Completing wait job for ${job.processInstanceKey}`) @@ -83,7 +69,7 @@ test('Can update process variables with setVariables', () => }) zbc.createWorker({ - taskType: taskTypes.pathB, + taskType: 'pathB', taskHandler: async job => { expect(job?.processInstanceKey).toBe(wfi) expect(job?.variables?.conditionVariable).toBe(false) diff --git a/src/__tests__/integration/Client-startProcess.spec.ts b/src/__tests__/integration/Client-startProcess.spec.ts index 7530acda..4764f4c5 100644 --- a/src/__tests__/integration/Client-startProcess.spec.ts +++ b/src/__tests__/integration/Client-startProcess.spec.ts @@ -1,38 +1,35 @@ +import { cancelProcesses } from '../ lib/cancelProcesses' import { ZBClient } from '../..' -import { createUniqueTaskType } from '../../lib/createUniqueTaskType' import { CreateProcessInstanceResponse } from '../../lib/interfaces-grpc-1.0' process.env.ZEEBE_NODE_LOG_LEVEL = process.env.ZEEBE_NODE_LOG_LEVEL || 'NONE' jest.setTimeout(30000) -let zbc: ZBClient +let zbc = new ZBClient() let wf: CreateProcessInstanceResponse let id: string +let processId: string +let processId2: string -beforeEach(async () => { - zbc = new ZBClient() +beforeAll(async () => { + const res = await zbc.deployProcess('./src/__tests__/testdata/hello-world.bpmn') + processId = res.processes[0].bpmnProcessId + processId2 = (await zbc.deployProcess('./src/__tests__/testdata/Client-SkipFirstTask.bpmn')).processes[0].bpmnProcessId + await cancelProcesses(processId) + await cancelProcesses(processId2) }) -afterEach(async () => { +afterAll(async () => { if (id) { // console.log(`Canceling process id ${id}`) zbc.cancelProcessInstance(id).catch(_ => _) } await zbc.close() // Makes sure we don't forget to close connection + await cancelProcesses(processId) + await cancelProcesses(processId) }) test('Can start a process', async () => { - const { bpmn, processId } = createUniqueTaskType({ - bpmnFilePath: './src/__tests__/testdata/hello-world.bpmn', - messages: [], - taskTypes: ['console-log'], - }) - const res = await zbc.deployProcess({ - definition: bpmn, - name: `start-hello-world-${processId}.bpmn`, - }) - expect(res.processes.length).toBe(1) - wf = await zbc.createProcessInstance(processId, {}) await zbc.cancelProcessInstance(wf.processInstanceKey) expect(wf.bpmnProcessId).toBe(processId) @@ -40,19 +37,17 @@ test('Can start a process', async () => { }) test('Can start a process at an arbitrary point', done => { - zbc.deployProcess('./src/__tests__/testdata/Client-SkipFirstTask.bpmn').then(_ => { - const random = Math.random() - zbc.createWorker({ - taskType: "second_service_task", - taskHandler: job => { - expect(job.variables.id).toBe(random) - return job.complete().then(() => done()) - } - }) - zbc.createProcessInstance({ - bpmnProcessId: 'SkipFirstTask', - variables: { id: random }, - startInstructions: [{elementId: 'second_service_task'}] - }).then(res => (id = res.processInstanceKey)) + const random = Math.random() + zbc.createWorker({ + taskType: "second_service_task", + taskHandler: job => { + expect(job.variables.id).toBe(random) + return job.complete().then(() => done()) + } }) + zbc.createProcessInstance({ + bpmnProcessId: 'SkipFirstTask', + variables: { id: random }, + startInstructions: [{elementId: 'second_service_task'}] + }).then(res => (id = res.processInstanceKey)) }) diff --git a/src/lib/MockWorker.ts b/src/lib/MockWorker.ts new file mode 100644 index 00000000..ac6ac122 --- /dev/null +++ b/src/lib/MockWorker.ts @@ -0,0 +1,44 @@ +import { ICustomHeaders, IInputVariables, IOutputVariables, MustReturnJobActionAcknowledgement, ZeebeJob } from "./interfaces-1.0"; + +export class ZeebeJobMock implements ZeebeJob { + key: string; + type: string; + processInstanceKey: string; + bpmnProcessId: string; + processDefinitionVersion: number; + processKey: string; + elementId: string; + elementInstanceKey: string; + customHeaders: Readonly; + worker: string; + retries: number; + deadline: string; + variables: Readonly; + cancelWorkflow: () => Promise<"JOB_ACTION_ACKNOWLEDGEMENT">; + complete: (updatedVariables?: IOutputVariables | undefined) => Promise<"JOB_ACTION_ACKNOWLEDGEMENT">; + fail: { (errorMessage: string, retries?: number | undefined): Promise<"JOB_ACTION_ACKNOWLEDGEMENT">; }; + forward: () => "JOB_ACTION_ACKNOWLEDGEMENT"; + error: (errorCode: string, errorMessage?: string | undefined) => Promise<"JOB_ACTION_ACKNOWLEDGEMENT">; + + completed?: IOutputVariables + failed?: {errorMessage: string, retries: number} + forwarded: boolean = false + errored?: {errorCode: string, errorMessage?: string} + + constructor(res: + {variables?: IInputVariables, customHeaders?: ICustomHeaders}) { + this.variables = res.variables || {} + this.customHeaders = res.customHeaders || {} + } +} + +export class ZeebeWorkerMock { + taskHandler: (job: ZeebeJob) => MustReturnJobActionAcknowledgement; + constructor(taskHandler: (job:ZeebeJob) => MustReturnJobActionAcknowledgement) { + this.taskHandler = taskHandler + } + + call(job: ZeebeJobMock) { + + } +}