botium-core 1.13.18 → 1.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/botium-cjs.js +326 -387
- package/dist/botium-cjs.js.map +1 -1
- package/dist/botium-es.js +326 -385
- package/dist/botium-es.js.map +1 -1
- package/package.json +21 -25
- package/samples/extensions/asserterHooks/botium.json +1 -0
- package/samples/extensions/logichooks/botium.json +1 -0
- package/samples/extensions/logichooks/custom/MyAsserter.js +3 -3
- package/src/Capabilities.js +2 -1
- package/src/containers/PluginConnectorContainer.js +8 -0
- package/src/containers/plugins/SimpleRestContainer.js +17 -9
- package/src/containers/plugins/index.js +29 -41
- package/src/helpers/HookUtils.js +32 -68
- package/src/scripting/Convo.js +17 -5
- package/src/scripting/ScriptingMemory.js +0 -24
- package/src/scripting/logichook/LogicHookConsts.js +5 -1
- package/src/scripting/logichook/LogicHookUtils.js +27 -47
- package/src/scripting/logichook/asserter/ButtonsAsserter.js +5 -5
- package/src/scripting/logichook/logichooks/ConditionalBusinessHoursLogicHook.js +56 -0
- package/src/scripting/logichook/logichooks/ConditionalCapabilityValueBasedLogicHook.js +37 -0
- package/src/scripting/logichook/logichooks/ConditionalJsonPathBasedLogicHook.js +31 -0
- package/src/scripting/logichook/logichooks/ConditionalTimeBasedLogicHook.js +46 -0
- package/test/compiler/precompilerscript.spec.js +24 -26
- package/test/connectors/pluginconnectorcontainer.spec.js +60 -0
- package/test/connectors/simplerest.spec.js +24 -27
- package/test/convo/fillAndApplyScriptingMemory.spec.js +1 -47
- package/test/hooks/customhooks.spec.js +3 -25
- package/test/logichooks/hookfromsrc.spec.js +13 -3
- package/test/plugins/plugins.spec.js +29 -2
- package/test/scripting/logichooks/CustomConditionalLogicHook.js +21 -0
- package/test/scripting/logichooks/conditionalStepBusinessHoursLogicHook.spec.js +130 -0
- package/test/scripting/logichooks/conditionalStepCapabilityValueBasedLogicHook.spec.js +35 -0
- package/test/scripting/logichooks/conditionalStepJsonPathBasedLogicHook.spec.js +35 -0
- package/test/scripting/logichooks/conditionalStepTimeBasedLogicHook.spec.js +91 -0
- package/test/scripting/logichooks/convos/conditional_steps.convo.txt +12 -0
- package/test/scripting/logichooks/convos/conditional_steps_business_hours.convo.txt +16 -0
- package/test/scripting/logichooks/convos/conditional_steps_cap_value_based.convo.txt +12 -0
- package/test/scripting/logichooks/convos/conditional_steps_followed_by_bot_msg.convo.txt +15 -0
- package/test/scripting/logichooks/convos/conditional_steps_followed_by_me.convo.txt +18 -0
- package/test/scripting/logichooks/convos/conditional_steps_json_path_based.convo.txt.convo.txt +12 -0
- package/test/scripting/logichooks/convos/conditional_steps_multiple_condition_groups.convo.txt +20 -0
- package/test/scripting/logichooks/convos/conditional_steps_multiple_condition_groups_no_assertion.convo.txt +20 -0
- package/test/scripting/logichooks/convos/conditional_steps_time_based.convo.txt +12 -0
- package/test/scripting/logichooks/customConditionalStepLogicHook.spec.js +105 -0
- package/test/scripting/scriptingProvider.spec.js +1 -1
- package/test/security/allowUnsafe.spec.js +20 -129
- package/LICENSES-3RDPARTY.txt +0 -6450
- package/test/scripting/asserters/convos/customembeddedasserterwithhugo.convo.txt +0 -7
- package/test/scripting/asserters/convos/customembeddedasserterwithouthugo.convo.txt +0 -7
- package/test/scripting/asserters/customEmbeddedAsserter.json +0 -14
- package/test/scripting/asserters/customEmbeddedAsserter.spec.js +0 -55
- package/test/scripting/logichooks/convos/custom_embedded.convo.txt +0 -8
- package/test/scripting/logichooks/convos/custom_embedded_skip.convo.txt +0 -11
- package/test/scripting/logichooks/convos/custom_embedded_skip_followed_by_me.convo.txt +0 -11
- package/test/scripting/logichooks/convos/custom_embedded_skip_followed_by_nothing.convo.txt +0 -8
- package/test/scripting/logichooks/customEmbedded.json +0 -14
- package/test/scripting/logichooks/customEmbedded.spec.js +0 -44
- package/test/scripting/logichooks/customEmbeddedSkip.json +0 -14
- package/test/scripting/logichooks/customEmbeddedSkip.spec.js +0 -58
- package/test/security/convos/withscriptingmemoryfunction.convo.txt +0 -5
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
const
|
|
1
|
+
const util = require('util')
|
|
2
2
|
const path = require('path')
|
|
3
3
|
const fs = require('fs')
|
|
4
4
|
const isClass = require('is-class')
|
|
5
5
|
const debug = require('debug')('botium-core-asserterUtils')
|
|
6
6
|
|
|
7
|
-
const { BotiumError } = require('../BotiumError')
|
|
8
|
-
|
|
9
7
|
const { DEFAULT_ASSERTERS, DEFAULT_LOGIC_HOOKS, DEFAULT_USER_INPUTS } = require('./LogicHookConsts')
|
|
10
8
|
|
|
11
9
|
DEFAULT_ASSERTERS.forEach((asserter) => {
|
|
@@ -129,19 +127,7 @@ module.exports = class LogicHookUtils {
|
|
|
129
127
|
}
|
|
130
128
|
}
|
|
131
129
|
|
|
132
|
-
const
|
|
133
|
-
if (!this.caps[Capabilities.SECURITY_ALLOW_UNSAFE]) {
|
|
134
|
-
throw new BotiumError(
|
|
135
|
-
'Security Error. Using unsafe component is not allowed',
|
|
136
|
-
{
|
|
137
|
-
type: 'security',
|
|
138
|
-
subtype: 'allow unsafe',
|
|
139
|
-
source: path.basename(__filename),
|
|
140
|
-
cause: { src: !!src, ref, args, hookType }
|
|
141
|
-
}
|
|
142
|
-
)
|
|
143
|
-
}
|
|
144
|
-
}
|
|
130
|
+
const allowUnsafe = !!this.caps[Capabilities.SECURITY_ALLOW_UNSAFE]
|
|
145
131
|
|
|
146
132
|
if (!src) {
|
|
147
133
|
const packageName = `botium-${hookType}-${ref}`
|
|
@@ -154,10 +140,10 @@ module.exports = class LogicHookUtils {
|
|
|
154
140
|
} else if (isClass(CheckClass.PluginClass)) {
|
|
155
141
|
return new CheckClass.PluginClass({ ref, ...this.buildScriptContext }, this.caps, args)
|
|
156
142
|
} else {
|
|
157
|
-
throw new Error(
|
|
143
|
+
throw new Error('Either class or function or PluginClass field expected')
|
|
158
144
|
}
|
|
159
145
|
} catch (err) {
|
|
160
|
-
throw new Error(`
|
|
146
|
+
throw new Error(`Logic Hook specification ${ref} ${hookType} (${packageName}) invalid: ${err.message}`)
|
|
161
147
|
}
|
|
162
148
|
}
|
|
163
149
|
|
|
@@ -166,14 +152,14 @@ module.exports = class LogicHookUtils {
|
|
|
166
152
|
const CheckClass = src
|
|
167
153
|
return new CheckClass({ ref, ...this.buildScriptContext }, this.caps, args)
|
|
168
154
|
} catch (err) {
|
|
169
|
-
throw new Error(`
|
|
155
|
+
throw new Error(`Logic Hook specification ${ref} from class invalid: ${err.message}`)
|
|
170
156
|
}
|
|
171
157
|
}
|
|
172
158
|
if (_.isFunction(src)) {
|
|
173
159
|
try {
|
|
174
160
|
return src({ ref, ...this.buildScriptContext }, this.caps, args)
|
|
175
161
|
} catch (err) {
|
|
176
|
-
throw new Error(`
|
|
162
|
+
throw new Error(`Logic Hook specification ${ref} from function invalid: ${err.message}`)
|
|
177
163
|
}
|
|
178
164
|
}
|
|
179
165
|
if (_.isObject(src) && !_.isString(src)) {
|
|
@@ -183,26 +169,15 @@ module.exports = class LogicHookUtils {
|
|
|
183
169
|
const script = src[key]
|
|
184
170
|
if (_.isFunction(script)) {
|
|
185
171
|
return script(args)
|
|
186
|
-
} else if (_.isString(script)) {
|
|
187
|
-
try {
|
|
188
|
-
const vm = new NodeVM({
|
|
189
|
-
eval: false,
|
|
190
|
-
require: false,
|
|
191
|
-
sandbox: args
|
|
192
|
-
})
|
|
193
|
-
return vm.run(script)
|
|
194
|
-
} catch (err) {
|
|
195
|
-
throw new Error(`Script ${key} is not valid - ${err.message || err}`)
|
|
196
|
-
}
|
|
197
172
|
} else {
|
|
198
|
-
throw new Error(`Script
|
|
173
|
+
throw new Error(`Script ${key} is not valid - only functions accepted`)
|
|
199
174
|
}
|
|
200
175
|
}
|
|
201
176
|
return result
|
|
202
177
|
}, {})
|
|
203
178
|
return hookObject
|
|
204
179
|
} catch (err) {
|
|
205
|
-
throw new Error(`
|
|
180
|
+
throw new Error(`Logic Hook specification ${ref} ${hookType} from provided src (${util.inspect(src)}) invalid: ${err.message}`)
|
|
206
181
|
}
|
|
207
182
|
}
|
|
208
183
|
|
|
@@ -215,8 +190,8 @@ module.exports = class LogicHookUtils {
|
|
|
215
190
|
}]
|
|
216
191
|
if (src.indexOf('/') >= 0) {
|
|
217
192
|
tryLoads.push({
|
|
218
|
-
tryLoadPackageName: src.
|
|
219
|
-
tryLoadAsserterByName: src.
|
|
193
|
+
tryLoadPackageName: src.substring(0, src.lastIndexOf('/')),
|
|
194
|
+
tryLoadAsserterByName: src.substring(src.lastIndexOf('/') + 1)
|
|
220
195
|
})
|
|
221
196
|
}
|
|
222
197
|
|
|
@@ -243,29 +218,34 @@ module.exports = class LogicHookUtils {
|
|
|
243
218
|
} else if (_.isFunction(CheckClass.PluginClass)) {
|
|
244
219
|
return CheckClass.PluginClass({ ref, ...this.buildScriptContext }, this.caps, args)
|
|
245
220
|
} else {
|
|
246
|
-
throw new Error(
|
|
221
|
+
throw new Error('Expected class or function')
|
|
247
222
|
}
|
|
248
223
|
}
|
|
249
224
|
|
|
250
225
|
for (const tryLoad of tryLoads) {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
226
|
+
if (this.caps.SAFEDIR) {
|
|
227
|
+
const tryLoadFile = path.resolve(this.caps.SAFEDIR, tryLoad.tryLoadPackageName)
|
|
228
|
+
if (tryLoadFile.startsWith(path.resolve(this.caps.SAFEDIR))) {
|
|
229
|
+
if (fs.existsSync(tryLoadFile)) {
|
|
230
|
+
try {
|
|
231
|
+
return tryLoadFromSource(tryLoadFile, tryLoad.tryLoadAsserterByName)
|
|
232
|
+
} catch (err) {
|
|
233
|
+
loadErr.push(`Logic Hook specification ${ref} ${hookType} from "${src}" invalid: ${err.message} `)
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
if (allowUnsafe || tryLoad.tryLoadPackageName.startsWith('botium-')) {
|
|
254
239
|
try {
|
|
255
|
-
return tryLoadFromSource(
|
|
240
|
+
return tryLoadFromSource(tryLoad.tryLoadPackageName, tryLoad.tryLoadAsserterByName)
|
|
256
241
|
} catch (err) {
|
|
257
|
-
loadErr.push(`
|
|
242
|
+
loadErr.push(`Logic Hook specification ${ref} ${hookType} from "${src}" invalid: ${err.message} `)
|
|
258
243
|
}
|
|
259
244
|
}
|
|
260
|
-
try {
|
|
261
|
-
return tryLoadFromSource(tryLoad.tryLoadPackageName, tryLoad.tryLoadAsserterByName)
|
|
262
|
-
} catch (err) {
|
|
263
|
-
loadErr.push(`Failed to fetch ${ref} ${hookType} from ${src} - ${err.message} `)
|
|
264
|
-
}
|
|
265
245
|
}
|
|
266
246
|
|
|
267
247
|
loadErr.forEach(debug)
|
|
268
248
|
}
|
|
269
|
-
throw new Error(`
|
|
249
|
+
throw new Error(`Logic Hook specification ${ref} ${hookType} from "${util.inspect(src)}" invalid : no loader available`)
|
|
270
250
|
}
|
|
271
251
|
}
|
|
@@ -18,19 +18,19 @@ module.exports = class ButtonsAsserter {
|
|
|
18
18
|
}
|
|
19
19
|
const buttonsNotFound = []
|
|
20
20
|
const buttonsFound = []
|
|
21
|
-
const
|
|
21
|
+
const stringifyPayload = (payload) => {
|
|
22
22
|
if (_.isNil(payload)) {
|
|
23
|
-
return
|
|
23
|
+
return ''
|
|
24
24
|
}
|
|
25
25
|
try {
|
|
26
|
-
return JSON.parse(payload)
|
|
26
|
+
return JSON.stringify(JSON.parse(payload))
|
|
27
27
|
} catch (e) {
|
|
28
|
-
return payload
|
|
28
|
+
return JSON.stringify(payload)
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
for (let i = 0; i < (args || []).length; i++) {
|
|
32
32
|
const matchByText = allButtons.some(b => this.context.Match(b.text, normalizeText(args[i], !!this.caps[SCRIPTING_NORMALIZE_TEXT])))
|
|
33
|
-
const matchByPayload = allButtons.some(b =>
|
|
33
|
+
const matchByPayload = allButtons.some(b => this.context.Match(stringifyPayload(b.payload), normalizeText(args[i], !!this.caps[SCRIPTING_NORMALIZE_TEXT])))
|
|
34
34
|
if (matchByText || matchByPayload) {
|
|
35
35
|
buttonsFound.push(args[i])
|
|
36
36
|
} else {
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
const util = require('util')
|
|
2
|
+
const moment = require('moment-timezone')
|
|
3
|
+
const debug = require('debug')('botium-core-ConditionalTimeBasedLogicHook')
|
|
4
|
+
|
|
5
|
+
module.exports = class ConditionalBusinessHoursLogicHook {
|
|
6
|
+
constructor (context, caps, globalArgs) {
|
|
7
|
+
this.context = context
|
|
8
|
+
this.caps = caps
|
|
9
|
+
this.globalArgs = globalArgs
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
_isBetween ({ now, start, end, days, timeZone }) {
|
|
13
|
+
if ((!start || !end) && (!days || days.length === 0)) {
|
|
14
|
+
throw new Error('ConditionalBusinessHoursLogicHook: Either start and end time or days array needs to be specified in params')
|
|
15
|
+
}
|
|
16
|
+
now.tz(timeZone)
|
|
17
|
+
if (days && days.length > 0 && !days.includes(now.format('dddd'))) {
|
|
18
|
+
return false
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (!start && !end && days && days.length > 0 && days.includes(now.format('dddd'))) {
|
|
22
|
+
return true
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const momentStartTime = moment(start, 'HH:mm')
|
|
26
|
+
const startTime = now.clone().set({ hour: momentStartTime.hour(), minute: momentStartTime.minute() })
|
|
27
|
+
startTime.tz(timeZone)
|
|
28
|
+
const momentEndTime = moment(end, 'HH:mm')
|
|
29
|
+
const endTime = now.clone().set({ hour: momentEndTime.hour(), minute: momentEndTime.minute() })
|
|
30
|
+
endTime.tz(timeZone)
|
|
31
|
+
if (startTime.isSameOrAfter(endTime)) {
|
|
32
|
+
if (now.isSameOrAfter(startTime)) {
|
|
33
|
+
endTime.add(1, 'days')
|
|
34
|
+
} else {
|
|
35
|
+
startTime.add(-1, 'days')
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return now.isBetween(startTime, endTime, 'minutes', '[]')
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
onBotPrepare ({ convo, convoStep, args }) {
|
|
42
|
+
const conditionGroupId = args[1]
|
|
43
|
+
let params
|
|
44
|
+
try {
|
|
45
|
+
params = JSON.parse(args[0])
|
|
46
|
+
} catch (e) {
|
|
47
|
+
throw new Error(`ConditionalBusinessHoursLogicHook: No parsable JSON object found in params: ${e}`)
|
|
48
|
+
}
|
|
49
|
+
convoStep.conditional = {
|
|
50
|
+
conditionGroupId
|
|
51
|
+
}
|
|
52
|
+
params.now = moment()
|
|
53
|
+
convoStep.conditional.skip = !this._isBetween(params)
|
|
54
|
+
debug(`ConditionalBusinessHoursLogicHook onBotPrepare ${convo.header.name}/${convoStep.stepTag}, args: ${util.inspect(args)}, convoStep.conditional: ${convoStep.conditional}`)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const util = require('util')
|
|
2
|
+
const jp = require('jsonpath')
|
|
3
|
+
const _ = require('lodash')
|
|
4
|
+
const debug = require('debug')('botium-core-ConditionalCapabilityValueBasedLogicHook')
|
|
5
|
+
|
|
6
|
+
module.exports = class ConditionalCapabilityValueBasedLogicHook {
|
|
7
|
+
constructor (context, caps, globalArgs) {
|
|
8
|
+
this.context = context
|
|
9
|
+
this.caps = caps
|
|
10
|
+
this.globalArgs = globalArgs
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
_isCapabilityValueEqual ({ capabilityName, jsonPath, value }) {
|
|
14
|
+
if (jsonPath) {
|
|
15
|
+
const capabilityObject = _.isObject(this.caps[capabilityName]) ? this.caps[capabilityName] : JSON.parse(this.caps[capabilityName])
|
|
16
|
+
const values = jp.query(capabilityObject, jsonPath)
|
|
17
|
+
return !!(values && values.length > 0 && values.includes(value))
|
|
18
|
+
} else {
|
|
19
|
+
return this.caps[capabilityName] === value
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
onBotPrepare ({ convo, convoStep, args }) {
|
|
24
|
+
const conditionGroupId = args[1]
|
|
25
|
+
let params
|
|
26
|
+
try {
|
|
27
|
+
params = JSON.parse(args[0])
|
|
28
|
+
} catch (e) {
|
|
29
|
+
throw new Error(`ConditionalCapabilityValueBasedLogicHook: No parsable JSON object found in params: ${e}`)
|
|
30
|
+
}
|
|
31
|
+
convoStep.conditional = {
|
|
32
|
+
conditionGroupId
|
|
33
|
+
}
|
|
34
|
+
convoStep.conditional.skip = !this._isCapabilityValueEqual(params)
|
|
35
|
+
debug(`ConditionalCapabilityValueBasedLogicHook onBotPrepare ${convo.header.name}/${convoStep.stepTag}, args: ${util.inspect(args)}, convoStep.conditional: ${convoStep.conditional}`)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const util = require('util')
|
|
2
|
+
const jp = require('jsonpath')
|
|
3
|
+
const debug = require('debug')('botium-core-ConditionalJsonPathBasedLogicHook')
|
|
4
|
+
|
|
5
|
+
module.exports = class ConditionalJsonPathBasedLogicHook {
|
|
6
|
+
constructor (context, caps, globalArgs) {
|
|
7
|
+
this.context = context
|
|
8
|
+
this.caps = caps
|
|
9
|
+
this.globalArgs = globalArgs
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
onBotPrepare ({ convo, convoStep, args, botMsg }) {
|
|
13
|
+
const conditionGroupId = args[1]
|
|
14
|
+
let params
|
|
15
|
+
try {
|
|
16
|
+
params = JSON.parse(args[0])
|
|
17
|
+
} catch (e) {
|
|
18
|
+
throw new Error(`ConditionalJsonPathBasedLogicHook: No parsable JSON object found in params: ${e}`)
|
|
19
|
+
}
|
|
20
|
+
convoStep.conditional = {
|
|
21
|
+
conditionGroupId
|
|
22
|
+
}
|
|
23
|
+
let skip = true
|
|
24
|
+
if (params.jsonPath) {
|
|
25
|
+
const values = jp.query(botMsg, params.jsonPath)
|
|
26
|
+
skip = !(values && values.length > 0 && values.includes(params.value))
|
|
27
|
+
}
|
|
28
|
+
convoStep.conditional.skip = skip
|
|
29
|
+
debug(`ConditionalJsonPathBasedLogicHook onBotPrepare ${convo.header.name}/${convoStep.stepTag}, args: ${util.inspect(args)}, convoStep.conditional: ${convoStep.conditional}`)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const util = require('util')
|
|
2
|
+
const moment = require('moment-timezone')
|
|
3
|
+
const debug = require('debug')('botium-core-ConditionalTimeBasedLogicHook')
|
|
4
|
+
|
|
5
|
+
module.exports = class ConditionalTimeBasedLogicHook {
|
|
6
|
+
constructor (context, caps, globalArgs) {
|
|
7
|
+
this.context = context
|
|
8
|
+
this.caps = caps
|
|
9
|
+
this.globalArgs = globalArgs
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
_isBetween ({ now, start, end, timeZone }) {
|
|
13
|
+
now.tz(timeZone)
|
|
14
|
+
const momentStartTime = moment(start, 'HH:mm')
|
|
15
|
+
const startTime = now.clone().set({ hour: momentStartTime.hour(), minute: momentStartTime.minute() })
|
|
16
|
+
startTime.tz(timeZone)
|
|
17
|
+
const momentEndTime = moment(end, 'HH:mm')
|
|
18
|
+
const endTime = now.clone().set({ hour: momentEndTime.hour(), minute: momentEndTime.minute() })
|
|
19
|
+
endTime.tz(timeZone)
|
|
20
|
+
|
|
21
|
+
if (startTime.isSameOrAfter(endTime)) {
|
|
22
|
+
if (now.isSameOrAfter(startTime)) {
|
|
23
|
+
endTime.add(1, 'days')
|
|
24
|
+
} else {
|
|
25
|
+
startTime.add(-1, 'days')
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return now.isBetween(startTime, endTime, 'minutes', '[]')
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
onBotPrepare ({ convo, convoStep, args }) {
|
|
32
|
+
const conditionGroupId = args[1]
|
|
33
|
+
let params
|
|
34
|
+
try {
|
|
35
|
+
params = JSON.parse(args[0])
|
|
36
|
+
} catch (e) {
|
|
37
|
+
throw new Error(`ConditionalTimeBasedLogicHook: No parsable JSON object found in params: ${e}`)
|
|
38
|
+
}
|
|
39
|
+
convoStep.conditional = {
|
|
40
|
+
conditionGroupId
|
|
41
|
+
}
|
|
42
|
+
params.now = moment()
|
|
43
|
+
convoStep.conditional.skip = !this._isBetween(params)
|
|
44
|
+
debug(`ConditionalTimeBasedLogicHook onBotPrepare ${convo.header.name}/${convoStep.stepTag}, args: ${util.inspect(args)}, convoStep.conditional: ${convoStep.conditional}`)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -33,13 +33,13 @@ const afterCustom = async (thisParam) => {
|
|
|
33
33
|
|
|
34
34
|
describe('compiler.precompiler.script', function () {
|
|
35
35
|
it('should execute non-standard json', async function () {
|
|
36
|
-
await beforeCustom(this,
|
|
36
|
+
await beforeCustom(this, ({ scriptData }) => {
|
|
37
37
|
const utterances = {}
|
|
38
38
|
for (const entry of scriptData) {
|
|
39
39
|
utterances[entry.intent] = entry.sentences
|
|
40
40
|
}
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
return { utterances }
|
|
42
|
+
})
|
|
43
43
|
this.compiler.ReadScript(path.resolve(__dirname, 'convos'), 'convos_precompiler_script.json')
|
|
44
44
|
this.compiler.ExpandUtterancesToConvos()
|
|
45
45
|
this.compiler.ExpandConvos()
|
|
@@ -54,15 +54,15 @@ describe('compiler.precompiler.script', function () {
|
|
|
54
54
|
})
|
|
55
55
|
|
|
56
56
|
it('should filter by extension, accepted', async function () {
|
|
57
|
-
await beforeCustom(this,
|
|
58
|
-
|
|
57
|
+
await beforeCustom(this, ({ filename, scriptData }) => {
|
|
58
|
+
if (filename.endsWith('.json')) {
|
|
59
59
|
const utterances = {}
|
|
60
60
|
for (const entry of scriptData) {
|
|
61
61
|
utterances[entry.intent] = entry.sentences
|
|
62
62
|
}
|
|
63
|
-
|
|
63
|
+
return { utterances }
|
|
64
64
|
}
|
|
65
|
-
|
|
65
|
+
})
|
|
66
66
|
this.compiler.ReadScript(path.resolve(__dirname, 'convos'), 'convos_precompiler_script.json')
|
|
67
67
|
this.compiler.ExpandUtterancesToConvos()
|
|
68
68
|
this.compiler.ExpandConvos()
|
|
@@ -71,15 +71,15 @@ describe('compiler.precompiler.script', function () {
|
|
|
71
71
|
})
|
|
72
72
|
|
|
73
73
|
it('should filter by extension, rejected', async function () {
|
|
74
|
-
await beforeCustom(this,
|
|
75
|
-
|
|
74
|
+
await beforeCustom(this, ({ filename, scriptData }) => {
|
|
75
|
+
if (filename.endsWith('.xxx')) {
|
|
76
76
|
const utterances = {}
|
|
77
77
|
for (const entry of scriptData) {
|
|
78
78
|
utterances[entry.intent] = entry.sentences
|
|
79
79
|
}
|
|
80
|
-
|
|
80
|
+
return { utterances }
|
|
81
81
|
}
|
|
82
|
-
|
|
82
|
+
})
|
|
83
83
|
this.compiler.ReadScript(path.resolve(__dirname, 'convos'), 'convos_precompiler_script.json')
|
|
84
84
|
this.compiler.ExpandUtterancesToConvos()
|
|
85
85
|
this.compiler.ExpandConvos()
|
|
@@ -88,15 +88,15 @@ describe('compiler.precompiler.script', function () {
|
|
|
88
88
|
})
|
|
89
89
|
|
|
90
90
|
it('should filter by content, accepted', async function () {
|
|
91
|
-
await beforeCustom(this,
|
|
91
|
+
await beforeCustom(this, ({ scriptData }) => {
|
|
92
92
|
if (scriptData) {
|
|
93
93
|
const utterances = {}
|
|
94
94
|
for (const entry of scriptData) {
|
|
95
95
|
utterances[entry.intent] = entry.sentences
|
|
96
96
|
}
|
|
97
|
-
|
|
97
|
+
return { utterances }
|
|
98
98
|
}
|
|
99
|
-
|
|
99
|
+
})
|
|
100
100
|
this.compiler.ReadScript(path.resolve(__dirname, 'convos'), 'convos_precompiler_script.json')
|
|
101
101
|
this.compiler.ExpandUtterancesToConvos()
|
|
102
102
|
this.compiler.ExpandConvos()
|
|
@@ -105,15 +105,15 @@ describe('compiler.precompiler.script', function () {
|
|
|
105
105
|
})
|
|
106
106
|
|
|
107
107
|
it('should filter by content, rejected', async function () {
|
|
108
|
-
await beforeCustom(this,
|
|
108
|
+
await beforeCustom(this, ({ scriptData }) => {
|
|
109
109
|
if (scriptData.utterances) {
|
|
110
110
|
const utterances = {}
|
|
111
111
|
for (const entry of scriptData.utterances) {
|
|
112
112
|
utterances[entry.intent] = entry.sentences
|
|
113
113
|
}
|
|
114
|
-
|
|
114
|
+
return { utterances }
|
|
115
115
|
}
|
|
116
|
-
|
|
116
|
+
})
|
|
117
117
|
this.compiler.ReadScript(path.resolve(__dirname, 'convos'), 'convos_precompiler_script.json')
|
|
118
118
|
this.compiler.ExpandUtterancesToConvos()
|
|
119
119
|
this.compiler.ExpandConvos()
|
|
@@ -122,13 +122,13 @@ describe('compiler.precompiler.script', function () {
|
|
|
122
122
|
})
|
|
123
123
|
|
|
124
124
|
it('should change extension', async function () {
|
|
125
|
-
await beforeCustom(this,
|
|
125
|
+
await beforeCustom(this, ({ filename, scriptData }) => {
|
|
126
126
|
const utterances = {}
|
|
127
127
|
for (const entry of scriptData) {
|
|
128
128
|
utterances[entry.intent] = entry.sentences
|
|
129
129
|
}
|
|
130
|
-
|
|
131
|
-
|
|
130
|
+
return { scriptBuffer: { utterances }, filename: filename + '.json' }
|
|
131
|
+
})
|
|
132
132
|
this.compiler.ReadScript(path.resolve(__dirname, 'convos'), 'convos_precompiler_script.json.txt')
|
|
133
133
|
this.compiler.ExpandUtterancesToConvos()
|
|
134
134
|
this.compiler.ExpandConvos()
|
|
@@ -137,13 +137,13 @@ describe('compiler.precompiler.script', function () {
|
|
|
137
137
|
})
|
|
138
138
|
|
|
139
139
|
it('should not read anything without extension change', async function () {
|
|
140
|
-
await beforeCustom(this,
|
|
140
|
+
await beforeCustom(this, ({ scriptData }) => {
|
|
141
141
|
const utterances = {}
|
|
142
142
|
for (const entry of scriptData) {
|
|
143
143
|
utterances[entry.intent] = entry.sentences
|
|
144
144
|
}
|
|
145
|
-
|
|
146
|
-
|
|
145
|
+
return { scriptBuffer: { utterances } }
|
|
146
|
+
})
|
|
147
147
|
this.compiler.ReadScript(path.resolve(__dirname, 'convos'), 'convos_precompiler_script.json.txt')
|
|
148
148
|
this.compiler.ExpandUtterancesToConvos()
|
|
149
149
|
this.compiler.ExpandConvos()
|
|
@@ -152,9 +152,7 @@ describe('compiler.precompiler.script', function () {
|
|
|
152
152
|
})
|
|
153
153
|
|
|
154
154
|
it('should be able to precompile text to text', async function () {
|
|
155
|
-
await beforeCustom(this,
|
|
156
|
-
module.exports = scriptData.replace("Hi!", "Hi Bot!")
|
|
157
|
-
`)
|
|
155
|
+
await beforeCustom(this, ({ scriptData }) => scriptData.replace('Hi!', 'Hi Bot!'))
|
|
158
156
|
this.compiler.ReadScript(path.resolve(__dirname, 'convos'), 'convos_precompiler_script_text_to_text.convo.txt')
|
|
159
157
|
this.compiler.ExpandUtterancesToConvos()
|
|
160
158
|
this.compiler.ExpandConvos()
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
const assert = require('chai').assert
|
|
2
|
+
const BotDriver = require('../../').BotDriver
|
|
3
|
+
const Capabilities = require('../../').Capabilities
|
|
4
|
+
|
|
5
|
+
const echoConnectorWithMetadata = ({ queueBotSays }) => {
|
|
6
|
+
return {
|
|
7
|
+
UserSays (msg) {
|
|
8
|
+
const botMsg = {
|
|
9
|
+
sender: 'bot',
|
|
10
|
+
sourceData: msg.sourceData,
|
|
11
|
+
messageText: `Response of ${msg.messageText}`
|
|
12
|
+
}
|
|
13
|
+
queueBotSays(botMsg)
|
|
14
|
+
},
|
|
15
|
+
GetMetaData () {
|
|
16
|
+
return Promise.resolve('Sample response from GetMetaData')
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const echoConnectorWithoutMetadata = ({ queueBotSays }) => {
|
|
21
|
+
return {
|
|
22
|
+
UserSays (msg) {
|
|
23
|
+
const botMsg = {
|
|
24
|
+
sender: 'bot',
|
|
25
|
+
sourceData: msg.sourceData,
|
|
26
|
+
messageText: `Response of ${msg.messageText}`
|
|
27
|
+
}
|
|
28
|
+
queueBotSays(botMsg)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
describe('compiler.precompiler.json', function () {
|
|
34
|
+
beforeEach(async function () {
|
|
35
|
+
this.init = async (withGetMetaData) => {
|
|
36
|
+
const myCaps = {
|
|
37
|
+
[Capabilities.PROJECTNAME]: 'connector.basecontainer',
|
|
38
|
+
[Capabilities.CONTAINERMODE]: withGetMetaData ? echoConnectorWithMetadata : echoConnectorWithoutMetadata
|
|
39
|
+
}
|
|
40
|
+
const driver = new BotDriver(myCaps)
|
|
41
|
+
this.compiler = driver.BuildCompiler()
|
|
42
|
+
this.container = await driver.Build()
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
afterEach(async function () {
|
|
46
|
+
this.container && await this.container.Clean()
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it('should get metadata if its available', async function () {
|
|
50
|
+
await this.init(true)
|
|
51
|
+
const result = await this.container.GetMetaData()
|
|
52
|
+
assert.equal(result, 'Sample response from GetMetaData')
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
it('should get undefined if metadata is not available', async function () {
|
|
56
|
+
await this.init(false)
|
|
57
|
+
const result = await this.container.GetMetaData()
|
|
58
|
+
assert.equal(result, undefined)
|
|
59
|
+
})
|
|
60
|
+
})
|