Skip to content

Commit d324604

Browse files
authored
Add testWorkflow to WorkflowResourceService (#70)
* Added test workflow feature to JS SDK - https://orkes.io/content/developer-guides/unit-and-regression-tests * Added registerWorkflowDef to MetadataClient * CI: Fix tests + Publish Test reports
1 parent 0c07a54 commit d324604

File tree

9 files changed

+156
-9
lines changed

9 files changed

+156
-9
lines changed

.github/workflows/pull_request.yml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ jobs:
1616
run: yarn install
1717
- name: Run the linter
1818
run: yarn lint
19+
1920
unit-tests:
2021
runs-on: ubuntu-latest
2122
steps:
@@ -27,9 +28,16 @@ jobs:
2728
node-version: "18"
2829
- name: Install package
2930
run: yarn install
30-
- name: Run Unit test
31-
run: yarn test
31+
- name: Run Tests
32+
run: yarn test --ci --reporters=default --reporters=jest-junit
3233
env:
3334
KEY_ID: ${{ secrets.KEY_ID }}
3435
KEY_SECRET: ${{ secrets.KEY_SECRET }}
3536
SERVER_URL: ${{ secrets.SERVER_URL }}
37+
- name: Publish Test Results
38+
if: always()
39+
uses: dorny/test-reporter@v1
40+
with:
41+
name: Test report
42+
path: reports/jest-*.xml
43+
reporter: jest-junit

package.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
"dotenv": "^16.0.1",
6262
"eslint": "^6.1.0",
6363
"jest": "^29.4.3",
64+
"jest-junit": "^16.0.0",
6465
"ts-jest": "^29.0.5",
6566
"ts-node": "^10.7.0",
6667
"tsup": "^7.1.0",
@@ -83,6 +84,14 @@
8384
"engines": {
8485
"node": ">=18"
8586
},
86-
"dependencies": {
87+
"dependencies": {},
88+
"jest-junit": {
89+
"outputDirectory": "reports",
90+
"outputName": "jest-junit.xml",
91+
"ancestorSeparator": "",
92+
"uniqueOutputName": "false",
93+
"suiteNameTemplate": "{filepath}",
94+
"classNameTemplate": "{classname}",
95+
"titleTemplate": "{title}"
8796
}
8897
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { expect, describe, test, jest } from "@jest/globals";
2+
import { MetadataClient } from "../../../core";
3+
import { simpleTask, workflow } from "../../../core/sdk";
4+
import { orkesConductorClient } from "../../../orkes";
5+
import { TaskDefTypes } from "../../types";
6+
7+
const config = {
8+
keyId: `${process.env.KEY_ID}`,
9+
keySecret: `${process.env.KEY_SECRET}`,
10+
serverUrl: `${process.env.SERVER_URL}`,
11+
};
12+
13+
describe("WorkflowResourceService", () => {
14+
jest.setTimeout(120000);
15+
16+
test("Should test a workflow", async () => {
17+
const client = await orkesConductorClient(config);
18+
const metadataClient = new MetadataClient(client);
19+
const tasks: TaskDefTypes[] = [
20+
simpleTask("simple_ref", "le_simple_task", {}),
21+
];
22+
23+
const wfDef = workflow("unit_test_wf", tasks);
24+
wfDef.outputParameters = { message: "${simple_ref.output.message}" };
25+
metadataClient.registerWorkflowDef(wfDef, true);
26+
27+
const status = "COMPLETED";
28+
const output = { message: "Mocked message" };
29+
30+
const wf = await client.workflowResource.testWorkflow({
31+
name: wfDef.name,
32+
taskRefToMockOutput: {
33+
"simple_ref": [{ status, output }],
34+
},
35+
});
36+
37+
expect(wf.status).toEqual(status);
38+
expect(wf.output).toEqual(output);
39+
});
40+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/* istanbul ignore file */
2+
/* tslint:disable */
3+
/* eslint-disable */
4+
export type TaskMock = {
5+
executionTime?: number;
6+
output: Record<string, any>;
7+
queueWaitTime?: number;
8+
status:
9+
| "IN_PROGRESS"
10+
| "FAILED"
11+
| "FAILED_WITH_TERMINAL_ERROR"
12+
| "COMPLETED";
13+
};
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/* istanbul ignore file */
2+
/* tslint:disable */
3+
/* eslint-disable */
4+
import type { TaskMock } from "./TaskMock";
5+
import type { WorkflowDef } from "./WorkflowDef";
6+
export type WorkflowTestRequest = {
7+
correlationId?: string;
8+
createdBy?: string;
9+
externalInputPayloadStoragePath?: string;
10+
idempotencyKey?: string;
11+
idempotencyStrategy?: "FAIL" | "RETURN_EXISTING";
12+
input?: Record<string, Record<string, any>>;
13+
name: string;
14+
priority?: number;
15+
subWorkflowTestRequest?: Record<string, WorkflowTestRequest>;
16+
taskRefToMockOutput?: Record<string, Array<TaskMock>>;
17+
taskToDomain?: Record<string, string>;
18+
version?: number;
19+
workflowDef?: WorkflowDef;
20+
};

src/common/open-api/services/WorkflowResourceService.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import type { StartWorkflowRequest } from '../models/StartWorkflowRequest';
1111
import type { Workflow } from '../models/Workflow';
1212
import type { WorkflowRun } from '../models/WorkflowRun';
1313
import type { WorkflowStatus } from '../models/WorkflowStatus';
14+
import type { WorkflowTestRequest } from '../models/WorkflowTestRequest';
15+
1416

1517
import type { CancelablePromise } from '../core/CancelablePromise';
1618
import type { BaseHttpRequest } from '../core/BaseHttpRequest';
@@ -605,4 +607,20 @@ export class WorkflowResourceService {
605607
});
606608
}
607609

610+
/**
611+
* Test workflow execution using mock data
612+
* @param requestBody
613+
* @returns Workflow OK
614+
* @throws ApiError
615+
*/
616+
public testWorkflow(
617+
requestBody: WorkflowTestRequest
618+
): CancelablePromise<Workflow> {
619+
return this.httpRequest.request({
620+
method: 'POST',
621+
url: '/workflow/test',
622+
body: requestBody,
623+
mediaType: 'application/json',
624+
});
625+
}
608626
}

src/core/metadataClient.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
import {
2-
ConductorClient,
3-
TaskDef,
4-
} from "../common";
1+
import { ConductorClient, TaskDef } from "../common";
2+
import { WorkflowDef } from "../common/open-api";
53
import { tryCatchReThrow } from "./helpers";
64

75
export class MetadataClient {
@@ -46,4 +44,20 @@ export class MetadataClient {
4644
this._client.metadataResource.updateTaskDef(taskDef)
4745
);
4846
}
47+
48+
/**
49+
* Creates or updates (overwrite: true) a workflow definition
50+
*
51+
* @param workflowDef
52+
* @param overwrite
53+
* @returns
54+
*/
55+
public registerWorkflowDef(
56+
workflowDef: WorkflowDef,
57+
overwrite: boolean = false
58+
) {
59+
return tryCatchReThrow(() =>
60+
this._client.metadataResource.create(workflowDef, overwrite)
61+
);
62+
}
4963
}

src/task/__tests__/TaskManager.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ describe("TaskManager", () => {
5555
const executor = new WorkflowExecutor(client);
5656

5757
const worker: ConductorWorker = {
58-
taskDefName: "taskmanager-error-test",
58+
taskDefName: "taskmanager-error-test2",
5959
execute: async () => {
6060
throw Error("This is a forced error");
6161
},
@@ -71,7 +71,7 @@ describe("TaskManager", () => {
7171
manager.startPolling();
7272

7373
await executor.startWorkflow({
74-
name: "TaskManagerTestE",
74+
name: "TaskManagerTestE2",
7575
input: {},
7676
version: 1,
7777
});

yarn.lock

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2413,6 +2413,16 @@ jest-haste-map@^29.5.0:
24132413
optionalDependencies:
24142414
fsevents "^2.3.2"
24152415

2416+
jest-junit@^16.0.0:
2417+
version "16.0.0"
2418+
resolved "https://registry.yarnpkg.com/jest-junit/-/jest-junit-16.0.0.tgz#d838e8c561cf9fdd7eb54f63020777eee4136785"
2419+
integrity sha512-A94mmw6NfJab4Fg/BlvVOUXzXgF0XIH6EmTgJ5NDPp4xoKq0Kr7sErb+4Xs9nZvu58pJojz5RFGpqnZYJTrRfQ==
2420+
dependencies:
2421+
mkdirp "^1.0.4"
2422+
strip-ansi "^6.0.1"
2423+
uuid "^8.3.2"
2424+
xml "^1.0.1"
2425+
24162426
jest-leak-detector@^29.5.0:
24172427
version "29.5.0"
24182428
resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.5.0.tgz#cf4bdea9615c72bac4a3a7ba7e7930f9c0610c8c"
@@ -2823,6 +2833,11 @@ mkdirp@^0.5.1:
28232833
dependencies:
28242834
minimist "^1.2.6"
28252835

2836+
mkdirp@^1.0.4:
2837+
version "1.0.4"
2838+
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
2839+
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
2840+
28262841
28272842
version "2.1.2"
28282843
resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
@@ -3578,6 +3593,11 @@ uri-js@^4.2.2:
35783593
dependencies:
35793594
punycode "^2.1.0"
35803595

3596+
uuid@^8.3.2:
3597+
version "8.3.2"
3598+
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
3599+
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
3600+
35813601
uuid@^9.0.0:
35823602
version "9.0.0"
35833603
resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz"
@@ -3686,6 +3706,11 @@ [email protected]:
36863706
dependencies:
36873707
mkdirp "^0.5.1"
36883708

3709+
xml@^1.0.1:
3710+
version "1.0.1"
3711+
resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5"
3712+
integrity sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==
3713+
36893714
y18n@^5.0.5:
36903715
version "5.0.8"
36913716
resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz"

0 commit comments

Comments
 (0)