botium-core 1.11.13 → 1.12.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 +692 -524
- package/dist/botium-cjs.js.map +1 -1
- package/dist/botium-es.js +323 -155
- package/dist/botium-es.js.map +1 -1
- package/package.json +30 -29
- package/samples/connectors/custom/botium-connector-myapi.js +3 -3
- package/samples/extensions/asserterHooks/DummyAsserter.js +3 -3
- package/src/Capabilities.js +7 -1
- package/src/Defaults.js +1 -0
- package/src/containers/plugins/SimpleRestContainer.js +129 -52
- package/src/scripting/CompilerCsv.js +1 -1
- package/src/scripting/MatchFunctions.js +21 -0
- package/src/scripting/ScriptingProvider.js +49 -40
- package/src/scripting/helper.js +3 -3
- package/src/scripting/logichook/LogicHookConsts.js +4 -0
- package/src/scripting/logichook/LogicHookUtils.js +2 -0
- package/src/scripting/logichook/asserter/JsonPathAsserter.js +1 -1
- package/src/scripting/logichook/asserter/TextWildcardExactAllAsserter.js +8 -0
- package/src/scripting/logichook/asserter/TextWildcardExactAllICAsserter.js +8 -0
- package/src/scripting/logichook/asserter/TextWildcardExactAnyAsserter.js +8 -0
- package/src/scripting/logichook/asserter/TextWildcardExactAnyICAsserter.js +8 -0
- package/src/scripting/logichook/logichooks/UpdateCustomLogicHook.js +3 -4
- package/test/connectors/convos/hello.convo.txt +6 -0
- package/test/connectors/simplerest.spec.js +129 -2
- package/test/scripting/asserters/convos/text_wildcardexact_all_nok.yml +7 -0
- package/test/scripting/asserters/convos/text_wildcardexact_all_ok.yml +7 -0
- package/test/scripting/asserters/convos/text_wildcardexact_any_nok.yml +7 -0
- package/test/scripting/asserters/convos/text_wildcardexact_any_ok.yml +7 -0
- package/test/scripting/asserters/textWildcardExactAllAsserter.spec.js +51 -0
- package/test/scripting/asserters/textWildcardExactAnyAsserter.spec.js +51 -0
- package/test/scripting/matching/matchingmode.spec.js +43 -0
|
@@ -464,11 +464,33 @@ module.exports = class ScriptingProvider {
|
|
|
464
464
|
return { convos: dirConvos, utterances: dirUtterances, pconvos: dirPartialConvos, scriptingMemories: dirScriptingMemories }
|
|
465
465
|
}
|
|
466
466
|
|
|
467
|
+
ReadScriptFromBuffer (scriptBuffer, scriptingFormat, scriptingTypes = null) {
|
|
468
|
+
if (_.isString(scriptingTypes)) scriptingTypes = [scriptingTypes]
|
|
469
|
+
if (_.isArray(scriptingTypes) && scriptingTypes.length === 0) scriptingTypes = null
|
|
470
|
+
|
|
471
|
+
const result = {
|
|
472
|
+
convos: [],
|
|
473
|
+
utterances: [],
|
|
474
|
+
pconvos: [],
|
|
475
|
+
scriptingMemories: []
|
|
476
|
+
}
|
|
477
|
+
if (!scriptingTypes || scriptingTypes.includes(Constants.SCRIPTING_TYPE_UTTERANCES)) {
|
|
478
|
+
result.utterances = this.Compile(scriptBuffer, scriptingFormat, Constants.SCRIPTING_TYPE_UTTERANCES)
|
|
479
|
+
}
|
|
480
|
+
if (!scriptingTypes || scriptingTypes.includes(Constants.SCRIPTING_TYPE_PCONVO)) {
|
|
481
|
+
result.pconvos = this.Compile(scriptBuffer, scriptingFormat, Constants.SCRIPTING_TYPE_PCONVO)
|
|
482
|
+
}
|
|
483
|
+
if (!scriptingTypes || scriptingTypes.includes(Constants.SCRIPTING_TYPE_CONVO)) {
|
|
484
|
+
result.convos = this.Compile(scriptBuffer, scriptingFormat, Constants.SCRIPTING_TYPE_CONVO)
|
|
485
|
+
}
|
|
486
|
+
if (!scriptingTypes || scriptingTypes.includes(Constants.SCRIPTING_TYPE_SCRIPTING_MEMORY)) {
|
|
487
|
+
result.scriptingMemories = this.Compile(scriptBuffer, scriptingFormat, Constants.SCRIPTING_TYPE_SCRIPTING_MEMORY)
|
|
488
|
+
}
|
|
489
|
+
return result
|
|
490
|
+
}
|
|
491
|
+
|
|
467
492
|
ReadScript (convoDir, filename) {
|
|
468
|
-
let
|
|
469
|
-
let fileUtterances = []
|
|
470
|
-
let filePartialConvos = []
|
|
471
|
-
let fileScriptingMemories = []
|
|
493
|
+
let result = {}
|
|
472
494
|
|
|
473
495
|
try {
|
|
474
496
|
let scriptBuffer = fs.readFileSync(path.resolve(convoDir, filename))
|
|
@@ -487,36 +509,25 @@ module.exports = class ScriptingProvider {
|
|
|
487
509
|
}
|
|
488
510
|
|
|
489
511
|
if (filename.endsWith('.xlsx') || filename.endsWith('.xlsm')) {
|
|
490
|
-
|
|
491
|
-
filePartialConvos = this.Compile(scriptBuffer, Constants.SCRIPTING_FORMAT_XSLX, Constants.SCRIPTING_TYPE_PCONVO)
|
|
492
|
-
fileConvos = this.Compile(scriptBuffer, Constants.SCRIPTING_FORMAT_XSLX, Constants.SCRIPTING_TYPE_CONVO)
|
|
493
|
-
fileScriptingMemories = this.Compile(scriptBuffer, Constants.SCRIPTING_FORMAT_XSLX, Constants.SCRIPTING_TYPE_SCRIPTING_MEMORY)
|
|
512
|
+
result = this.ReadScriptFromBuffer(scriptBuffer, Constants.SCRIPTING_FORMAT_XSLX, [Constants.SCRIPTING_TYPE_UTTERANCES, Constants.SCRIPTING_TYPE_PCONVO, Constants.SCRIPTING_TYPE_CONVO, Constants.SCRIPTING_TYPE_SCRIPTING_MEMORY])
|
|
494
513
|
} else if (filename.endsWith('.convo.txt')) {
|
|
495
|
-
|
|
514
|
+
result = this.ReadScriptFromBuffer(scriptBuffer, Constants.SCRIPTING_FORMAT_TXT, Constants.SCRIPTING_TYPE_CONVO)
|
|
496
515
|
} else if (filename.endsWith('.pconvo.txt')) {
|
|
497
|
-
|
|
516
|
+
result = this.ReadScriptFromBuffer(scriptBuffer, Constants.SCRIPTING_FORMAT_TXT, Constants.SCRIPTING_TYPE_PCONVO)
|
|
498
517
|
} else if (filename.endsWith('.utterances.txt')) {
|
|
499
|
-
|
|
518
|
+
result = this.ReadScriptFromBuffer(scriptBuffer, Constants.SCRIPTING_FORMAT_TXT, Constants.SCRIPTING_TYPE_UTTERANCES)
|
|
500
519
|
} else if (filename.endsWith('.scriptingmemory.txt')) {
|
|
501
|
-
|
|
520
|
+
result = this.ReadScriptFromBuffer(scriptBuffer, Constants.SCRIPTING_FORMAT_TXT, Constants.SCRIPTING_TYPE_SCRIPTING_MEMORY)
|
|
502
521
|
} else if (filename.endsWith('.convo.csv')) {
|
|
503
|
-
|
|
522
|
+
result = this.ReadScriptFromBuffer(scriptBuffer, Constants.SCRIPTING_FORMAT_CSV, Constants.SCRIPTING_TYPE_CONVO)
|
|
504
523
|
} else if (filename.endsWith('.pconvo.csv')) {
|
|
505
|
-
|
|
524
|
+
result = this.ReadScriptFromBuffer(scriptBuffer, Constants.SCRIPTING_FORMAT_CSV, Constants.SCRIPTING_TYPE_PCONVO)
|
|
506
525
|
} else if (filename.endsWith('.yaml') || filename.endsWith('.yml')) {
|
|
507
|
-
|
|
508
|
-
filePartialConvos = this.Compile(scriptBuffer, Constants.SCRIPTING_FORMAT_YAML, Constants.SCRIPTING_TYPE_PCONVO)
|
|
509
|
-
fileConvos = this.Compile(scriptBuffer, Constants.SCRIPTING_FORMAT_YAML, Constants.SCRIPTING_TYPE_CONVO)
|
|
510
|
-
fileScriptingMemories = this.Compile(scriptBuffer, Constants.SCRIPTING_FORMAT_YAML, Constants.SCRIPTING_TYPE_SCRIPTING_MEMORY)
|
|
526
|
+
result = this.ReadScriptFromBuffer(scriptBuffer, Constants.SCRIPTING_FORMAT_YAML, [Constants.SCRIPTING_TYPE_UTTERANCES, Constants.SCRIPTING_TYPE_PCONVO, Constants.SCRIPTING_TYPE_CONVO, Constants.SCRIPTING_TYPE_SCRIPTING_MEMORY])
|
|
511
527
|
} else if (filename.endsWith('.json')) {
|
|
512
|
-
|
|
513
|
-
filePartialConvos = this.Compile(scriptBuffer, Constants.SCRIPTING_FORMAT_JSON, Constants.SCRIPTING_TYPE_PCONVO)
|
|
514
|
-
fileConvos = this.Compile(scriptBuffer, Constants.SCRIPTING_FORMAT_JSON, Constants.SCRIPTING_TYPE_CONVO)
|
|
515
|
-
fileScriptingMemories = this.Compile(scriptBuffer, Constants.SCRIPTING_FORMAT_JSON, Constants.SCRIPTING_TYPE_SCRIPTING_MEMORY)
|
|
528
|
+
result = this.ReadScriptFromBuffer(scriptBuffer, Constants.SCRIPTING_FORMAT_JSON, [Constants.SCRIPTING_TYPE_UTTERANCES, Constants.SCRIPTING_TYPE_PCONVO, Constants.SCRIPTING_TYPE_CONVO, Constants.SCRIPTING_TYPE_SCRIPTING_MEMORY])
|
|
516
529
|
} else if (filename.endsWith('.markdown') || filename.endsWith('.md')) {
|
|
517
|
-
|
|
518
|
-
fileConvos = this.Compile(scriptBuffer, Constants.SCRIPTING_FORMAT_MARKDOWN, Constants.SCRIPTING_TYPE_CONVO)
|
|
519
|
-
filePartialConvos = this.Compile(scriptBuffer, Constants.SCRIPTING_FORMAT_MARKDOWN, Constants.SCRIPTING_TYPE_PCONVO)
|
|
530
|
+
result = this.ReadScriptFromBuffer(scriptBuffer, Constants.SCRIPTING_FORMAT_MARKDOWN, [Constants.SCRIPTING_TYPE_UTTERANCES, Constants.SCRIPTING_TYPE_PCONVO, Constants.SCRIPTING_TYPE_CONVO])
|
|
520
531
|
} else {
|
|
521
532
|
debug(`ReadScript - dropped file: ${filename}, filename not supported`)
|
|
522
533
|
}
|
|
@@ -526,42 +537,40 @@ module.exports = class ScriptingProvider {
|
|
|
526
537
|
}
|
|
527
538
|
|
|
528
539
|
// Compilers saved the convos, and we alter here the saved version too
|
|
529
|
-
if (
|
|
530
|
-
|
|
540
|
+
if (result.convos && result.convos.length > 0) {
|
|
541
|
+
result.convos.forEach((fileConvo) => {
|
|
531
542
|
fileConvo.sourceTag = { convoDir, filename }
|
|
532
543
|
if (!fileConvo.header.name) {
|
|
533
544
|
fileConvo.header.name = filename
|
|
534
545
|
}
|
|
535
546
|
})
|
|
536
547
|
const isSkip = (c) => c.header.name && skipPattern.test(c.header.name.toLowerCase())
|
|
537
|
-
|
|
538
|
-
|
|
548
|
+
result.convos.filter(c => isSkip(c)).forEach(c => debug(`ReadScript - skipping convo '${c.header.name}'`))
|
|
549
|
+
result.convos = result.convos.filter(c => !isSkip(c))
|
|
539
550
|
}
|
|
540
|
-
if (
|
|
541
|
-
|
|
551
|
+
if (result.pconvos && result.pconvos.length > 0) {
|
|
552
|
+
result.pconvos.forEach((filePartialConvo) => {
|
|
542
553
|
filePartialConvo.sourceTag = { convoDir, filename }
|
|
543
554
|
if (!filePartialConvo.header.name) {
|
|
544
555
|
filePartialConvo.header.name = filename
|
|
545
556
|
}
|
|
546
557
|
})
|
|
547
558
|
}
|
|
548
|
-
if (
|
|
549
|
-
|
|
559
|
+
if (result.scriptingMemories && result.scriptingMemories.length > 0) {
|
|
560
|
+
result.scriptingMemories.forEach((scriptingMemory) => {
|
|
550
561
|
scriptingMemory.sourceTag = { filename }
|
|
551
562
|
})
|
|
552
563
|
}
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
this.fileUtterances = this._tagAndCleanupUtterances(fileUtterances, convoDir, filename)
|
|
564
|
+
if (result.utterances) {
|
|
565
|
+
result.utterances = this._tagAndCleanupUtterances(result.utterances, convoDir, filename)
|
|
556
566
|
}
|
|
557
|
-
return { convos:
|
|
567
|
+
return { convos: result.convos || [], utterances: result.utterances || [], pconvos: result.pconvos || [], scriptingMemories: result.scriptingMemories || [] }
|
|
558
568
|
}
|
|
559
569
|
|
|
560
570
|
_tagAndCleanupUtterances (utteranceFiles, convoDir, filename) {
|
|
561
571
|
return utteranceFiles.map((fileUtt) => {
|
|
562
572
|
fileUtt.sourceTag = { convoDir, filename }
|
|
563
|
-
fileUtt.utterances = fileUtt.utterances
|
|
564
|
-
.filter(u => u)
|
|
573
|
+
fileUtt.utterances = fileUtt.utterances.filter(u => u)
|
|
565
574
|
return fileUtt
|
|
566
575
|
})
|
|
567
576
|
}
|
|
@@ -944,7 +953,7 @@ module.exports = class ScriptingProvider {
|
|
|
944
953
|
}
|
|
945
954
|
}
|
|
946
955
|
} else {
|
|
947
|
-
expandedConvos.push(Object.assign(_.cloneDeep(currentConvo), { conversation: convoStepsStack }))
|
|
956
|
+
expandedConvos.push(Object.assign(_.cloneDeep(currentConvo), { conversation: _.cloneDeep(convoStepsStack) }))
|
|
948
957
|
}
|
|
949
958
|
}
|
|
950
959
|
|
package/src/scripting/helper.js
CHANGED
|
@@ -72,7 +72,7 @@ const toString = (value) => {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
const flatString = (str) => {
|
|
75
|
-
return str.split('\n').map(s => s.trim()).join(' ')
|
|
75
|
+
return str ? str.split('\n').map(s => s.trim()).join(' ') : ''
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
const linesToConvoStep = (lines, sender, context, eol, singleLineMode = false) => {
|
|
@@ -439,7 +439,7 @@ const convoStepToLines = (step) => {
|
|
|
439
439
|
if (step.messageText) {
|
|
440
440
|
lines.push((step.optional ? '?' : '') + (step.not ? '!' : '') + step.messageText)
|
|
441
441
|
}
|
|
442
|
-
if (step.buttons && step.buttons.length > 0) lines.push('BUTTONS ' + step.buttons.map(b => flatString(b.text)).join('|'))
|
|
442
|
+
if (step.buttons && step.buttons.length > 0) lines.push('BUTTONS ' + step.buttons.filter(b => b.text).map(b => flatString(b.text)).join('|'))
|
|
443
443
|
if (step.media && step.media.length > 0) lines.push('MEDIA ' + step.media.filter(m => !m.buffer && m.mediaUri).map(m => m.mediaUri).join('|'))
|
|
444
444
|
if (step.cards && step.cards.length > 0) {
|
|
445
445
|
step.cards.forEach(c => {
|
|
@@ -449,7 +449,7 @@ const convoStepToLines = (step) => {
|
|
|
449
449
|
if (c.content) cardTexts = cardTexts.concat(_.isArray(c.content) ? c.content : [c.content])
|
|
450
450
|
if (cardTexts.length > 0) lines.push('CARDS ' + cardTexts.map(c => flatString(c)).join('|'))
|
|
451
451
|
|
|
452
|
-
if (c.buttons && c.buttons.length > 0) lines.push('BUTTONS ' + c.buttons.map(b => flatString(b.text)).join('|'))
|
|
452
|
+
if (c.buttons && c.buttons.length > 0) lines.push('BUTTONS ' + c.buttons.filter(b => b.text).map(b => flatString(b.text)).join('|'))
|
|
453
453
|
if (c.image && !c.image.buffer && c.image.mediaUri) lines.push('MEDIA ' + c.image.mediaUri)
|
|
454
454
|
})
|
|
455
455
|
}
|
|
@@ -33,6 +33,10 @@ module.exports = {
|
|
|
33
33
|
{ name: 'TEXT_WILDCARD_ANY_IC', className: 'TextWildcardAnyICAsserter' },
|
|
34
34
|
{ name: 'TEXT_WILDCARD_ALL', className: 'TextWildcardAllAsserter' },
|
|
35
35
|
{ name: 'TEXT_WILDCARD_ALL_IC', className: 'TextWildcardAllICAsserter' },
|
|
36
|
+
{ name: 'TEXT_WILDCARDEXACT_ANY', className: 'TextWildcardExactAnyAsserter' },
|
|
37
|
+
{ name: 'TEXT_WILDCARDEXACT_ANY_IC', className: 'TextWildcardExactAnyICAsserter' },
|
|
38
|
+
{ name: 'TEXT_WILDCARDEXACT_ALL', className: 'TextWildcardExactAllAsserter' },
|
|
39
|
+
{ name: 'TEXT_WILDCARDEXACT_ALL_IC', className: 'TextWildcardExactAllICAsserter' },
|
|
36
40
|
{ name: 'TEXT_REGEXP_ANY', className: 'TextRegexpAnyAsserter' },
|
|
37
41
|
{ name: 'TEXT_REGEXP_ANY_IC', className: 'TextRegexpAnyICAsserter' },
|
|
38
42
|
{ name: 'TEXT_REGEXP_ALL', className: 'TextRegexpAllAsserter' },
|
|
@@ -240,6 +240,8 @@ module.exports = class LogicHookUtils {
|
|
|
240
240
|
return CheckClass({ ref, ...this.buildScriptContext }, this.caps, args)
|
|
241
241
|
} else if (isClass(CheckClass.PluginClass)) {
|
|
242
242
|
return new CheckClass.PluginClass({ ref, ...this.buildScriptContext }, this.caps, args)
|
|
243
|
+
} else if (_.isFunction(CheckClass.PluginClass)) {
|
|
244
|
+
return CheckClass.PluginClass({ ref, ...this.buildScriptContext }, this.caps, args)
|
|
243
245
|
} else {
|
|
244
246
|
throw new Error(`${src} class or function expected`)
|
|
245
247
|
}
|
|
@@ -118,7 +118,7 @@ module.exports = class JsonPathAsserter {
|
|
|
118
118
|
}
|
|
119
119
|
},
|
|
120
120
|
cause: {
|
|
121
|
-
expected: assert || (args && `any element for ${args.join('|')}`) || (!args && `any element in ${path}`),
|
|
121
|
+
expected: assert || ((args && args.length > 0) && `any element for ${args.join('|')}`) || ((!args || args.length === 0) && `any element in ${path}`),
|
|
122
122
|
actual: null,
|
|
123
123
|
path
|
|
124
124
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
const BaseTextAsserter = require('./BaseTextAsserter')
|
|
2
|
+
const MatchFunctions = require('../../MatchFunctions')
|
|
3
|
+
|
|
4
|
+
module.exports = class TextWildcardExactAnyAsserter extends BaseTextAsserter {
|
|
5
|
+
constructor (context, caps = {}) {
|
|
6
|
+
super(context, caps, MatchFunctions.wildcardExact(false), 'all')
|
|
7
|
+
}
|
|
8
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
const BaseTextAsserter = require('./BaseTextAsserter')
|
|
2
|
+
const MatchFunctions = require('../../MatchFunctions')
|
|
3
|
+
|
|
4
|
+
module.exports = class TextWildcardExactAnyAsserter extends BaseTextAsserter {
|
|
5
|
+
constructor (context, caps = {}) {
|
|
6
|
+
super(context, caps, MatchFunctions.wildcardExact(true), 'all')
|
|
7
|
+
}
|
|
8
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
const BaseTextAsserter = require('./BaseTextAsserter')
|
|
2
|
+
const MatchFunctions = require('../../MatchFunctions')
|
|
3
|
+
|
|
4
|
+
module.exports = class TextWildcardExactAnyAsserter extends BaseTextAsserter {
|
|
5
|
+
constructor (context, caps = {}) {
|
|
6
|
+
super(context, caps, MatchFunctions.wildcardExact(false), 'any')
|
|
7
|
+
}
|
|
8
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
const BaseTextAsserter = require('./BaseTextAsserter')
|
|
2
|
+
const MatchFunctions = require('../../MatchFunctions')
|
|
3
|
+
|
|
4
|
+
module.exports = class TextWildcardExactAnyAsserter extends BaseTextAsserter {
|
|
5
|
+
constructor (context, caps = {}) {
|
|
6
|
+
super(context, caps, MatchFunctions.wildcardExact(true), 'any')
|
|
7
|
+
}
|
|
8
|
+
}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
const util = require('util')
|
|
2
2
|
const _ = require('lodash')
|
|
3
3
|
|
|
4
|
-
const { isStringJson } = require('../../../helpers/Utils')
|
|
5
|
-
|
|
6
4
|
module.exports = class UpdateCustomLogicHook {
|
|
7
5
|
constructor (context, caps = {}, globalArgs = {}) {
|
|
8
6
|
this.context = context
|
|
@@ -58,10 +56,11 @@ module.exports = class UpdateCustomLogicHook {
|
|
|
58
56
|
}
|
|
59
57
|
|
|
60
58
|
_getValue (raw) {
|
|
61
|
-
|
|
59
|
+
try {
|
|
62
60
|
return JSON.parse(raw)
|
|
61
|
+
} catch (e) {
|
|
62
|
+
return raw
|
|
63
63
|
}
|
|
64
|
-
return raw
|
|
65
64
|
}
|
|
66
65
|
|
|
67
66
|
_update (args, meMsg) {
|
|
@@ -22,6 +22,12 @@ const myCapsPost = {
|
|
|
22
22
|
[Capabilities.SIMPLEREST_BODY_TEMPLATE]: { BODY1: 'BODY1VALUE', BODY2: '{{msg.messageText}}' },
|
|
23
23
|
[Capabilities.SIMPLEREST_RESPONSE_JSONPATH]: ['$']
|
|
24
24
|
}
|
|
25
|
+
const myCapsFormPost = {
|
|
26
|
+
[Capabilities.CONTAINERMODE]: 'simplerest',
|
|
27
|
+
[Capabilities.SIMPLEREST_URL]: 'http://my-host.com/api/endpoint/{{msg.messageText}}',
|
|
28
|
+
[Capabilities.SIMPLEREST_METHOD]: 'POST',
|
|
29
|
+
[Capabilities.SIMPLEREST_RESPONSE_JSONPATH]: ['$']
|
|
30
|
+
}
|
|
25
31
|
|
|
26
32
|
const myCapsScriptingMemory = {
|
|
27
33
|
[Capabilities.CONTAINERMODE]: 'simplerest',
|
|
@@ -448,7 +454,7 @@ describe('connectors.simplerest.build', function () {
|
|
|
448
454
|
assert.isTrue(err.message.includes('Cant load hook, syntax is not valid'))
|
|
449
455
|
}
|
|
450
456
|
})
|
|
451
|
-
it('should query params from UPDATE_CUSTOM (without "?")', async function () {
|
|
457
|
+
it('should add query params from UPDATE_CUSTOM (without "?")', async function () {
|
|
452
458
|
const myCaps = Object.assign({}, myCapsGet)
|
|
453
459
|
const myMsg = Object.assign({}, msg)
|
|
454
460
|
myMsg.ADD_QUERY_PARAM = {
|
|
@@ -467,7 +473,7 @@ describe('connectors.simplerest.build', function () {
|
|
|
467
473
|
|
|
468
474
|
await container.Clean()
|
|
469
475
|
})
|
|
470
|
-
it('should query params from UPDATE_CUSTOM (with "?")', async function () {
|
|
476
|
+
it('should add query params from UPDATE_CUSTOM (with "?")', async function () {
|
|
471
477
|
const myCaps = Object.assign({}, myCapsGet)
|
|
472
478
|
myCaps.SIMPLEREST_URL = 'http://my-host.com/api/endpoint/messageText?const1=const1'
|
|
473
479
|
const myMsg = Object.assign({}, msg)
|
|
@@ -510,6 +516,26 @@ describe('connectors.simplerest.build', function () {
|
|
|
510
516
|
|
|
511
517
|
await container.Clean()
|
|
512
518
|
})
|
|
519
|
+
it('should add form params from UPDATE_CUSTOM (without "?")', async function () {
|
|
520
|
+
const myCaps = Object.assign({}, myCapsFormPost)
|
|
521
|
+
const myMsg = Object.assign({}, msg)
|
|
522
|
+
myMsg.ADD_FORM_PARAM = {
|
|
523
|
+
formparam1: 'valueparam1',
|
|
524
|
+
formparam2: '{{msg.messageText}}'
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
const driver = new BotDriver(myCaps)
|
|
528
|
+
const container = await driver.Build()
|
|
529
|
+
assert.equal(container.pluginInstance.constructor.name, 'SimpleRestContainer')
|
|
530
|
+
|
|
531
|
+
await container.Start()
|
|
532
|
+
const request = await container.pluginInstance._buildRequest(myMsg)
|
|
533
|
+
assert.isObject(request.form)
|
|
534
|
+
assert.equal(request.form.formparam1, 'valueparam1')
|
|
535
|
+
assert.equal(request.form.formparam2, 'messageText')
|
|
536
|
+
|
|
537
|
+
await container.Clean()
|
|
538
|
+
})
|
|
513
539
|
it('should add header from UPDATE_CUSTOM', async function () {
|
|
514
540
|
const myCaps = Object.assign({}, myCapsGet)
|
|
515
541
|
const myMsg = Object.assign({}, msg)
|
|
@@ -782,9 +808,14 @@ describe('connectors.simplerest.useresponse', function () {
|
|
|
782
808
|
this.scope = nock('https://mock.com')
|
|
783
809
|
.get('/ping').reply(200, { text: 'response from ping' })
|
|
784
810
|
.get('/pingtrash').reply(200, 'asdfasdfasdfasdf')
|
|
811
|
+
.get('/pingencoded').reply(200, { text: JSON.stringify({ prop: 'response from ping' }) })
|
|
812
|
+
.get('/pingstring').reply(200, 'response from ping')
|
|
785
813
|
.get('/start').reply(200, { text: 'response from start' })
|
|
786
814
|
.get('/starttrash').reply(200, 'asdfasdfasdfasdf')
|
|
815
|
+
.get('/startencoded').reply(200, { text: JSON.stringify({ prop: 'response from start' }) })
|
|
816
|
+
.get('/startstring').reply(200, 'response from start')
|
|
787
817
|
.get('/msg').reply(200, { text: 'response from msg' })
|
|
818
|
+
.get('/msgfail').reply(400, { error: 'failure text' })
|
|
788
819
|
.persist()
|
|
789
820
|
|
|
790
821
|
const myCaps = Object.assign({
|
|
@@ -832,6 +863,32 @@ describe('connectors.simplerest.useresponse', function () {
|
|
|
832
863
|
}
|
|
833
864
|
})
|
|
834
865
|
|
|
866
|
+
it('should use parser to parse response from ping', async function () {
|
|
867
|
+
await this.init({
|
|
868
|
+
[Capabilities.SIMPLEREST_PING_URL]: 'https://mock.com/pingencoded',
|
|
869
|
+
[Capabilities.SIMPLEREST_PING_PROCESS_RESPONSE]: true,
|
|
870
|
+
[Capabilities.SIMPLEREST_PARSER_HOOK]: 'body.text = JSON.parse(body.text).prop'
|
|
871
|
+
})
|
|
872
|
+
|
|
873
|
+
this.compiler.ReadScript(path.resolve(__dirname, 'convos'), 'responsefromping.convo.txt')
|
|
874
|
+
const transcript = await this.compiler.convos[0].Run(this.container)
|
|
875
|
+
assert.equal(transcript.steps.length, 1)
|
|
876
|
+
assert.equal(transcript.steps[0].actual.messageText, 'response from ping')
|
|
877
|
+
})
|
|
878
|
+
|
|
879
|
+
it('should use parser to parse string from ping', async function () {
|
|
880
|
+
await this.init({
|
|
881
|
+
[Capabilities.SIMPLEREST_PING_URL]: 'https://mock.com/pingstring',
|
|
882
|
+
[Capabilities.SIMPLEREST_PING_PROCESS_RESPONSE]: true,
|
|
883
|
+
[Capabilities.SIMPLEREST_PARSER_HOOK]: 'changeBody({ text: body })'
|
|
884
|
+
})
|
|
885
|
+
|
|
886
|
+
this.compiler.ReadScript(path.resolve(__dirname, 'convos'), 'responsefromping.convo.txt')
|
|
887
|
+
const transcript = await this.compiler.convos[0].Run(this.container)
|
|
888
|
+
assert.equal(transcript.steps.length, 1)
|
|
889
|
+
assert.equal(transcript.steps[0].actual.messageText, 'response from ping')
|
|
890
|
+
})
|
|
891
|
+
|
|
835
892
|
it('should use response from start', async function () {
|
|
836
893
|
await this.init({
|
|
837
894
|
[Capabilities.SIMPLEREST_START_URL]: 'https://mock.com/start',
|
|
@@ -858,6 +915,45 @@ describe('connectors.simplerest.useresponse', function () {
|
|
|
858
915
|
assert.isTrue(err.message.indexOf('Bot did not respond within') >= 0)
|
|
859
916
|
}
|
|
860
917
|
})
|
|
918
|
+
|
|
919
|
+
it('should use parser to parse response from ping', async function () {
|
|
920
|
+
await this.init({
|
|
921
|
+
[Capabilities.SIMPLEREST_START_URL]: 'https://mock.com/startencoded',
|
|
922
|
+
[Capabilities.SIMPLEREST_START_PROCESS_RESPONSE]: true,
|
|
923
|
+
[Capabilities.SIMPLEREST_PARSER_HOOK]: 'body.text = JSON.parse(body.text).prop'
|
|
924
|
+
})
|
|
925
|
+
|
|
926
|
+
this.compiler.ReadScript(path.resolve(__dirname, 'convos'), 'responsefromstart.convo.txt')
|
|
927
|
+
const transcript = await this.compiler.convos[0].Run(this.container)
|
|
928
|
+
assert.equal(transcript.steps.length, 1)
|
|
929
|
+
assert.equal(transcript.steps[0].actual.messageText, 'response from start')
|
|
930
|
+
})
|
|
931
|
+
|
|
932
|
+
it('should use parser to parse string from ping', async function () {
|
|
933
|
+
await this.init({
|
|
934
|
+
[Capabilities.SIMPLEREST_START_URL]: 'https://mock.com/startstring',
|
|
935
|
+
[Capabilities.SIMPLEREST_START_PROCESS_RESPONSE]: true,
|
|
936
|
+
[Capabilities.SIMPLEREST_PARSER_HOOK]: 'changeBody({ text: body })'
|
|
937
|
+
})
|
|
938
|
+
|
|
939
|
+
this.compiler.ReadScript(path.resolve(__dirname, 'convos'), 'responsefromstart.convo.txt')
|
|
940
|
+
const transcript = await this.compiler.convos[0].Run(this.container)
|
|
941
|
+
assert.equal(transcript.steps.length, 1)
|
|
942
|
+
assert.equal(transcript.steps[0].actual.messageText, 'response from start')
|
|
943
|
+
})
|
|
944
|
+
|
|
945
|
+
it('should use error body content', async function () {
|
|
946
|
+
await this.init({
|
|
947
|
+
[Capabilities.SIMPLEREST_URL]: 'https://mock.com/msgfail'
|
|
948
|
+
})
|
|
949
|
+
|
|
950
|
+
this.compiler.ReadScript(path.resolve(__dirname, 'convos'), 'hello.convo.txt')
|
|
951
|
+
try {
|
|
952
|
+
await this.compiler.convos[0].Run(this.container)
|
|
953
|
+
} catch (err) {
|
|
954
|
+
assert.isTrue(err.message.indexOf('failure text') >= 0)
|
|
955
|
+
}
|
|
956
|
+
})
|
|
861
957
|
})
|
|
862
958
|
|
|
863
959
|
describe('connectors.simplerest.inbound', function () {
|
|
@@ -985,6 +1081,37 @@ describe('connectors.simplerest.polling', function () {
|
|
|
985
1081
|
await container.WaitBotSays()
|
|
986
1082
|
await container.WaitBotSays()
|
|
987
1083
|
|
|
1084
|
+
await container.Stop()
|
|
1085
|
+
await container.Clean()
|
|
1086
|
+
scope.persist(false)
|
|
1087
|
+
}).timeout(5000)
|
|
1088
|
+
it('should use request hook for polling', async () => {
|
|
1089
|
+
const caps = {
|
|
1090
|
+
[Capabilities.CONTAINERMODE]: 'simplerest',
|
|
1091
|
+
[Capabilities.SIMPLEREST_URL]: () => 'https://mock.com/endpoint',
|
|
1092
|
+
[Capabilities.SIMPLEREST_RESPONSE_JSONPATH]: () => ['$.text'],
|
|
1093
|
+
[Capabilities.SIMPLEREST_POLL_URL]: () => 'https://mock.com/poll',
|
|
1094
|
+
[Capabilities.SIMPLEREST_POLL_REQUEST_HOOK]: 'requestOptions.uri = "https://mock.com/_from_hook"'
|
|
1095
|
+
}
|
|
1096
|
+
const scope = nock('https://mock.com')
|
|
1097
|
+
.get('/endpoint')
|
|
1098
|
+
.reply(200, {
|
|
1099
|
+
text: 'you called me'
|
|
1100
|
+
})
|
|
1101
|
+
.get('/_from_hook')
|
|
1102
|
+
.reply(200, {
|
|
1103
|
+
text: 'you called me'
|
|
1104
|
+
})
|
|
1105
|
+
.persist()
|
|
1106
|
+
|
|
1107
|
+
const driver = new BotDriver(caps)
|
|
1108
|
+
const container = await driver.Build()
|
|
1109
|
+
await container.Start()
|
|
1110
|
+
|
|
1111
|
+
await container.UserSays({ text: 'hallo' })
|
|
1112
|
+
await container.WaitBotSays()
|
|
1113
|
+
await container.WaitBotSays()
|
|
1114
|
+
|
|
988
1115
|
await container.Stop()
|
|
989
1116
|
await container.Clean()
|
|
990
1117
|
scope.persist(false)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const assert = require('chai').assert
|
|
2
|
+
const path = require('path')
|
|
3
|
+
|
|
4
|
+
const BotDriver = require('../../..').BotDriver
|
|
5
|
+
const Capabilities = require('../../..').Capabilities
|
|
6
|
+
|
|
7
|
+
const echoConnector = ({ queueBotSays }) => {
|
|
8
|
+
return {
|
|
9
|
+
UserSays (msg) {
|
|
10
|
+
const botMsg = { sender: 'bot', sourceData: msg.sourceData, messageText: msg.messageText }
|
|
11
|
+
queueBotSays(botMsg)
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
describe('scripting.asserters.textWildcardExactAllAsserter', function () {
|
|
17
|
+
beforeEach(async function () {
|
|
18
|
+
const myCaps = {
|
|
19
|
+
[Capabilities.PROJECTNAME]: 'scripting.asserters.textWildcardExactAllAsserter',
|
|
20
|
+
[Capabilities.CONTAINERMODE]: echoConnector
|
|
21
|
+
}
|
|
22
|
+
const driver = new BotDriver(myCaps)
|
|
23
|
+
this.compiler = driver.BuildCompiler()
|
|
24
|
+
this.container = await driver.Build()
|
|
25
|
+
})
|
|
26
|
+
afterEach(async function () {
|
|
27
|
+
this.container && await this.container.Clean()
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it('ok', async function () {
|
|
31
|
+
this.compiler.ReadScriptsFromDirectory(path.resolve(__dirname, 'convos', 'text_wildcardexact_all_ok.yml'))
|
|
32
|
+
|
|
33
|
+
this.compiler.ExpandScriptingMemoryToConvos()
|
|
34
|
+
assert.equal(this.compiler.convos.length, 1)
|
|
35
|
+
await this.compiler.convos[0].Run(this.container)
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
it('nok', async function () {
|
|
39
|
+
this.compiler.ReadScriptsFromDirectory(path.resolve(__dirname, 'convos', 'text_wildcardexact_all_nok.yml'))
|
|
40
|
+
|
|
41
|
+
this.compiler.ExpandScriptingMemoryToConvos()
|
|
42
|
+
assert.equal(this.compiler.convos.length, 1)
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
await this.compiler.convos[0].Run(this.container)
|
|
46
|
+
assert.fail('expected error')
|
|
47
|
+
} catch (err) {
|
|
48
|
+
assert.equal(err.message, 'text_wildcardexact_all_nok/Line 2: assertion error - Line 2: Expected text(s) in response "Im Joe, my number is 12345, and my ID is id2_*3"')
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
})
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const assert = require('chai').assert
|
|
2
|
+
const path = require('path')
|
|
3
|
+
|
|
4
|
+
const BotDriver = require('../../..').BotDriver
|
|
5
|
+
const Capabilities = require('../../..').Capabilities
|
|
6
|
+
|
|
7
|
+
const echoConnector = ({ queueBotSays }) => {
|
|
8
|
+
return {
|
|
9
|
+
UserSays (msg) {
|
|
10
|
+
const botMsg = { sender: 'bot', sourceData: msg.sourceData, messageText: msg.messageText }
|
|
11
|
+
queueBotSays(botMsg)
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
describe('scripting.asserters.textWildcardExactAnyAsserter', function () {
|
|
17
|
+
beforeEach(async function () {
|
|
18
|
+
const myCaps = {
|
|
19
|
+
[Capabilities.PROJECTNAME]: 'scripting.asserters.textWildcardExactAnyAsserter',
|
|
20
|
+
[Capabilities.CONTAINERMODE]: echoConnector
|
|
21
|
+
}
|
|
22
|
+
const driver = new BotDriver(myCaps)
|
|
23
|
+
this.compiler = driver.BuildCompiler()
|
|
24
|
+
this.container = await driver.Build()
|
|
25
|
+
})
|
|
26
|
+
afterEach(async function () {
|
|
27
|
+
this.container && await this.container.Clean()
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it('ok', async function () {
|
|
31
|
+
this.compiler.ReadScriptsFromDirectory(path.resolve(__dirname, 'convos', 'text_wildcardexact_any_ok.yml'))
|
|
32
|
+
|
|
33
|
+
this.compiler.ExpandScriptingMemoryToConvos()
|
|
34
|
+
assert.equal(this.compiler.convos.length, 1)
|
|
35
|
+
await this.compiler.convos[0].Run(this.container)
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
it('nok', async function () {
|
|
39
|
+
this.compiler.ReadScriptsFromDirectory(path.resolve(__dirname, 'convos', 'text_wildcardexact_any_nok.yml'))
|
|
40
|
+
|
|
41
|
+
this.compiler.ExpandScriptingMemoryToConvos()
|
|
42
|
+
assert.equal(this.compiler.convos.length, 1)
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
await this.compiler.convos[0].Run(this.container)
|
|
46
|
+
assert.fail('expected error')
|
|
47
|
+
} catch (err) {
|
|
48
|
+
assert.equal(err.message, 'text_wildcardexact_any_nok/Line 2: assertion error - Line 2: Expected any text in response "Im Joe, my number is 12345, and my ID is id2_*3,Im Joe, my number is 12345, and my ID is id3_*3"')
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
})
|
|
@@ -206,6 +206,49 @@ describe('matching.matchingmode.wildcardIgnoreCase', function () {
|
|
|
206
206
|
})
|
|
207
207
|
})
|
|
208
208
|
|
|
209
|
+
describe('matching.matchingmode.wildcardExact', function () {
|
|
210
|
+
beforeEach(async function () {
|
|
211
|
+
const myCaps = {
|
|
212
|
+
[Capabilities.PROJECTNAME]: 'matching.matchingmode',
|
|
213
|
+
[Capabilities.CONTAINERMODE]: echoConnector,
|
|
214
|
+
[Capabilities.SCRIPTING_MATCHING_MODE]: 'wildcardExact'
|
|
215
|
+
}
|
|
216
|
+
const driver = new BotDriver(myCaps)
|
|
217
|
+
this.compiler = driver.BuildCompiler()
|
|
218
|
+
this.container = await driver.Build()
|
|
219
|
+
})
|
|
220
|
+
afterEach(async function () {
|
|
221
|
+
this.container && await this.container.Clean()
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
it('should not match response with substring', async function () {
|
|
225
|
+
assert.isFalse(this.compiler.Match('Interesting...', 'Interesting'))
|
|
226
|
+
})
|
|
227
|
+
it('should match long response with wildcard', async function () {
|
|
228
|
+
assert.isTrue(this.compiler.Match('this is a long text', 'this is a * text'))
|
|
229
|
+
})
|
|
230
|
+
it('should match very long response with wildcard', async function () {
|
|
231
|
+
assert.isTrue(this.compiler.Match('this is a long text this is a long text this is a long text this is a long text', 'this is a * text this is a * text this is a * text this is a * text'))
|
|
232
|
+
})
|
|
233
|
+
it('should not match long uppcercase response with wildcard', async function () {
|
|
234
|
+
assert.isFalse(this.compiler.Match('THIS IS A LONG TEXT', 'this is a * text'))
|
|
235
|
+
})
|
|
236
|
+
it('should match very long response with very long wildcard', async function () {
|
|
237
|
+
assert.isTrue(this.compiler.Match('begin this is a long text this is a long text this is a long text this is a long text end', 'begin * end'))
|
|
238
|
+
})
|
|
239
|
+
it('should not allow more than 10 wildcards in a string', async function () {
|
|
240
|
+
try {
|
|
241
|
+
this.compiler.Match('some text', 'begin * * * * * * * * * * * end')
|
|
242
|
+
assert.fail('should have failed')
|
|
243
|
+
} catch (err) {
|
|
244
|
+
assert.equal(err.message, 'Maximum number of 10 wildcards supported.')
|
|
245
|
+
}
|
|
246
|
+
})
|
|
247
|
+
it('should not match if pattern is not matching', async function () {
|
|
248
|
+
assert.isFalse(this.compiler.Match('This is a long text', '*notthere*'))
|
|
249
|
+
})
|
|
250
|
+
})
|
|
251
|
+
|
|
209
252
|
describe('matching.matchingmode.equals', function () {
|
|
210
253
|
beforeEach(async function () {
|
|
211
254
|
const myCaps = {
|