Skip to content

Commit 5d6e06d

Browse files
committed
process historyTimeToLive negative and zero return P0D duration
1 parent 54ada99 commit 5d6e06d

File tree

6 files changed

+187
-83
lines changed

6 files changed

+187
-83
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
# unreleased
44

5+
# 8.1.0
6+
7+
- process history time to live negative and zero days both result in time duration `P0D`
8+
59
# 8.0.3
610

711
- add iso8601 to OnifyTimerEventDefinition supports list to avoid confusion

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@onify/flow-extensions",
3-
"version": "8.0.3",
3+
"version": "8.1.0",
44
"description": "Onify Flow extensions",
55
"type": "module",
66
"module": "src/index.js",
@@ -20,13 +20,13 @@
2020
}
2121
},
2222
"scripts": {
23-
"test": "mocha -R dot",
23+
"test": "mocha",
2424
"posttest": "npm run lint && npm run dist && texample",
2525
"lint": "eslint . --cache && prettier . --check --cache",
2626
"prepare": "npm run dist",
2727
"dist": "babel src -d dist && babel test/helpers/FlowScripts.js -d dist",
2828
"test:lcov": "c8 -r lcov mocha && npm run lint",
29-
"cov:html": "c8 mocha -R dot && c8 report --reporter html"
29+
"cov:html": "c8 mocha && c8 report --reporter html"
3030
},
3131
"keywords": [
3232
"onify",

src/index.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,9 @@ function getHistoryTimeToLiveTimer(behaviour) {
102102
const { id, $type: type, historyTimeToLive } = behaviour;
103103

104104
let value = historyTimeToLive;
105-
if (/^\d+$/.test(historyTimeToLive)) {
106-
value = `P${historyTimeToLive}D`;
105+
let days;
106+
if (!isNaN((days = Number(value)))) {
107+
value = `P${days > 0 ? days : 0}D`;
107108
}
108109
return {
109110
id: `${type}/${id}:historyTimeToLive`,
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
import { parseInterval } from '@0dep/piso';
2+
import testHelpers from '../helpers/testHelpers.js';
3+
4+
Feature('Process history ttl', () => {
5+
Scenario('Flow with process history time to live as number of days', () => {
6+
let source, flow;
7+
Given('a source matching scenario', () => {
8+
source = `<?xml version="1.0" encoding="UTF-8"?>
9+
<definitions id="def_0" xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
10+
xmlns:camunda="http://camunda.org/schema/1.0/bpmn"
11+
targetNamespace="http://bpmn.io/schema/bpmn">
12+
<process id="my-process" isExecutable="true" camunda:historyTimeToLive="180">
13+
<userTask id="task" />
14+
</process>
15+
</definitions>`;
16+
});
17+
18+
let serializable;
19+
When('parsed with extend function', async () => {
20+
serializable = await testHelpers.parseOnifyFlow(source);
21+
});
22+
23+
Then('history ttl timer is registered as duration', () => {
24+
expect(serializable.elements.timers[0]).to.deep.equal({
25+
name: 'my-process:historyTimeToLive',
26+
parent: {
27+
id: 'my-process',
28+
type: 'bpmn:Process',
29+
},
30+
timer: {
31+
id: 'bpmn:Process/my-process:historyTimeToLive',
32+
timerType: 'timeDuration',
33+
type: 'historyTimeToLive',
34+
value: 'P180D',
35+
},
36+
});
37+
});
38+
39+
let started, wait;
40+
When('started', async () => {
41+
flow = await testHelpers.getOnifyFlow(source);
42+
started = flow.waitFor('process.start');
43+
wait = flow.waitFor('wait');
44+
flow.run();
45+
});
46+
47+
let historyTtl;
48+
Then('process environment has historyTimeToLive', async () => {
49+
const bp = await started;
50+
expect(bp.environment.variables).to.have.property('historyTimeToLive', 'P180D');
51+
historyTtl = bp.environment.variables.historyTimeToLive;
52+
});
53+
54+
And('it is parsable as ISO8601 duration', () => {
55+
expect(parseInterval(historyTtl).duration.result.D).to.equal(180);
56+
});
57+
58+
let processEnd, state;
59+
When('flow is stopped and resumed', async () => {
60+
await flow.stop();
61+
62+
state = await flow.getState();
63+
64+
processEnd = flow.waitFor('process.end');
65+
return flow.resume();
66+
});
67+
68+
And('task is signaled', async () => {
69+
await wait;
70+
flow.signal({ id: 'task' });
71+
});
72+
73+
Then('process run completes', async () => {
74+
const ended = await processEnd;
75+
expect(ended.environment.variables).to.have.property('historyTimeToLive', historyTtl);
76+
});
77+
78+
When('flow is recovered and resumed from stopped state', async () => {
79+
flow = await testHelpers.recoverOnifyFlow(source, state);
80+
processEnd = flow.waitFor('process.end');
81+
return flow.resume();
82+
});
83+
84+
And('task is signaled', () => {
85+
flow.signal({ id: 'task' });
86+
});
87+
88+
Then('process run completes', async () => {
89+
const ended = await processEnd;
90+
expect(ended.environment.variables).to.have.property('historyTimeToLive', historyTtl);
91+
});
92+
});
93+
94+
Scenario('Flow with process history time to live as negative number of days', () => {
95+
let source;
96+
Given('a source matching scenario', () => {
97+
source = `<?xml version="1.0" encoding="UTF-8"?>
98+
<definitions id="def_0" xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
99+
xmlns:camunda="http://camunda.org/schema/1.0/bpmn"
100+
targetNamespace="http://bpmn.io/schema/bpmn">
101+
<process id="my-process" isExecutable="true" camunda:historyTimeToLive="-1">
102+
<userTask id="task" />
103+
</process>
104+
</definitions>`;
105+
});
106+
107+
let serializable;
108+
When('parsed with extend function', async () => {
109+
serializable = await testHelpers.parseOnifyFlow(source);
110+
});
111+
112+
Then('history ttl timer is registered as 0 days', () => {
113+
expect(serializable.elements.timers[0]).to.deep.equal({
114+
name: 'my-process:historyTimeToLive',
115+
parent: {
116+
id: 'my-process',
117+
type: 'bpmn:Process',
118+
},
119+
timer: {
120+
id: 'bpmn:Process/my-process:historyTimeToLive',
121+
timerType: 'timeDuration',
122+
type: 'historyTimeToLive',
123+
value: 'P0D',
124+
},
125+
});
126+
});
127+
});
128+
129+
Scenario('Flow with process history time to live as 0', () => {
130+
let source;
131+
Given('a source matching scenario', () => {
132+
source = `<?xml version="1.0" encoding="UTF-8"?>
133+
<definitions id="def_0" xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
134+
xmlns:camunda="http://camunda.org/schema/1.0/bpmn"
135+
targetNamespace="http://bpmn.io/schema/bpmn">
136+
<process id="my-process" isExecutable="true" camunda:historyTimeToLive="0">
137+
<userTask id="task" />
138+
</process>
139+
</definitions>`;
140+
});
141+
142+
let serializable;
143+
When('parsed with extend function', async () => {
144+
serializable = await testHelpers.parseOnifyFlow(source);
145+
});
146+
147+
Then('history ttl timer is registered as 0 days', () => {
148+
expect(serializable.elements.timers[0]).to.deep.equal({
149+
name: 'my-process:historyTimeToLive',
150+
parent: {
151+
id: 'my-process',
152+
type: 'bpmn:Process',
153+
},
154+
timer: {
155+
id: 'bpmn:Process/my-process:historyTimeToLive',
156+
timerType: 'timeDuration',
157+
type: 'historyTimeToLive',
158+
value: 'P0D',
159+
},
160+
});
161+
});
162+
});
163+
});

test/features/process-history-ttl-feaure.js

Lines changed: 0 additions & 73 deletions
This file was deleted.

test/helpers/testHelpers.js

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export default {
1919
Logger,
2020
recoverOnifyFlow,
2121
getEngine,
22+
parseOnifyFlow,
2223
};
2324

2425
function moddleContext(source, options) {
@@ -30,19 +31,27 @@ function moddleContext(source, options) {
3031
* Get Definition as Onify flow with extensions
3132
* @param {string | Buffer} source BPMN source
3233
* @param {import('bpmn-elements').EnvironmentOptions} options Definition options
33-
* @returns {Promise<import('bpmn-elements').Definition>}
3434
*/
3535
async function getOnifyFlow(source, options = {}) {
36+
const { types, ...environmentOptions } = options;
37+
const serialized = await parseOnifyFlow(source, { types });
38+
39+
return new Elements.Definition(new Elements.Context(serialized), getFlowOptions(serialized.name || serialized.id, environmentOptions));
40+
}
41+
42+
/**
43+
* Parse source Onify flow with extensions
44+
* @param {string | Buffer} source BPMN source
45+
* @param {import('bpmn-elements').EnvironmentOptions} options Definition options
46+
*/
47+
async function parseOnifyFlow(source, options = {}) {
3648
const moddle = await moddleContext(source, await getModdleExtensions());
3749
if (moddle.warnings?.length) {
3850
const logger = Logger('bpmn-moddle');
3951
for (const w of moddle.warnings) logger.warn(w);
4052
}
4153

42-
const { types, ...environmentOptions } = options || {};
43-
44-
const serialized = Serializer(moddle, TypeResolver({ ...Elements, TimerEventDefinition, ...types }), extendFn);
45-
return new Elements.Definition(new Elements.Context(serialized), getFlowOptions(serialized.name || serialized.id, environmentOptions));
54+
return Serializer(moddle, TypeResolver({ ...Elements, TimerEventDefinition, ...options.types }), extendFn);
4655
}
4756

4857
/**

0 commit comments

Comments
 (0)