@hellotext/hellotext 1.8.7 → 2.0.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.
- package/README.md +27 -2
- package/dist/hellotext.js +1 -1
- package/index.d.ts +61 -0
- package/lib/api/businesses.cjs +37 -0
- package/lib/api/businesses.js +3 -9
- package/lib/api/events.cjs +45 -0
- package/lib/api/events.js +8 -14
- package/lib/api/forms.cjs +51 -0
- package/lib/api/forms.js +10 -17
- package/lib/api/index.cjs +51 -0
- package/lib/api/index.js +10 -23
- package/lib/api/response.cjs +76 -0
- package/lib/api/response.js +1 -7
- package/lib/api/submissions.cjs +47 -0
- package/lib/api/submissions.js +9 -17
- package/lib/api/webchat/messages.cjs +70 -0
- package/lib/api/webchat/messages.js +10 -18
- package/lib/api/webchats.cjs +44 -0
- package/lib/api/webchats.js +8 -16
- package/lib/builders/input_builder.cjs +61 -0
- package/lib/builders/input_builder.js +4 -11
- package/lib/builders/logo_builder.cjs +50 -0
- package/lib/builders/logo_builder.js +5 -12
- package/lib/channels/application_channel.cjs +67 -0
- package/lib/channels/application_channel.js +1 -8
- package/lib/channels/{web_chat_channel.js → webchat_channel.cjs} +35 -20
- package/lib/channels/webchat_channel.js +3 -11
- package/lib/controllers/form_controller.cjs +141 -0
- package/lib/controllers/form_controller.js +15 -22
- package/lib/controllers/mixins/usePopover.cjs +59 -0
- package/lib/controllers/mixins/usePopover.js +6 -14
- package/lib/controllers/{web_chat/pagination_controller.js → webchat/emoji_picker_controller.cjs} +74 -29
- package/lib/controllers/webchat/emoji_picker_controller.js +11 -17
- package/lib/controllers/webchat_controller.cjs +433 -0
- package/lib/controllers/webchat_controller.js +49 -51
- package/lib/core/configuration/forms.cjs +49 -0
- package/lib/core/configuration/forms.js +2 -8
- package/lib/core/configuration/{web_chat.js → webchat.cjs} +53 -38
- package/lib/core/configuration/webchat.js +2 -9
- package/lib/core/configuration.cjs +65 -0
- package/lib/core/configuration.js +8 -13
- package/lib/core/event.cjs +71 -0
- package/lib/core/event.js +5 -11
- package/lib/core/index.cjs +20 -0
- package/lib/core/index.js +2 -20
- package/lib/errors/index.cjs +19 -0
- package/lib/errors/index.js +2 -19
- package/lib/errors/invalid_event.cjs +34 -0
- package/lib/errors/invalid_event.js +1 -7
- package/lib/errors/not_initialized_error.cjs +34 -0
- package/lib/errors/not_initialized_error.js +1 -7
- package/lib/hellotext.cjs +153 -0
- package/lib/hellotext.js +19 -27
- package/lib/index.cjs +19 -0
- package/lib/index.js +11 -20
- package/lib/locales/en.cjs +22 -0
- package/lib/locales/en.js +2 -9
- package/lib/locales/es.cjs +22 -0
- package/lib/locales/es.js +2 -9
- package/lib/locales/index.cjs +14 -0
- package/lib/locales/index.js +6 -14
- package/lib/models/business.cjs +62 -0
- package/lib/models/business.js +22 -24
- package/lib/models/cookies.cjs +40 -0
- package/lib/models/cookies.js +3 -10
- package/lib/models/form.cjs +166 -0
- package/lib/models/form.js +10 -17
- package/lib/models/form_collection.cjs +122 -0
- package/lib/models/form_collection.js +18 -22
- package/lib/models/index.cjs +54 -0
- package/lib/models/index.js +7 -54
- package/lib/models/query.cjs +51 -0
- package/lib/models/query.js +3 -9
- package/lib/models/session.cjs +58 -0
- package/lib/models/session.js +12 -17
- package/lib/models/{web_chat.js → webchat.cjs} +14 -22
- package/lib/models/webchat.js +6 -13
- package/lib/vanilla.cjs +13 -0
- package/lib/vanilla.js +1 -13
- package/package.json +41 -7
- package/src/controllers/webchat_controller.js +72 -47
- package/src/hellotext.js +5 -4
- package/src/index.bundle.js +5 -0
- package/src/index.js +1 -3
- package/src/models/business.js +3 -6
- package/src/models/form_collection.js +10 -4
- package/src/models/session.js +4 -3
- package/styles/index.css +22 -30
- package/.babelrc +0 -24
- package/.github/workflows/ci.yml +0 -24
- package/.prettierignore +0 -3
- package/.prettierrc.json +0 -18
- package/MIT-LICENSE +0 -20
- package/__tests__/builders/input_builder_test.js +0 -117
- package/__tests__/core/configuration/forms_test.js +0 -30
- package/__tests__/core/configuration/webchat_test.js +0 -163
- package/__tests__/core/configuration_test.js +0 -28
- package/__tests__/core/event_test.js +0 -56
- package/__tests__/hellotext_test.js +0 -197
- package/__tests__/models/business_test.js +0 -26
- package/__tests__/models/cookies_test.js +0 -25
- package/__tests__/models/form_collection_test.js +0 -103
- package/__tests__/models/form_test.js +0 -131
- package/__tests__/models/query_test.js +0 -97
- package/docs/forms.md +0 -176
- package/docs/tracking.md +0 -203
- package/docs/webchat.md +0 -101
- package/jest.config.js +0 -4
- package/jest.setup.js +0 -16
- package/lib/api/web_chat/messages.js +0 -74
- package/lib/api/web_chats.js +0 -53
- package/webpack.config.js +0 -24
package/.prettierrc.json
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"arrowParens": "avoid",
|
|
3
|
-
"bracketSpacing": true,
|
|
4
|
-
"printWidth": 100,
|
|
5
|
-
"semi": false,
|
|
6
|
-
"singleQuote": true,
|
|
7
|
-
"tabWidth": 2,
|
|
8
|
-
"trailingComma": "all",
|
|
9
|
-
"useTabs": false,
|
|
10
|
-
"overrides": [
|
|
11
|
-
{
|
|
12
|
-
"files": "*.json",
|
|
13
|
-
"options": {
|
|
14
|
-
"printWidth": 200
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
]
|
|
18
|
-
}
|
package/MIT-LICENSE
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
Copyright (c) 2022 HelloText
|
|
2
|
-
|
|
3
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
-
a copy of this software and associated documentation files (the
|
|
5
|
-
"Software"), to deal in the Software without restriction, including
|
|
6
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
-
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
-
the following conditions:
|
|
10
|
-
|
|
11
|
-
The above copyright notice and this permission notice shall be
|
|
12
|
-
included in all copies or substantial portions of the Software.
|
|
13
|
-
|
|
14
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @jest-environment jsdom
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import Hellotext from '../../src/hellotext'
|
|
6
|
-
import { InputBuilder } from '../../src/builders/input_builder'
|
|
7
|
-
|
|
8
|
-
describe('when the input is first_name', () => {
|
|
9
|
-
const data = {
|
|
10
|
-
label: 'First Name',
|
|
11
|
-
type: 'text',
|
|
12
|
-
required: true,
|
|
13
|
-
placeholder: 'Enter your first name',
|
|
14
|
-
kind: 'first_name',
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
it('builds an article element that contains a label and input elements', () => {
|
|
18
|
-
const article = InputBuilder.build(data)
|
|
19
|
-
const label = article.querySelector('label')
|
|
20
|
-
const input = article.querySelector('input')
|
|
21
|
-
|
|
22
|
-
expect(label.innerText).toEqual('First Name')
|
|
23
|
-
expect(label.getAttribute('for')).toEqual('first_name')
|
|
24
|
-
|
|
25
|
-
expect(input.id).toEqual('first_name')
|
|
26
|
-
expect(input.type).toEqual('text')
|
|
27
|
-
expect(input.required).toEqual(true)
|
|
28
|
-
expect(input.placeholder).toEqual('Enter your first name')
|
|
29
|
-
expect(input.name).toEqual('first_name')
|
|
30
|
-
})
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
describe('when the input is last_name', () => {
|
|
34
|
-
const data = {
|
|
35
|
-
label: 'Last Name',
|
|
36
|
-
type: 'text',
|
|
37
|
-
required: false,
|
|
38
|
-
placeholder: 'Enter your last name',
|
|
39
|
-
kind: 'last_name',
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
it('builds an article element that contains a label and input elements', () => {
|
|
43
|
-
const article = InputBuilder.build(data)
|
|
44
|
-
const label = article.querySelector('label')
|
|
45
|
-
const input = article.querySelector('input')
|
|
46
|
-
|
|
47
|
-
expect(label.innerText).toEqual('Last Name')
|
|
48
|
-
expect(label.getAttribute('for')).toEqual('last_name')
|
|
49
|
-
|
|
50
|
-
expect(input.id).toEqual('last_name')
|
|
51
|
-
expect(input.type).toEqual('text')
|
|
52
|
-
expect(input.required).toEqual(false)
|
|
53
|
-
expect(input.placeholder).toEqual('Enter your last name')
|
|
54
|
-
expect(input.name).toEqual('last_name')
|
|
55
|
-
})
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
describe('when the input belongs to a property', () => {
|
|
59
|
-
const data = {
|
|
60
|
-
label: 'Email',
|
|
61
|
-
type: 'email',
|
|
62
|
-
required: true,
|
|
63
|
-
placeholder: 'Enter your email',
|
|
64
|
-
kind: 'email',
|
|
65
|
-
property: 'xybz',
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
it('builds an article element that contains a label and input elements', () => {
|
|
69
|
-
const article = InputBuilder.build(data)
|
|
70
|
-
const label = article.querySelector('label')
|
|
71
|
-
const input = article.querySelector('input')
|
|
72
|
-
|
|
73
|
-
expect(label.innerText).toEqual('Email')
|
|
74
|
-
expect(label.getAttribute('for')).toEqual('email')
|
|
75
|
-
|
|
76
|
-
expect(input.id).toEqual('email')
|
|
77
|
-
expect(input.type).toEqual('email')
|
|
78
|
-
expect(input.required).toEqual(true)
|
|
79
|
-
expect(input.placeholder).toEqual('Enter your email')
|
|
80
|
-
expect(input.name).toEqual('email')
|
|
81
|
-
})
|
|
82
|
-
})
|
|
83
|
-
|
|
84
|
-
describe('when the input is a phone number', () => {
|
|
85
|
-
const data = {
|
|
86
|
-
label: 'Phone',
|
|
87
|
-
type: 'tel',
|
|
88
|
-
required: true,
|
|
89
|
-
placeholder: 'Enter your phone number',
|
|
90
|
-
kind: 'phone',
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
beforeEach(() => {
|
|
94
|
-
Hellotext.business = {
|
|
95
|
-
country: {
|
|
96
|
-
prefix: '598',
|
|
97
|
-
code: 'UY',
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
it('builds an article element that contains a label and input elements', () => {
|
|
103
|
-
const article = InputBuilder.build(data)
|
|
104
|
-
const label = article.querySelector('label')
|
|
105
|
-
const input = article.querySelector('input')
|
|
106
|
-
|
|
107
|
-
expect(label.innerText).toEqual('Phone')
|
|
108
|
-
expect(label.getAttribute('for')).toEqual('phone')
|
|
109
|
-
|
|
110
|
-
expect(input.id).toEqual('phone')
|
|
111
|
-
expect(input.type).toEqual('tel')
|
|
112
|
-
expect(input.required).toEqual(true)
|
|
113
|
-
expect(input.placeholder).toEqual('Enter your phone number')
|
|
114
|
-
expect(input.name).toEqual('phone')
|
|
115
|
-
expect(input.value).toEqual('+598')
|
|
116
|
-
})
|
|
117
|
-
})
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { Forms } from '../../../src/core/configuration/forms'
|
|
2
|
-
|
|
3
|
-
describe('Forms', () => {
|
|
4
|
-
describe('.autoMount', () => {
|
|
5
|
-
it('is true by default', () => {
|
|
6
|
-
expect(Forms.autoMount).toEqual(true)
|
|
7
|
-
})
|
|
8
|
-
|
|
9
|
-
it('can be set to false', () => {
|
|
10
|
-
Forms.autoMount = false
|
|
11
|
-
expect(Forms.autoMount).toEqual(false)
|
|
12
|
-
})
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
describe('.successMessage', () => {
|
|
16
|
-
it('is true by default', () => {
|
|
17
|
-
expect(Forms.successMessage).toEqual(true)
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
it('can be set to false', () => {
|
|
21
|
-
Forms.successMessage = false
|
|
22
|
-
expect(Forms.successMessage).toEqual(false)
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
it('can be set to a string', () => {
|
|
26
|
-
Forms.successMessage = 'Thank you for your submission'
|
|
27
|
-
expect(Forms.successMessage).toEqual('Thank you for your submission')
|
|
28
|
-
})
|
|
29
|
-
})
|
|
30
|
-
})
|
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
import { Webchat } from '../../../src/core/configuration/webchat'
|
|
2
|
-
|
|
3
|
-
describe('Webchat', () => {
|
|
4
|
-
describe('behaviour', () => {
|
|
5
|
-
it('is POPOVER by default', () => {
|
|
6
|
-
expect(Webchat.behaviour).toEqual('popover')
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
it('can be set to modal', () => {
|
|
10
|
-
Webchat.behaviour = 'modal'
|
|
11
|
-
expect(Webchat.behaviour).toEqual('modal')
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
it('throws an exception when an invalid value is supplied', () => {
|
|
15
|
-
expect(() => {
|
|
16
|
-
Webchat.behaviour = 'invalid'
|
|
17
|
-
}).toThrowError('Invalid behaviour value: invalid')
|
|
18
|
-
});
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
describe('container', () => {
|
|
22
|
-
it('is body by default', () => {
|
|
23
|
-
expect(Webchat.container).toEqual('body')
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it('can be set to any other value', () => {
|
|
27
|
-
Webchat.container = 'html'
|
|
28
|
-
expect(Webchat.container).toEqual('html')
|
|
29
|
-
});
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
describe('placement', () => {
|
|
33
|
-
it('is bottom-right by default', () => {
|
|
34
|
-
expect(Webchat.placement).toEqual('bottom-right')
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('can be set to any other value', () => {
|
|
38
|
-
Webchat.placement = 'top-left'
|
|
39
|
-
expect(Webchat.placement).toEqual('top-left')
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('throws an exception when an invalid value is supplied', () => {
|
|
43
|
-
expect(() => {
|
|
44
|
-
Webchat.placement = 'invalid'
|
|
45
|
-
}).toThrowError('Invalid placement value: invalid')
|
|
46
|
-
});
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
describe('classes', () => {
|
|
50
|
-
it('is an empty array by default', () => {
|
|
51
|
-
expect(Webchat.classes).toEqual([])
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
describe('setting value to a String', () => {
|
|
55
|
-
it('can be set to a string value', () => {
|
|
56
|
-
Webchat.classes = 'custom-class'
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it('returns an array of the values', () => {
|
|
60
|
-
Webchat.classes = 'custom-class, another-class'
|
|
61
|
-
expect(Webchat.classes).toEqual(['custom-class', 'another-class'])
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it('can be set to an Array', () => {
|
|
66
|
-
Webchat.classes = ['custom-class']
|
|
67
|
-
expect(Webchat.classes).toEqual(['custom-class'])
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it('throws an exception when an invalid value is supplied', () => {
|
|
71
|
-
expect(() => {
|
|
72
|
-
Webchat.classes = { invalid: 'value' }
|
|
73
|
-
}).toThrowError('classes must be an array or a string')
|
|
74
|
-
});
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
describe('triggerClasses', () => {
|
|
78
|
-
it('is an empty array by default', () => {
|
|
79
|
-
expect(Webchat.triggerClasses).toEqual([undefined])
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
describe('setting value to a String', () => {
|
|
83
|
-
it('can be set to a string value', () => {
|
|
84
|
-
Webchat.triggerClasses = 'custom-class'
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it('returns an array of the values', () => {
|
|
88
|
-
Webchat.triggerClasses = 'custom-class, another-class'
|
|
89
|
-
expect(Webchat.triggerClasses).toEqual(['custom-class', 'another-class'])
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
describe('when setting value to an Array', () => {
|
|
94
|
-
it('can be set', () => {
|
|
95
|
-
Webchat.triggerClasses = ['custom-class']
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
it('returns the value', () => {
|
|
99
|
-
Webchat.triggerClasses = ['custom-class', 'another-class']
|
|
100
|
-
expect(Webchat.triggerClasses).toEqual(['custom-class', 'another-class'])
|
|
101
|
-
});
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
it('throws an exception when an invalid value is supplied', () => {
|
|
105
|
-
expect(() => {
|
|
106
|
-
Webchat.triggerClasses = { invalid: 'value' }
|
|
107
|
-
}).toThrowError('triggerClasses must be an array or a string')
|
|
108
|
-
});
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
describe('styles', () => {
|
|
112
|
-
it('raises an exception when an invalid style is set', () => {
|
|
113
|
-
expect(() => {
|
|
114
|
-
Webchat.style = { fill: 'value' }
|
|
115
|
-
}).toThrowError('Invalid style property: fill')
|
|
116
|
-
})
|
|
117
|
-
describe('primaryColor', () => {
|
|
118
|
-
it('can be set to a hex string', () => {
|
|
119
|
-
Webchat.style = { primaryColor: '#EEEEEE' }
|
|
120
|
-
expect(Webchat.style.primaryColor).toEqual('#EEEEEE')
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
it('can be set to an rgb string', () => {
|
|
124
|
-
Webchat.style = { primaryColor: 'rgb(255, 255, 255)' }
|
|
125
|
-
expect(Webchat.style.primaryColor).toEqual('rgb(255, 255, 255)')
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
it('can be set to an rgba string', () => {
|
|
129
|
-
Webchat.style = { primaryColor: 'rgba(255, 255, 255, 0.5)' }
|
|
130
|
-
expect(Webchat.style.primaryColor).toEqual('rgba(255, 255, 255, 0.5)')
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
it('throws an exception when an invalid value is supplied', () => {
|
|
134
|
-
expect(() => {
|
|
135
|
-
Webchat.style = { primaryColor: 'red' }
|
|
136
|
-
}).toThrowError('Invalid color value: red for primaryColor. Colors must be hex or rgb/a.')
|
|
137
|
-
});
|
|
138
|
-
})
|
|
139
|
-
|
|
140
|
-
describe('secondaryColor', () => {
|
|
141
|
-
it('can be set to a hex string', () => {
|
|
142
|
-
Webchat.style = { secondaryColor: '#EEEEEE' }
|
|
143
|
-
expect(Webchat.style.secondaryColor).toEqual('#EEEEEE')
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
it('can be set to an rgb string', () => {
|
|
147
|
-
Webchat.style = { secondaryColor: 'rgb(255, 255, 255)' }
|
|
148
|
-
expect(Webchat.style.secondaryColor).toEqual('rgb(255, 255, 255)')
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
it('can be set to an rgba string', () => {
|
|
152
|
-
Webchat.style = { secondaryColor: 'rgba(255, 255, 255, 0.5)' }
|
|
153
|
-
expect(Webchat.style.secondaryColor).toEqual('rgba(255, 255, 255, 0.5)')
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
it('throws an exception when an invalid value is supplied', () => {
|
|
157
|
-
expect(() => {
|
|
158
|
-
Webchat.style = { secondaryColor: 'red' }
|
|
159
|
-
}).toThrowError('Invalid color value: red for secondaryColor. Colors must be hex or rgb/a.')
|
|
160
|
-
});
|
|
161
|
-
})
|
|
162
|
-
})
|
|
163
|
-
})
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { Configuration } from '../../src/core'
|
|
2
|
-
|
|
3
|
-
describe('Configuration', () => {
|
|
4
|
-
describe('.autoGenerateSession', () => {
|
|
5
|
-
it('is true by default', () => {
|
|
6
|
-
expect(Configuration.autoGenerateSession).toEqual(true)
|
|
7
|
-
})
|
|
8
|
-
|
|
9
|
-
it('can be set to false', () => {
|
|
10
|
-
Configuration.autoGenerateSession = false
|
|
11
|
-
expect(Configuration.autoGenerateSession).toEqual(false)
|
|
12
|
-
})
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
describe('.forms', () => {
|
|
16
|
-
it('has default values', () => {
|
|
17
|
-
expect(Configuration.forms.autoMount).toEqual(true)
|
|
18
|
-
expect(Configuration.forms.successMessage).toEqual(true)
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it('can be modified', () => {
|
|
22
|
-
Configuration.assign({ forms: { autoMount: false, successMessage: false } })
|
|
23
|
-
|
|
24
|
-
expect(Configuration.forms.autoMount).toEqual(false)
|
|
25
|
-
expect(Configuration.forms.successMessage).toEqual(false)
|
|
26
|
-
})
|
|
27
|
-
})
|
|
28
|
-
})
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import Event from "../../src/core/event"
|
|
2
|
-
|
|
3
|
-
describe(".valid", function () {
|
|
4
|
-
it("is true when event name is a valid defined name", () => {
|
|
5
|
-
expect(Event.valid("session-set")).toEqual(true)
|
|
6
|
-
});
|
|
7
|
-
|
|
8
|
-
it("is false when event name is not defined", () => {
|
|
9
|
-
expect(Event.valid("undefined-event")).toEqual(false)
|
|
10
|
-
});
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
describe(".invalid", () => {
|
|
14
|
-
it("is true when event name is not defined", () => {
|
|
15
|
-
expect(Event.invalid("undefined-event")).toEqual(true)
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
it("is false when event name is a valid defined name", () => {
|
|
19
|
-
expect(Event.invalid("session-set")).toEqual(false)
|
|
20
|
-
});
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
describe("#addSubscriber", function () {
|
|
24
|
-
const instance = new Event()
|
|
25
|
-
|
|
26
|
-
it("adds the callback to the list of subscribers for an event", () => {
|
|
27
|
-
const callback = (session) => {}
|
|
28
|
-
instance.addSubscriber("session-set", callback)
|
|
29
|
-
expect(instance.subscribers["session-set"].length).toEqual(1)
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
describe("#removeSubscriber", function () {
|
|
34
|
-
const instance = new Event()
|
|
35
|
-
|
|
36
|
-
it("removes the callback from the list of subscribers for an event", () => {
|
|
37
|
-
const callback = (session) => {}
|
|
38
|
-
instance.addSubscriber("session-set", callback)
|
|
39
|
-
instance.removeSubscriber("session-set", callback)
|
|
40
|
-
|
|
41
|
-
expect(instance.subscribers["session-set"].length).toEqual(0)
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
describe("#dispatch", () => {
|
|
46
|
-
const instance = new Event()
|
|
47
|
-
|
|
48
|
-
it("notifies the listeners for an event", () => {
|
|
49
|
-
const callback = jest.fn()
|
|
50
|
-
|
|
51
|
-
instance.addSubscriber("session-set", callback)
|
|
52
|
-
instance.dispatch("session-set", "session_payload")
|
|
53
|
-
|
|
54
|
-
expect(callback).toHaveBeenCalledTimes(1)
|
|
55
|
-
});
|
|
56
|
-
});
|
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
import Hellotext from "../src/hellotext";
|
|
2
|
-
import { Business } from "../src/models"
|
|
3
|
-
|
|
4
|
-
const getCookieValue = name => document.cookie.match('(^|;)\\s*' + name + '\\s*=\\s*([^;]+)')?.pop()
|
|
5
|
-
|
|
6
|
-
const expireSession = () => {
|
|
7
|
-
document.cookie = "hello_session=;expires=Thu, 01 Jan 1970 00:00:00 GMT"
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
beforeEach(() => {
|
|
11
|
-
Business.prototype.fetchPublicData = jest.fn().mockResolvedValue({ whitelist: 'disabled' })
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
afterEach(() => {
|
|
15
|
-
jest.clearAllMocks();
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
describe("when trying to call methods before initializing the class", () => {
|
|
19
|
-
it("raises an error when Hellotext.track is called", () => {
|
|
20
|
-
expect(Hellotext.track("page.viewed")).rejects.toThrowError()
|
|
21
|
-
});
|
|
22
|
-
})
|
|
23
|
-
//
|
|
24
|
-
describe("when the class is initialized successfully", () => {
|
|
25
|
-
const business_id = "xy76ks"
|
|
26
|
-
|
|
27
|
-
describe("when hello_session is present in the query params", () => {
|
|
28
|
-
beforeAll(() => {
|
|
29
|
-
const windowMock = {
|
|
30
|
-
location: { search: "?hello_session=session" },
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
jest.spyOn(global, 'window', 'get').mockImplementation(() => windowMock)
|
|
34
|
-
Hellotext.initialize(business_id)
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
it("sets the cookie as value of the query parameter", () => {
|
|
38
|
-
expect(getCookieValue("hello_session")).toEqual("session")
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it("returns the value when Hellotext.session is called", () => {
|
|
42
|
-
expect(Hellotext.session).toEqual("session")
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
describe("when tracking events", () => {
|
|
46
|
-
it("success attribute is true when response from the server is received successfully", async () => {
|
|
47
|
-
global.fetch = jest.fn().mockResolvedValue({
|
|
48
|
-
json: jest.fn().mockResolvedValue({received: "success"}),
|
|
49
|
-
status: 200
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
const response = await Hellotext.track("page.viewed")
|
|
53
|
-
|
|
54
|
-
expect(response.succeeded).toEqual(true)
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it("success attribute is false when response from the server is rejected", async () => {
|
|
58
|
-
global.fetch = jest.fn().mockResolvedValue({
|
|
59
|
-
json: jest.fn().mockResolvedValue({}),
|
|
60
|
-
status: 422
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
const response = await Hellotext.track("page.viewed")
|
|
64
|
-
|
|
65
|
-
expect(response.failed).toEqual(true)
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
describe("when hello_session is not present in the query params", () => {
|
|
71
|
-
const business_id = "xy76ks"
|
|
72
|
-
|
|
73
|
-
beforeAll(() => {
|
|
74
|
-
const windowMock = {location: { search: "" },}
|
|
75
|
-
jest.spyOn(global, 'window', 'get').mockImplementation(() => windowMock)
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
it("mints a new session token and sets the cookie as well", () => {
|
|
79
|
-
global.fetch = jest.fn().mockResolvedValue({
|
|
80
|
-
json: jest.fn().mockResolvedValue({id: "generated_token"}),
|
|
81
|
-
status: 200
|
|
82
|
-
})
|
|
83
|
-
|
|
84
|
-
Hellotext.initialize(business_id)
|
|
85
|
-
|
|
86
|
-
setTimeout(() => {
|
|
87
|
-
expect(getCookieValue("hello_session")).toEqual("generated_token")
|
|
88
|
-
expect(Hellotext.session).toEqual("generated_token")
|
|
89
|
-
}, 1000)
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it("does not mint a new session token when autogenerateSession is set to false", () => {
|
|
93
|
-
Hellotext.initialize(business_id, { autogenerateSession: false })
|
|
94
|
-
|
|
95
|
-
setTimeout(() => {
|
|
96
|
-
expect(getCookieValue("hello_session")).toEqual(undefined)
|
|
97
|
-
expect(Hellotext.session).toEqual(undefined)
|
|
98
|
-
}, 1000)
|
|
99
|
-
})
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
//
|
|
103
|
-
// describe(".isInitialized", () => {
|
|
104
|
-
// describe("when session is set", () => {
|
|
105
|
-
// beforeAll(() => {
|
|
106
|
-
// const windowMock = {location: { search: "?hello_session=session" }}
|
|
107
|
-
// jest.spyOn(global, 'window', 'get').mockImplementation(() => windowMock)
|
|
108
|
-
// Hellotext.initialize("123")
|
|
109
|
-
// })
|
|
110
|
-
//
|
|
111
|
-
// it("is true", () => {
|
|
112
|
-
// expect(Hellotext.isInitialized).toEqual(true)
|
|
113
|
-
// });
|
|
114
|
-
// });
|
|
115
|
-
// });
|
|
116
|
-
//
|
|
117
|
-
// describe(".on", () => {
|
|
118
|
-
// const business_id = "xy76ks"
|
|
119
|
-
//
|
|
120
|
-
// beforeAll(() => {
|
|
121
|
-
// const windowMock = {location: { search: "" },}
|
|
122
|
-
// jest.spyOn(global, 'window', 'get').mockImplementation(() => windowMock)
|
|
123
|
-
// })
|
|
124
|
-
//
|
|
125
|
-
// it("registers a callback that is called when the session is set", function () {
|
|
126
|
-
// global.fetch = jest.fn().mockResolvedValue({
|
|
127
|
-
// json: jest.fn().mockResolvedValue({id: "generated_token"}),
|
|
128
|
-
// status: 200
|
|
129
|
-
// })
|
|
130
|
-
//
|
|
131
|
-
// const callback = jest.fn()
|
|
132
|
-
//
|
|
133
|
-
// Hellotext.on("session-set", callback)
|
|
134
|
-
// Hellotext.initialize(business_id)
|
|
135
|
-
//
|
|
136
|
-
// expect(callback).toHaveBeenCalledTimes(1)
|
|
137
|
-
// });
|
|
138
|
-
//
|
|
139
|
-
// it("throws an error when event is invalid", () => {
|
|
140
|
-
// expect(
|
|
141
|
-
// () => Hellotext.on("undefined-event", () => {})
|
|
142
|
-
// ).toThrowError()
|
|
143
|
-
// });
|
|
144
|
-
// });
|
|
145
|
-
//
|
|
146
|
-
// describe("when session is stored in the cookie", function () {
|
|
147
|
-
// beforeAll(() => {
|
|
148
|
-
// document.cookie = `hello_session=12345`
|
|
149
|
-
// Hellotext.initialize(123)
|
|
150
|
-
// })
|
|
151
|
-
//
|
|
152
|
-
// it("Assigns session from cookie", function () {
|
|
153
|
-
// expect(Hellotext.session).toEqual("12345")
|
|
154
|
-
// });
|
|
155
|
-
// });
|
|
156
|
-
//
|
|
157
|
-
//
|
|
158
|
-
// describe(".removeEventListener", () => {
|
|
159
|
-
// beforeAll(() => {
|
|
160
|
-
// const windowMock = {location: { search: "?hello_session=123" },}
|
|
161
|
-
// jest.spyOn(global, 'window', 'get').mockImplementation(() => windowMock)
|
|
162
|
-
//
|
|
163
|
-
// Hellotext.initialize(123)
|
|
164
|
-
// })
|
|
165
|
-
//
|
|
166
|
-
// it("throws an error when event is invalid", () => {
|
|
167
|
-
// expect(
|
|
168
|
-
// () => Hellotext.removeEventListener("undefined-event", () => {})
|
|
169
|
-
// ).toThrowError()
|
|
170
|
-
// });
|
|
171
|
-
//
|
|
172
|
-
// it("removes the callback from the subscribers and will not be notified again", () => {
|
|
173
|
-
// const callback = jest.fn()
|
|
174
|
-
//
|
|
175
|
-
// Hellotext.on("session-set", callback)
|
|
176
|
-
// Hellotext.removeEventListener("session-set", callback)
|
|
177
|
-
//
|
|
178
|
-
// expect(callback).toHaveBeenCalledTimes(0)
|
|
179
|
-
// });
|
|
180
|
-
// })
|
|
181
|
-
//
|
|
182
|
-
// describe("when hello_preview query parameter is present", () => {
|
|
183
|
-
// beforeAll(() => {
|
|
184
|
-
// const windowMock = {location: { search: "?hello_preview" },}
|
|
185
|
-
// jest.spyOn(global, 'window', 'get').mockImplementation(() => windowMock)
|
|
186
|
-
//
|
|
187
|
-
// expireSession()
|
|
188
|
-
// Hellotext.initialize(123)
|
|
189
|
-
// })
|
|
190
|
-
//
|
|
191
|
-
// describe(".track", () => {
|
|
192
|
-
// it("returns a success response without interacting with the API", async () => {
|
|
193
|
-
// const response = await Hellotext.track("page.viewed")
|
|
194
|
-
// expect(response.succeeded).toEqual(true)
|
|
195
|
-
// });
|
|
196
|
-
// })
|
|
197
|
-
// })
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @jest-environment jsdom
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import { Business } from '../../src/models'
|
|
7
|
-
|
|
8
|
-
describe('enabledWhitelist', () => {
|
|
9
|
-
beforeEach(() => {
|
|
10
|
-
global.fetch = jest.fn().mockResolvedValue({ json: jest.fn().mockResolvedValue({}) })
|
|
11
|
-
})
|
|
12
|
-
|
|
13
|
-
it('is true when the whitelist is an array', () => {
|
|
14
|
-
const business = new Business('123')
|
|
15
|
-
business.data = { whitelist: ['www.example.com'] }
|
|
16
|
-
|
|
17
|
-
expect(business.enabledWhitelist).toEqual(true)
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
it('is false when the whitelist is a string', () => {
|
|
21
|
-
const business = new Business('123')
|
|
22
|
-
business.data = { whitelist: 'disabled' }
|
|
23
|
-
|
|
24
|
-
expect(business.enabledWhitelist).toEqual(false)
|
|
25
|
-
})
|
|
26
|
-
})
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @jest-environment jsdom
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { Cookies } from '../../src/models'
|
|
6
|
-
|
|
7
|
-
beforeEach(() => {
|
|
8
|
-
document.cookie = ''
|
|
9
|
-
})
|
|
10
|
-
|
|
11
|
-
describe('set', () => {
|
|
12
|
-
it('sets the value of a cookie', () => {
|
|
13
|
-
expect(Cookies.get('hello_session')).toEqual(undefined)
|
|
14
|
-
|
|
15
|
-
Cookies.set('hello_session', 'session')
|
|
16
|
-
expect(Cookies.get('hello_session')).toEqual('session')
|
|
17
|
-
})
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
describe('get', () => {
|
|
21
|
-
it('gets the value of a cookie', () => {
|
|
22
|
-
document.cookie = 'hello_session=session'
|
|
23
|
-
expect(Cookies.get('hello_session')).toEqual('session')
|
|
24
|
-
})
|
|
25
|
-
})
|