@capillarytech/creatives-library 8.0.206-alpha.0 → 8.0.206

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.
@@ -1,188 +0,0 @@
1
- import React, { useMemo } from 'react';
2
- import PropTypes from 'prop-types';
3
- import emailIllustration from '../Assets/images/emailIllustration.svg';
4
- import smsIllustration from '../Assets/images/smsIllustration.svg';
5
- import pushIllustration from '../Assets/images/pushIllustration.svg';
6
- import viberIllustration from '../Assets/images/viberIllustration.svg';
7
- import lineIllustration from '../Assets/images/lineIllustration.svg';
8
- import facebookIllustration from '../Assets/images/facebookIllustration.svg';
9
- import whatsappIllustration from '../Assets/images/whatsappIllustration.png';
10
- import whatsappOrZaloAccountIllustration from '../Assets/images/whatsappOrZaloAccountIllustration.svg';
11
- import rcsIllustration from '../Assets/images/rcsIllustration.png';
12
- import zaloillustration from '@capillarytech/cap-ui-library/assets/images/featureUiNotEnabledIllustration.svg';
13
- import inAppIllustration from '@capillarytech/cap-ui-library/assets/images/featureUiNotEnabledIllustration.svg';
14
- import messages from './messages';
15
- import { FormattedMessage } from 'react-intl';
16
- import { CapIllustration } from "@capillarytech/cap-ui-library";
17
- import { MOBILE_PUSH, SMS, EMAIL, LINE, VIBER, FACEBOOK, WHATSAPP, RCS, ZALO, INAPP } from '../CreativesContainer/constants';
18
-
19
-
20
- // Configuration object for channel types
21
- const CHANNEL_CONFIG = {
22
- [SMS]: {
23
- illustrationImage: smsIllustration,
24
- buttonMessage: messages.newSMSTemplate,
25
- titleMessage: messages.smsTitleIllustartion,
26
- hasButton: true,
27
- },
28
- [EMAIL]: {
29
- illustrationImage: emailIllustration,
30
- buttonMessage: messages.newEmailTemplate,
31
- titleMessage: messages.emailTitleIllustartion,
32
- hasButton: true,
33
- },
34
- [MOBILE_PUSH]: {
35
- illustrationImage: pushIllustration,
36
- buttonMessage: messages.newNotificationTemplate,
37
- titleMessage: messages.pushTitleIllustartion,
38
- hasButton: true,
39
- },
40
- [VIBER]: {
41
- illustrationImage: viberIllustration,
42
- buttonMessage: messages.newViberTemplate,
43
- titleMessage: messages.viberTitleIllustartion,
44
- hasButton: true,
45
- },
46
- [LINE]: {
47
- illustrationImage: lineIllustration,
48
- buttonMessage: messages.newLineTemplate,
49
- titleMessage: messages.lineTitleIllustartion,
50
- hasButton: true,
51
- },
52
- [FACEBOOK]: {
53
- illustrationImage: facebookIllustration,
54
- buttonMessage: messages.newFacebookTemplate,
55
- titleMessage: messages.facebookTitleIllustartion,
56
- hasButton: true,
57
- },
58
- [RCS]: {
59
- illustrationImage: rcsIllustration,
60
- buttonMessage: messages.newRCSTemplate,
61
- titleMessage: messages.rcsTitleIllustartion,
62
- descriptionMessage: messages.rcsDescIllustartion,
63
- descriptionPosition: 'bottom',
64
- descriptionClassName: 'illustration-desc rcs-illustration',
65
- hasButton: true,
66
- },
67
- [INAPP]: {
68
- illustrationImage: inAppIllustration,
69
- titleMessage: messages.inAppTitleIllustration,
70
- descriptionMessage: messages.inAppDescIllustration,
71
- descriptionPosition: 'bottom',
72
- descriptionClassName: 'illustration-desc inapp-illustration',
73
- buttonClassName: 'inapp-illustration-button',
74
- hasButton: false,
75
- },
76
- };
77
-
78
- function ChannelTypeIllustration(props) {
79
- const {
80
- isFullMode,
81
- createTemplate,
82
- currentChannel,
83
- hostName
84
- } = props;
85
-
86
- const templateText = useMemo(() => {
87
- const templateIntlMsg = <FormattedMessage {...messages.template} />;
88
- return isFullMode ? templateIntlMsg : '';
89
- }, [isFullMode]);
90
-
91
- const getChannelTypeIllustrationInfo = (type, hostName) => {
92
- // Handle special cases with hostName dependency
93
- if (type === WHATSAPP) {
94
- if (!hostName) {
95
- return {
96
- illustrationImage: whatsappOrZaloAccountIllustration,
97
- title: <FormattedMessage {...messages.whatsappAccountNotConfiguredTitle} />,
98
- description: <FormattedMessage {...messages.accountNotConfiguredDescription} />,
99
- descriptionPosition: 'bottom',
100
- descriptionClassName: 'illustration-desc zalo-illustration',
101
- buttonClassName: 'zalo-illustration-button',
102
- };
103
- }
104
- return {
105
- buttonLabel: <FormattedMessage {...messages.newWhatsappTemplate} values={{ template: templateText }} />,
106
- onClick: createTemplate,
107
- illustrationImage: whatsappIllustration,
108
- title: <FormattedMessage {...messages.whatsappTitleIllustration} values={{ template: templateText }} />,
109
- description: <FormattedMessage {...messages.whatsappDescIllustration} />,
110
- descriptionPosition: 'bottom',
111
- descriptionClassName: 'illustration-desc',
112
- };
113
- }
114
-
115
- if (type === ZALO) {
116
- if (!hostName) {
117
- return {
118
- illustrationImage: whatsappOrZaloAccountIllustration,
119
- title: <FormattedMessage {...messages.zaloAccountNotConfiguredTitle} />,
120
- description: <FormattedMessage {...messages.accountNotConfiguredDescription} />,
121
- descriptionPosition: 'bottom',
122
- descriptionClassName: 'illustration-desc zalo-illustration',
123
- buttonClassName: 'zalo-illustration-button',
124
- };
125
- }
126
- return {
127
- illustrationImage: zaloillustration,
128
- title: <FormattedMessage {...messages.zaloTitleIllustration} />,
129
- description: <FormattedMessage {...messages.zaloDescIllustration} />,
130
- descriptionPosition: 'bottom',
131
- descriptionClassName: 'illustration-desc zalo-illustration',
132
- buttonClassName: 'zalo-illustration-button',
133
- };
134
- }
135
-
136
- // Handle standard channels using configuration
137
- const config = CHANNEL_CONFIG[type];
138
- if (!config) {
139
- return {
140
- illustrationImage: emailIllustration,
141
- title: '',
142
- description: '',
143
- descriptionPosition: 'bottom',
144
- descriptionClassName: 'illustration-desc unknown-illustration',
145
- buttonClassName: 'unknown-illustration-button',
146
- buttonLabel: <FormattedMessage {...messages.createNewActionButton} />,
147
- }; //send default illustration here
148
- }
149
-
150
- const result = {
151
- illustrationImage: config.illustrationImage,
152
- title: <FormattedMessage {...config.titleMessage} values={{ template: templateText }} />,
153
- };
154
-
155
- if (config.hasButton) {
156
- result.buttonLabel = <FormattedMessage {...config.buttonMessage} values={{ template: templateText }} />;
157
- result.onClick = createTemplate;
158
- }
159
-
160
- if (config.descriptionMessage) {
161
- result.description = <FormattedMessage {...config.descriptionMessage} />;
162
- result.descriptionPosition = config.descriptionPosition;
163
- result.descriptionClassName = config.descriptionClassName;
164
- }
165
-
166
- if (config.buttonClassName) {
167
- result.buttonClassName = config.buttonClassName;
168
- }
169
-
170
- return result;
171
- };
172
-
173
- const channelLowerCase = currentChannel?.toLowerCase() || '';
174
-
175
- return (
176
- <CapIllustration
177
- buttonClassName={`create-new-${channelLowerCase}`}
178
- {...getChannelTypeIllustrationInfo(currentChannel, hostName)}
179
- />
180
- );
181
- }
182
- ChannelTypeIllustration.propTypes = {
183
- isFullMode: PropTypes.bool,
184
- createTemplate: PropTypes.func.isRequired,
185
- currentChannel: PropTypes.string,
186
- hostName: PropTypes.string,
187
- };
188
- export default ChannelTypeIllustration;
@@ -1,323 +0,0 @@
1
- // Mock the CapIllustration component
2
- jest.mock('@capillarytech/cap-ui-library', () => ({
3
- CapIllustration: ({ children, ...props }) => <div data-testid="cap-illustration" {...props}>{children}</div>
4
- }));
5
-
6
- // Mock all image imports
7
- jest.mock('../../Assets/images/emailIllustration.svg', () => 'test-file-stub');
8
- jest.mock('../../Assets/images/smsIllustration.svg', () => 'test-file-stub');
9
- jest.mock('../../Assets/images/pushIllustration.svg', () => 'test-file-stub');
10
- jest.mock('../../Assets/images/whatsappIllustration.png', () => 'test-file-stub');
11
- jest.mock('../../Assets/images/whatsappOrZaloAccountIllustration.svg', () => 'test-file-stub');
12
- jest.mock('../../Assets/images/rcsIllustration.png', () => 'test-file-stub');
13
- jest.mock('@capillarytech/cap-ui-library/assets/images/featureUiNotEnabledIllustration.svg', () => 'test-file-stub');
14
-
15
-
16
- import React from 'react';
17
- import { shallow, configure } from 'enzyme';
18
- import Adapter from '@cfaester/enzyme-adapter-react-18';
19
- import ChannelTypeIllustration from '../ChannelTypeIllustration';
20
- import { MOBILE_PUSH, SMS, EMAIL, LINE, VIBER, FACEBOOK, WHATSAPP, RCS, ZALO, INAPP } from '../../CreativesContainer/constants';
21
-
22
- configure({ adapter: new Adapter() });
23
-
24
- describe('ChannelTypeIllustration', () => {
25
- const mockCreateTemplate = jest.fn();
26
- const mockIntl = {
27
- formatMessage: jest.fn(() => 'some text')
28
- };
29
-
30
- beforeEach(() => {
31
- jest.clearAllMocks();
32
- mockIntl.formatMessage.mockClear();
33
- });
34
-
35
- const defaultProps = {
36
- isFullMode: false,
37
- intl: mockIntl,
38
- createTemplate: mockCreateTemplate,
39
- currentChannel: SMS,
40
- hostName: false
41
- };
42
-
43
- beforeEach(() => {
44
- jest.clearAllMocks();
45
- mockIntl.formatMessage.mockClear();
46
- });
47
-
48
- const renderComponent = (props = {}) => {
49
- return shallow(
50
- <ChannelTypeIllustration {...defaultProps} {...props} intl={mockIntl} />
51
- );
52
- };
53
-
54
- describe('Component Rendering', () => {
55
- it('should render CapIllustration component', () => {
56
- const component = renderComponent();
57
- expect(component.find('CapIllustration')).toHaveLength(1);
58
- });
59
-
60
- it('should pass correct buttonClassName based on currentChannel', () => {
61
- const component = renderComponent({ currentChannel: 'SMS' });
62
- const capIllustration = component.find('CapIllustration');
63
- expect(capIllustration.prop('buttonClassName')).toBe('create-new-sms');
64
- });
65
-
66
- it('should handle undefined currentChannel gracefully', () => {
67
- const component = renderComponent({ currentChannel: undefined });
68
- const capIllustration = component.find('CapIllustration');
69
- expect(capIllustration.prop('buttonClassName')).toBe('unknown-illustration-button');
70
- });
71
- });
72
-
73
- describe('SMS Channel', () => {
74
- it('should return correct illustration info for SMS channel', () => {
75
- const component = renderComponent({ currentChannel: SMS });
76
- const capIllustration = component.find('CapIllustration');
77
-
78
- expect(capIllustration.prop('illustrationImage')).toBe('test-file-stub');
79
- expect(capIllustration.prop('onClick')).toBe(mockCreateTemplate);
80
- expect(capIllustration.prop('buttonLabel')).toBeDefined();
81
- expect(capIllustration.prop('title')).toBeDefined();
82
- });
83
-
84
- it('should include template text in full mode for SMS', () => {
85
- const component = renderComponent({
86
- currentChannel: SMS,
87
- isFullMode: true
88
- });
89
- const capIllustration = component.find('CapIllustration');
90
- expect(capIllustration.prop('buttonLabel')).toBeDefined();
91
- expect(capIllustration.prop('title')).toBeDefined();
92
- });
93
- });
94
-
95
- describe('EMAIL Channel', () => {
96
- it('should return correct illustration info for EMAIL channel', () => {
97
- const component = renderComponent({ currentChannel: EMAIL });
98
- const capIllustration = component.find('CapIllustration');
99
-
100
- expect(capIllustration.prop('illustrationImage')).toBe('test-file-stub');
101
- expect(capIllustration.prop('onClick')).toBe(mockCreateTemplate);
102
- expect(capIllustration.prop('buttonLabel')).toBeDefined();
103
- expect(capIllustration.prop('title')).toBeDefined();
104
- });
105
- });
106
-
107
- describe('MOBILE_PUSH Channel', () => {
108
- it('should return correct illustration info for MOBILE_PUSH channel', () => {
109
- const component = renderComponent({ currentChannel: MOBILE_PUSH });
110
- const capIllustration = component.find('CapIllustration');
111
-
112
- expect(capIllustration.prop('illustrationImage')).toBe('test-file-stub');
113
- expect(capIllustration.prop('onClick')).toBe(mockCreateTemplate);
114
- expect(capIllustration.prop('buttonLabel')).toBeDefined();
115
- expect(capIllustration.prop('title')).toBeDefined();
116
- });
117
- });
118
-
119
- describe('WHATSAPP Channel', () => {
120
- it('should return correct illustration info for WHATSAPP channel when hostName is available', () => {
121
- const component = renderComponent({
122
- currentChannel: WHATSAPP,
123
- hostName: true
124
- });
125
- const capIllustration = component.find('CapIllustration');
126
-
127
- expect(capIllustration.prop('illustrationImage')).toBe('test-file-stub');
128
- expect(capIllustration.prop('onClick')).toBe(mockCreateTemplate);
129
- expect(capIllustration.prop('buttonLabel')).toBeDefined();
130
- expect(capIllustration.prop('title')).toBeDefined();
131
- expect(capIllustration.prop('description')).toBeDefined();
132
- expect(capIllustration.prop('descriptionPosition')).toBe('bottom');
133
- expect(capIllustration.prop('descriptionClassName')).toBe('illustration-desc');
134
- });
135
-
136
- it('should return account not configured info for WHATSAPP when hostName is not available', () => {
137
- const component = renderComponent({
138
- currentChannel: WHATSAPP,
139
- hostName: false
140
- });
141
- const capIllustration = component.find('CapIllustration');
142
-
143
- expect(capIllustration.prop('illustrationImage')).toBe('test-file-stub');
144
- expect(capIllustration.prop('title')).toBeDefined();
145
- expect(capIllustration.prop('description')).toBeDefined();
146
- expect(capIllustration.prop('descriptionPosition')).toBe('bottom');
147
- expect(capIllustration.prop('descriptionClassName')).toBe('illustration-desc zalo-illustration');
148
- expect(capIllustration.prop('buttonClassName')).toBe('zalo-illustration-button');
149
- expect(capIllustration.prop('onClick')).toBeUndefined();
150
- expect(capIllustration.prop('buttonLabel')).toBeUndefined();
151
- });
152
- });
153
-
154
- describe('RCS Channel', () => {
155
- it('should return correct illustration info for RCS channel', () => {
156
- const component = renderComponent({ currentChannel: RCS });
157
- const capIllustration = component.find('CapIllustration');
158
-
159
- expect(capIllustration.prop('illustrationImage')).toBe('test-file-stub');
160
- expect(capIllustration.prop('onClick')).toBe(mockCreateTemplate);
161
- expect(capIllustration.prop('buttonLabel')).toBeDefined();
162
- expect(capIllustration.prop('title')).toBeDefined();
163
- expect(capIllustration.prop('description')).toBeDefined();
164
- expect(capIllustration.prop('descriptionPosition')).toBe('bottom');
165
- expect(capIllustration.prop('descriptionClassName')).toBe('illustration-desc rcs-illustration');
166
- });
167
- });
168
-
169
- describe('ZALO Channel', () => {
170
- it('should return correct illustration info for ZALO channel when hostName is available', () => {
171
- const component = renderComponent({
172
- currentChannel: ZALO,
173
- hostName: true
174
- });
175
- const capIllustration = component.find('CapIllustration');
176
-
177
- expect(capIllustration.prop('illustrationImage')).toBe('test-file-stub');
178
- expect(capIllustration.prop('title')).toBeDefined();
179
- expect(capIllustration.prop('description')).toBeDefined();
180
- expect(capIllustration.prop('descriptionPosition')).toBe('bottom');
181
- expect(capIllustration.prop('descriptionClassName')).toBe('illustration-desc zalo-illustration');
182
- expect(capIllustration.prop('buttonClassName')).toBe('zalo-illustration-button');
183
- expect(capIllustration.prop('onClick')).toBeUndefined();
184
- expect(capIllustration.prop('buttonLabel')).toBeUndefined();
185
- });
186
-
187
- it('should return account not configured info for ZALO when hostName is not available', () => {
188
- const component = renderComponent({
189
- currentChannel: ZALO,
190
- hostName: false
191
- });
192
- const capIllustration = component.find('CapIllustration');
193
-
194
- expect(capIllustration.prop('illustrationImage')).toBe('test-file-stub');
195
- expect(capIllustration.prop('title')).toBeDefined();
196
- expect(capIllustration.prop('description')).toBeDefined();
197
- expect(capIllustration.prop('descriptionPosition')).toBe('bottom');
198
- expect(capIllustration.prop('descriptionClassName')).toBe('illustration-desc zalo-illustration');
199
- expect(capIllustration.prop('buttonClassName')).toBe('zalo-illustration-button');
200
- expect(capIllustration.prop('onClick')).toBeUndefined();
201
- expect(capIllustration.prop('buttonLabel')).toBeUndefined();
202
- });
203
- });
204
-
205
- describe('INAPP Channel', () => {
206
- it('should return correct illustration info for INAPP channel', () => {
207
- const component = renderComponent({ currentChannel: INAPP });
208
- const capIllustration = component.find('CapIllustration');
209
-
210
- expect(capIllustration.prop('illustrationImage')).toBe('test-file-stub');
211
- expect(capIllustration.prop('title')).toBeDefined();
212
- expect(capIllustration.prop('description')).toBeDefined();
213
- expect(capIllustration.prop('descriptionPosition')).toBe('bottom');
214
- expect(capIllustration.prop('descriptionClassName')).toBe('illustration-desc inapp-illustration');
215
- expect(capIllustration.prop('buttonClassName')).toBe('inapp-illustration-button');
216
- expect(capIllustration.prop('onClick')).toBeUndefined();
217
- expect(capIllustration.prop('buttonLabel')).toBeUndefined();
218
- });
219
- });
220
-
221
- describe('VIBER Channel', () => {
222
- it('should return correct illustration info for VIBER channel', () => {
223
- const component = renderComponent({ currentChannel: VIBER });
224
- const capIllustration = component.find('CapIllustration');
225
-
226
- expect(capIllustration.prop('illustrationImage')).toBe('test-file-stub');
227
- expect(capIllustration.prop('onClick')).toBe(mockCreateTemplate);
228
- expect(capIllustration.prop('buttonLabel')).toBeDefined();
229
- expect(capIllustration.prop('title')).toBeDefined();
230
- });
231
- });
232
-
233
- describe('LINE Channel', () => {
234
- it('should return correct illustration info for LINE channel', () => {
235
- const component = renderComponent({ currentChannel: LINE });
236
- const capIllustration = component.find('CapIllustration');
237
-
238
- expect(capIllustration.prop('illustrationImage')).toBe('test-file-stub');
239
- expect(capIllustration.prop('onClick')).toBe(mockCreateTemplate);
240
- expect(capIllustration.prop('buttonLabel')).toBeDefined();
241
- expect(capIllustration.prop('title')).toBeDefined();
242
- });
243
- });
244
-
245
- describe('FACEBOOK Channel', () => {
246
- it('should return correct illustration info for FACEBOOK channel', () => {
247
- const component = renderComponent({ currentChannel: FACEBOOK });
248
- const capIllustration = component.find('CapIllustration');
249
-
250
- expect(capIllustration.prop('illustrationImage')).toBe('test-file-stub');
251
- expect(capIllustration.prop('onClick')).toBe(mockCreateTemplate);
252
- expect(capIllustration.prop('buttonLabel')).toBeDefined();
253
- expect(capIllustration.prop('title')).toBeDefined();
254
- });
255
- });
256
-
257
- describe('Edge Cases', () => {
258
- it('should return default illustration for unknown channel type', () => {
259
- const component = renderComponent({ currentChannel: 'UNKNOWN_CHANNEL' });
260
- const capIllustration = component.find('CapIllustration');
261
-
262
- expect(capIllustration.prop('illustrationImage')).toBe('test-file-stub');
263
- expect(capIllustration.prop('onClick')).toBeUndefined();
264
- expect(capIllustration.prop('buttonLabel')).toBeDefined();;
265
- expect(capIllustration.prop('title')).toBe('');
266
- });
267
-
268
- it('should handle null currentChannel', () => {
269
- const component = renderComponent({ currentChannel: null });
270
- const capIllustration = component.find('CapIllustration');
271
-
272
- expect(capIllustration.prop('buttonClassName')).toBe('unknown-illustration-button');
273
- });
274
-
275
- it('should handle empty string currentChannel', () => {
276
- const component = renderComponent({ currentChannel: '' });
277
- const capIllustration = component.find('CapIllustration');
278
-
279
- expect(capIllustration.prop('buttonClassName')).toBe('unknown-illustration-button');
280
- });
281
- });
282
-
283
- describe('isFullMode Behavior', () => {
284
- it('should render FormattedMessage components when isFullMode is true', () => {
285
- const component = renderComponent({
286
- currentChannel: SMS,
287
- isFullMode: true
288
- });
289
- const capIllustration = component.find('CapIllustration');
290
- expect(capIllustration.prop('buttonLabel')).toBeDefined();
291
- expect(capIllustration.prop('title')).toBeDefined();
292
- });
293
-
294
- it('should render FormattedMessage components when isFullMode is false', () => {
295
- const component = renderComponent({
296
- currentChannel: SMS,
297
- isFullMode: false
298
- });
299
- const capIllustration = component.find('CapIllustration');
300
- expect(capIllustration.prop('buttonLabel')).toBeDefined();
301
- expect(capIllustration.prop('title')).toBeDefined();
302
- });
303
- });
304
-
305
- describe('PropTypes Validation', () => {
306
- it('should handle missing optional props gracefully', () => {
307
- const minimalProps = {
308
- intl: mockIntl,
309
- createTemplate: mockCreateTemplate
310
- };
311
-
312
- expect(() => {
313
- renderComponent(minimalProps);
314
- }).not.toThrow();
315
- });
316
-
317
- it('should handle all required props', () => {
318
- expect(() => {
319
- renderComponent(defaultProps);
320
- }).not.toThrow();
321
- });
322
- });
323
- });