@hellotext/hellotext 1.8.3 → 1.8.5

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 (51) hide show
  1. package/__tests__/core/configuration/webchat_test.js +163 -0
  2. package/__tests__/hellotext_test.js +97 -101
  3. package/dist/hellotext.js +1 -1
  4. package/docs/webchat.md +101 -0
  5. package/jest.config.js +1 -0
  6. package/jest.setup.js +9 -0
  7. package/lib/api/index.js +6 -0
  8. package/lib/api/web_chat/messages.js +74 -0
  9. package/lib/api/web_chats.js +53 -0
  10. package/lib/api/webchat/messages.js +85 -0
  11. package/lib/api/webchats.js +53 -0
  12. package/lib/builders/logo_builder.js +2 -1
  13. package/lib/channels/application_channel.js +68 -0
  14. package/lib/channels/web_chat_channel.js +97 -0
  15. package/lib/channels/webchat_channel.js +112 -0
  16. package/lib/controllers/mixins/usePopover.js +61 -0
  17. package/lib/controllers/web_chat/pagination_controller.js +81 -0
  18. package/lib/controllers/webchat/emoji_picker_controller.js +134 -0
  19. package/lib/controllers/webchat_controller.js +446 -0
  20. package/lib/core/configuration/web_chat.js +168 -0
  21. package/lib/core/configuration/webchat.js +185 -0
  22. package/lib/core/configuration.js +6 -1
  23. package/lib/core/event.js +1 -1
  24. package/lib/hellotext.js +18 -9
  25. package/lib/index.js +4 -0
  26. package/lib/models/business.js +9 -1
  27. package/lib/models/index.js +7 -0
  28. package/lib/models/session.js +2 -0
  29. package/lib/models/web_chat.js +51 -0
  30. package/lib/models/webchat.js +51 -0
  31. package/package.json +8 -7
  32. package/src/api/index.js +5 -0
  33. package/src/api/webchat/messages.js +55 -0
  34. package/src/api/webchats.js +30 -0
  35. package/src/builders/logo_builder.js +8 -4
  36. package/src/channels/application_channel.js +45 -0
  37. package/src/channels/webchat_channel.js +77 -0
  38. package/src/controllers/mixins/usePopover.js +50 -0
  39. package/src/controllers/webchat/emoji_picker_controller.js +82 -0
  40. package/src/controllers/webchat_controller.js +448 -0
  41. package/src/core/configuration/webchat.js +176 -0
  42. package/src/core/configuration.js +5 -0
  43. package/src/core/event.js +10 -1
  44. package/src/hellotext.js +7 -2
  45. package/src/index.js +5 -0
  46. package/src/models/business.js +11 -1
  47. package/src/models/index.js +1 -0
  48. package/src/models/session.js +7 -5
  49. package/src/models/webchat.js +28 -0
  50. package/styles/index.css +4 -0
  51. package/webpack.config.js +1 -1
@@ -0,0 +1,163 @@
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,7 +1,3 @@
1
- /**
2
- * @jest-environment jsdom
3
- */
4
-
5
1
  import Hellotext from "../src/hellotext";
6
2
  import { Business } from "../src/models"
7
3
 
@@ -24,7 +20,7 @@ describe("when trying to call methods before initializing the class", () => {
24
20
  expect(Hellotext.track("page.viewed")).rejects.toThrowError()
25
21
  });
26
22
  })
27
-
23
+ //
28
24
  describe("when the class is initialized successfully", () => {
29
25
  const business_id = "xy76ks"
30
26
 
@@ -103,99 +99,99 @@ describe("when the class is initialized successfully", () => {
103
99
  })
104
100
  });
105
101
  });
106
-
107
- describe(".isInitialized", () => {
108
- describe("when session is set", () => {
109
- beforeAll(() => {
110
- const windowMock = {location: { search: "?hello_session=session" }}
111
- jest.spyOn(global, 'window', 'get').mockImplementation(() => windowMock)
112
- Hellotext.initialize("123")
113
- })
114
-
115
- it("is true", () => {
116
- expect(Hellotext.isInitialized).toEqual(true)
117
- });
118
- });
119
- });
120
-
121
- describe(".on", () => {
122
- const business_id = "xy76ks"
123
-
124
- beforeAll(() => {
125
- const windowMock = {location: { search: "" },}
126
- jest.spyOn(global, 'window', 'get').mockImplementation(() => windowMock)
127
- })
128
-
129
- it("registers a callback that is called when the session is set", function () {
130
- global.fetch = jest.fn().mockResolvedValue({
131
- json: jest.fn().mockResolvedValue({id: "generated_token"}),
132
- status: 200
133
- })
134
-
135
- const callback = jest.fn()
136
-
137
- Hellotext.on("session-set", callback)
138
- Hellotext.initialize(business_id)
139
-
140
- expect(callback).toHaveBeenCalledTimes(1)
141
- });
142
-
143
- it("throws an error when event is invalid", () => {
144
- expect(
145
- () => Hellotext.on("undefined-event", () => {})
146
- ).toThrowError()
147
- });
148
- });
149
-
150
- describe("when session is stored in the cookie", function () {
151
- beforeAll(() => {
152
- document.cookie = `hello_session=12345`
153
- Hellotext.initialize(123)
154
- })
155
-
156
- it("Assigns session from cookie", function () {
157
- expect(Hellotext.session).toEqual("12345")
158
- });
159
- });
160
-
161
-
162
- describe(".removeEventListener", () => {
163
- beforeAll(() => {
164
- const windowMock = {location: { search: "?hello_session=123" },}
165
- jest.spyOn(global, 'window', 'get').mockImplementation(() => windowMock)
166
-
167
- Hellotext.initialize(123)
168
- })
169
-
170
- it("throws an error when event is invalid", () => {
171
- expect(
172
- () => Hellotext.removeEventListener("undefined-event", () => {})
173
- ).toThrowError()
174
- });
175
-
176
- it("removes the callback from the subscribers and will not be notified again", () => {
177
- const callback = jest.fn()
178
-
179
- Hellotext.on("session-set", callback)
180
- Hellotext.removeEventListener("session-set", callback)
181
-
182
- expect(callback).toHaveBeenCalledTimes(0)
183
- });
184
- })
185
-
186
- describe("when hello_preview query parameter is present", () => {
187
- beforeAll(() => {
188
- const windowMock = {location: { search: "?hello_preview" },}
189
- jest.spyOn(global, 'window', 'get').mockImplementation(() => windowMock)
190
-
191
- expireSession()
192
- Hellotext.initialize(123)
193
- })
194
-
195
- describe(".track", () => {
196
- it("returns a success response without interacting with the API", async () => {
197
- const response = await Hellotext.track("page.viewed")
198
- expect(response.succeeded).toEqual(true)
199
- });
200
- })
201
- })
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
+ // })