botium-core 1.13.19 → 1.14.1

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.
Files changed (41) hide show
  1. package/dist/botium-cjs.js +328 -395
  2. package/dist/botium-cjs.js.map +1 -1
  3. package/dist/botium-es.js +328 -393
  4. package/dist/botium-es.js.map +1 -1
  5. package/package.json +24 -29
  6. package/samples/extensions/asserterHooks/botium.json +1 -0
  7. package/samples/extensions/logichooks/botium.json +1 -0
  8. package/samples/extensions/logichooks/custom/MyAsserter.js +3 -3
  9. package/src/Capabilities.js +2 -1
  10. package/src/containers/PluginConnectorContainer.js +8 -0
  11. package/src/containers/plugins/SimpleRestContainer.js +17 -9
  12. package/src/containers/plugins/index.js +29 -41
  13. package/src/helpers/HookUtils.js +32 -68
  14. package/src/scripting/Convo.js +26 -9
  15. package/src/scripting/ScriptingMemory.js +0 -24
  16. package/src/scripting/logichook/LogicHookUtils.js +27 -47
  17. package/src/scripting/logichook/logichooks/ConditionalBusinessHoursLogicHook.js +1 -1
  18. package/src/scripting/logichook/logichooks/ConditionalCapabilityValueBasedLogicHook.js +1 -1
  19. package/src/scripting/logichook/logichooks/ConditionalJsonPathBasedLogicHook.js +1 -1
  20. package/src/scripting/logichook/logichooks/ConditionalTimeBasedLogicHook.js +1 -1
  21. package/test/compiler/precompilerscript.spec.js +24 -26
  22. package/test/connectors/pluginconnectorcontainer.spec.js +60 -0
  23. package/test/connectors/simplerest.spec.js +24 -27
  24. package/test/convo/fillAndApplyScriptingMemory.spec.js +1 -47
  25. package/test/hooks/customhooks.spec.js +3 -25
  26. package/test/logichooks/hookfromsrc.spec.js +13 -3
  27. package/test/plugins/plugins.spec.js +29 -2
  28. package/test/scripting/logichooks/convos/conditional_steps_multiple_condition_groups_no_assertion.convo.txt +6 -6
  29. package/test/scripting/logichooks/convos/conditional_steps_multiple_mandatory_condition_groups.convo.txt +20 -0
  30. package/test/scripting/logichooks/convos/conditional_steps_multiple_optional_condition_groups.convo.txt +20 -0
  31. package/test/scripting/logichooks/customConditionalStepLogicHook.spec.js +16 -0
  32. package/test/security/allowUnsafe.spec.js +20 -129
  33. package/LICENSES-3RDPARTY.txt +0 -6450
  34. package/test/scripting/asserters/convos/customembeddedasserterwithhugo.convo.txt +0 -7
  35. package/test/scripting/asserters/convos/customembeddedasserterwithouthugo.convo.txt +0 -7
  36. package/test/scripting/asserters/customEmbeddedAsserter.json +0 -14
  37. package/test/scripting/asserters/customEmbeddedAsserter.spec.js +0 -55
  38. package/test/scripting/logichooks/convos/custom_embedded.convo.txt +0 -8
  39. package/test/scripting/logichooks/customEmbedded.json +0 -14
  40. package/test/scripting/logichooks/customEmbedded.spec.js +0 -44
  41. package/test/security/convos/withscriptingmemoryfunction.convo.txt +0 -5
@@ -36,7 +36,13 @@ describe('logichooks.hookfromsrc', function () {
36
36
  [Capabilities.ASSERTERS]: [{
37
37
  ref: 'CUSTOMASSERTER',
38
38
  src: {
39
- assertConvoStep: 'if (botMsg.messageText === "Hello") result=Promise.resolve(); else result=Promise.reject(new Error("expected Hello"))'
39
+ assertConvoStep: ({ botMsg }) => {
40
+ if (botMsg.messageText === 'Hello') {
41
+ return Promise.resolve()
42
+ } else {
43
+ return Promise.reject(new Error('expected Hello'))
44
+ }
45
+ }
40
46
  }
41
47
  }]
42
48
  })
@@ -48,7 +54,10 @@ describe('logichooks.hookfromsrc', function () {
48
54
  [Capabilities.ASSERTERS]: [{
49
55
  ref: 'CUSTOMASSERTER',
50
56
  src: {
51
- assertConvoStep: 'if (botMsg.messageText === "Hello1") module.exports=Promise.resolve(); else module.exports=Promise.reject(new Error("expected Hello1"))'
57
+ assertConvoStep: ({ botMsg }) => {
58
+ if (botMsg.messageText === 'Hello1') return Promise.resolve()
59
+ else return Promise.reject(new Error('expected Hello1'))
60
+ }
52
61
  }
53
62
  }]
54
63
  })
@@ -74,7 +83,8 @@ describe('logichooks.hookfromsrc', function () {
74
83
  await compiler.convos[0].Run(container)
75
84
  assert.fail('it should have failed')
76
85
  } catch (err) {
77
- assert.isTrue(err.message.includes('Line 6: assertion error - Script assertConvoStep is not valid'))
86
+ console.log(err.message)
87
+ assert.isTrue(err.message.includes('Line 6: assertion error - Script assertConvoStep is not valid - only functions accepted'))
78
88
  }
79
89
  })
80
90
  })
@@ -27,7 +27,7 @@ describe('plugins.plugins', function () {
27
27
  })
28
28
 
29
29
  describe('load', function () {
30
- it('should map simple function to class', async function () {
30
+ it('should map simple function from module to class', async function () {
31
31
  const myCaps = {
32
32
  [Capabilities.PROJECTNAME]: 'plugins.load',
33
33
  [Capabilities.CONTAINERMODE]: 'fromfile1'
@@ -39,7 +39,20 @@ describe('plugins.plugins', function () {
39
39
  const response = await container.WaitBotSays()
40
40
  assert.equal(response.messageText, 'TEST')
41
41
  })
42
- it('should use UserSays function as class', async function () {
42
+ it('should map simple function from file to class', async function () {
43
+ const myCaps = {
44
+ [Capabilities.PROJECTNAME]: 'plugins.load',
45
+ [Capabilities.SAFEDIR]: './test/plugins/plugindir',
46
+ [Capabilities.CONTAINERMODE]: 'fromfile/botium-connector-fromfile1.js'
47
+ }
48
+ const driver = new BotDriver(myCaps)
49
+ const container = await driver.Build()
50
+
51
+ await container.UserSays({ messageText: 'TEST' })
52
+ const response = await container.WaitBotSays()
53
+ assert.equal(response.messageText, 'TEST')
54
+ })
55
+ it('should use UserSays function from module as class', async function () {
43
56
  const myCaps = {
44
57
  [Capabilities.PROJECTNAME]: 'plugins.load',
45
58
  [Capabilities.CONTAINERMODE]: 'fromfile2',
@@ -48,6 +61,20 @@ describe('plugins.plugins', function () {
48
61
  const driver = new BotDriver(myCaps)
49
62
  const container = await driver.Build()
50
63
 
64
+ await container.UserSays({ messageText: 'TEST' })
65
+ const response = await container.WaitBotSays()
66
+ assert.equal(response.messageText, 'MYPREFIX:TEST')
67
+ })
68
+ it('should use UserSays function from file as class', async function () {
69
+ const myCaps = {
70
+ [Capabilities.PROJECTNAME]: 'plugins.load',
71
+ [Capabilities.SAFEDIR]: './test/plugins/plugindir',
72
+ [Capabilities.CONTAINERMODE]: 'fromfile/botium-connector-fromfile2.js',
73
+ cap1: 'MYPREFIX'
74
+ }
75
+ const driver = new BotDriver(myCaps)
76
+ const container = await driver.Build()
77
+
51
78
  await container.UserSays({ messageText: 'TEST' })
52
79
  const response = await container.WaitBotSays()
53
80
  assert.equal(response.messageText, 'MYPREFIX:TEST')
@@ -4,17 +4,17 @@ custom embedded
4
4
  hello
5
5
 
6
6
  #bot
7
- hello should not assert
8
- CONDITIONAL_STEP_LOGIC_HOOK { "skip":true }|G1
7
+ hello
8
+ CONDITIONAL_STEP_LOGIC_HOOK { "skip":false }|G1
9
9
 
10
10
  #bot
11
11
  hello should not assert
12
- CONDITIONAL_STEP_LOGIC_HOOK { "skip":true }|G1
12
+ CONDITIONAL_STEP_LOGIC_HOOK { "skip":false }|G1
13
13
 
14
14
  #bot
15
- hello should not assert
16
- CONDITIONAL_STEP_LOGIC_HOOK { "skip":true }|G2
15
+ hello
16
+ CONDITIONAL_STEP_LOGIC_HOOK { "skip":false }|G2
17
17
 
18
18
  #bot
19
19
  hello should not assert
20
- CONDITIONAL_STEP_LOGIC_HOOK { "skip":true }|G2
20
+ CONDITIONAL_STEP_LOGIC_HOOK { "skip":false }|G2
@@ -0,0 +1,20 @@
1
+ custom embedded
2
+
3
+ #me
4
+ hello
5
+
6
+ #bot
7
+ hello should not assert
8
+ CONDITIONAL_STEP_LOGIC_HOOK { "skip":true }|G1
9
+
10
+ #bot
11
+ hello
12
+ CONDITIONAL_STEP_LOGIC_HOOK { "skip":false }|G1
13
+
14
+ #bot
15
+ hello should not assert
16
+ CONDITIONAL_STEP_LOGIC_HOOK { "skip":true }|G2
17
+
18
+ #bot
19
+ hello should not assert
20
+ CONDITIONAL_STEP_LOGIC_HOOK { "skip":true }|G2
@@ -0,0 +1,20 @@
1
+ custom embedded
2
+
3
+ #me
4
+ hello
5
+
6
+ #bot
7
+ ?hello
8
+ CONDITIONAL_STEP_LOGIC_HOOK { "skip":false }|G1
9
+
10
+ #bot
11
+ ?hello should not assert
12
+ CONDITIONAL_STEP_LOGIC_HOOK { "skip":false }|G1
13
+
14
+ #bot
15
+ ?hello 2
16
+ CONDITIONAL_STEP_LOGIC_HOOK { "skip":false }|G2
17
+
18
+ #bot
19
+ ?hello should not assert
20
+ CONDITIONAL_STEP_LOGIC_HOOK { "skip":true }|G2
@@ -101,5 +101,21 @@ describe('convo with custom conditional logichook', function () {
101
101
  const transript = await this.compiler.convos[0].Run(this.container)
102
102
  assert.equal(transript.steps.length, 3)
103
103
  })
104
+
105
+ it('should fail mandatory condition group if no condition met', async function () {
106
+ try {
107
+ this.compiler.ReadScript(path.resolve(__dirname, 'convos'), 'conditional_steps_multiple_mandatory_condition_groups.convo.txt')
108
+ await this.compiler.convos[0].Run(this.container)
109
+ assert.fail('it should have failed')
110
+ } catch (e) {
111
+ assert.equal(e.message, 'custom embedded/Line 18: Non of the conditions are met in \'G2\' condition group')
112
+ }
113
+ })
114
+
115
+ it('should not fail optional condition group if no condition met', async function () {
116
+ this.compiler.ReadScript(path.resolve(__dirname, 'convos'), 'conditional_steps_multiple_optional_condition_groups.convo.txt')
117
+ const transript = await this.compiler.convos[0].Run(this.container)
118
+ assert.equal(transript.steps.length, 2)
119
+ })
104
120
  })
105
121
  })
@@ -5,7 +5,6 @@ chai.use(chaiAsPromised)
5
5
  const assert = chai.assert
6
6
  const BotDriver = require('../../').BotDriver
7
7
  const Capabilities = require('../../').Capabilities
8
- const { BotiumError } = require('../../src/scripting/BotiumError')
9
8
  const HookUtils = require('../../src/helpers/HookUtils')
10
9
 
11
10
  const myCapsSimpleRest = {
@@ -17,21 +16,6 @@ const myCapsSimpleRest = {
17
16
  [Capabilities.SIMPLEREST_RESPONSE_JSONPATH]: ['$']
18
17
  }
19
18
 
20
- const echoConnector = ({ queueBotSays }) => {
21
- return {
22
- UserSays (msg) {
23
- const botMsg = { sender: 'bot', sourceData: msg.sourceData, messageText: `You said: "${msg.messageText}"` }
24
- queueBotSays(botMsg)
25
- }
26
- }
27
- }
28
-
29
- const myCapsEcho = {
30
- [Capabilities.CONTAINERMODE]: echoConnector,
31
- [Capabilities.SECURITY_ALLOW_UNSAFE]: false,
32
- [Capabilities.SCRIPTING_ENABLE_MEMORY]: true
33
- }
34
-
35
19
  const _getSimpleRestCaps = (caps) => {
36
20
  return Object.assign(
37
21
  {},
@@ -57,11 +41,6 @@ const functionConnector = ({ queueBotSays }) => {
57
41
 
58
42
  describe('security.allowUnsafe', function () {
59
43
  describe('hook utils', function () {
60
- it('should accept string hook in safe mode', async function () {
61
- HookUtils.getHook({
62
- [Capabilities.SECURITY_ALLOW_UNSAFE]: false
63
- }, '1+1')
64
- })
65
44
  it('should accept javascript hook in safe mode', async function () {
66
45
  HookUtils.getHook({
67
46
  [Capabilities.SECURITY_ALLOW_UNSAFE]: false
@@ -74,20 +53,26 @@ describe('security.allowUnsafe', function () {
74
53
  }, 'test/security/resources/hook-as-file.js')
75
54
  assert.fail('should have failed')
76
55
  } catch (err) {
77
- assert.isTrue(err instanceof BotiumError)
78
- assert.exists(err.context)
79
- assert.equal(err.context.message, 'Security Error. Using unsafe custom hook with require is not allowed')
80
- assert.equal(err.context.source, 'HookUtils.js')
81
- assert.equal(err.context.type, 'security')
82
- assert.equal(err.context.subtype, 'allow unsafe')
83
- assert.exists(err.context.cause)
84
- assert.equal(err.context.cause.hookData, 'test/security/resources/hook-as-file.js')
56
+ console.log(err.message)
57
+ assert.isTrue(err.message.indexOf('invalid') >= 0)
85
58
  }
86
59
  })
87
- it('should accept file hook in unsafe mode', async function () {
60
+ it('should accept file hook from safe dir in unsafe mode', async function () {
88
61
  HookUtils.getHook({
89
- [Capabilities.SECURITY_ALLOW_UNSAFE]: true
90
- }, 'test/security/resources/hook-as-file.js')
62
+ [Capabilities.SECURITY_ALLOW_UNSAFE]: true,
63
+ [Capabilities.SAFEDIR]: 'test/security/'
64
+ }, 'resources/hook-as-file.js')
65
+ })
66
+ it('should not accept file hook from outside safe dir', async function () {
67
+ try {
68
+ HookUtils.getHook({
69
+ [Capabilities.SECURITY_ALLOW_UNSAFE]: true,
70
+ [Capabilities.SAFEDIR]: 'test/security/'
71
+ }, '../hook-as-file.js')
72
+ assert.fail('should have failed')
73
+ } catch (err) {
74
+ assert.isTrue(err.message.indexOf('invalid') >= 0)
75
+ }
91
76
  })
92
77
  it('should accept require hook in unsafe mode', async function () {
93
78
  HookUtils.getHook({
@@ -96,19 +81,6 @@ describe('security.allowUnsafe', function () {
96
81
  })
97
82
  })
98
83
 
99
- describe('scripting memory', function () {
100
- it('should not throw security error for using inline function', async function () {
101
- const driver = new BotDriver(myCapsEcho)
102
- const compiler = driver.BuildCompiler()
103
- const container = await driver.Build()
104
- await container.Start()
105
-
106
- compiler.ReadScript(path.resolve(__dirname, 'convos'), 'withscriptingmemoryfunction.convo.txt')
107
- await compiler.convos[0].Run(container)
108
- await container.Clean()
109
- }).timeout(50000)
110
- })
111
-
112
84
  describe('simple rest, scripting memory', function () {
113
85
  it('should use variables succesful', async function () {
114
86
  const myCaps = _getSimpleRestCaps(
@@ -145,19 +117,6 @@ describe('security.allowUnsafe', function () {
145
117
  })
146
118
 
147
119
  describe('simple rest, hooks', function () {
148
- it('should create and use simplerest with javascript hook', async function () {
149
- const driver = new BotDriver(_getSimpleRestCaps(
150
- {
151
- [Capabilities.SIMPLEREST_REQUEST_HOOK]: '1+1'
152
- }
153
- ))
154
-
155
- const compiler = driver.BuildCompiler()
156
- const container = await driver.Build()
157
- await container.Start()
158
-
159
- compiler.ReadScript(path.resolve(__dirname, 'convos'), 'dummy.convo.txt')
160
- })
161
120
  it('should create and use simplerest with function hooks', async function () {
162
121
  const driver = new BotDriver(_getSimpleRestCaps(
163
122
  {
@@ -173,35 +132,6 @@ describe('security.allowUnsafe', function () {
173
132
  })
174
133
  })
175
134
 
176
- describe('precompilers', function () {
177
- it('should not throw security error for inline script type', async function () {
178
- const driver = new BotDriver(_getSimpleRestCaps(
179
- {
180
- [Capabilities.PRECOMPILERS]: {
181
- NAME: 'SCRIPT',
182
- SCRIPT: '1+1'
183
- }
184
- }
185
- ))
186
-
187
- const compiler = driver.BuildCompiler()
188
- const container = await driver.Build()
189
- const fileName = 'dummy.convo.txt'
190
- compiler.ReadScript(path.resolve(__dirname, 'convos'), fileName)
191
- assert.equal(compiler.convos.length, 1)
192
- await container.Clean()
193
- })
194
- })
195
-
196
- describe('base container, hooks', function () {
197
- it('should not throw security error for using inline hook', async function () {
198
- const driver = new BotDriver(_getSimpleRestCaps(
199
- { [Capabilities.CUSTOMHOOK_ONUSERSAYS]: '1+1' }
200
- ))
201
- await driver.Build()
202
- })
203
- })
204
-
205
135
  describe('logic hook, asserter', function () {
206
136
  it('should load asserter from file', async function () {
207
137
  const driver = new BotDriver(_getSimpleRestCaps(
@@ -216,45 +146,6 @@ describe('security.allowUnsafe', function () {
216
146
 
217
147
  driver.BuildCompiler()
218
148
  })
219
- it('should not throw security error for logic hook with inline src', async function () {
220
- const driver = new BotDriver(_getSimpleRestCaps(
221
- {
222
- [Capabilities.LOGIC_HOOKS]: [
223
- {
224
- ref: 'MY-LOGICHOOK-NAME',
225
- src: {
226
- onMeStart: '1+1'
227
- },
228
- global: false,
229
- args: {
230
- 'my-arg-1': 'something'
231
- }
232
- }
233
- ]
234
- }
235
- ))
236
-
237
- driver.BuildCompiler()
238
- })
239
- it('should not throw security error for global logic hook with inline src', async function () {
240
- const driver = new BotDriver(_getSimpleRestCaps(
241
- {
242
- [Capabilities.LOGIC_HOOKS]: [
243
- {
244
- ref: 'MY-LOGICHOOK-NAME',
245
- src: {
246
- onMeStart: '1+1'
247
- },
248
- global: true,
249
- args: {
250
- 'my-arg-1': 'something'
251
- }
252
- }
253
- ]
254
- }
255
- ))
256
- driver.BuildCompiler()
257
- })
258
149
  })
259
150
 
260
151
  describe('connectors', function () {
@@ -270,10 +161,10 @@ describe('security.allowUnsafe', function () {
270
161
  })
271
162
  await driver.Build()
272
163
  })
273
-
274
- it('should create any connector from file/dir, if its starts with botium-connector prefix', async function () {
164
+ it('should create any connector from safedir', async function () {
275
165
  const driver = new BotDriver({
276
- [Capabilities.CONTAINERMODE]: 'botium-connector-as-file',
166
+ [Capabilities.SAFEDIR]: 'test/security/',
167
+ [Capabilities.CONTAINERMODE]: 'resources/botium-connector-as-file.js',
277
168
  [Capabilities.SECURITY_ALLOW_UNSAFE]: false
278
169
  })
279
170
  await driver.Build()