@capillarytech/creatives-library 8.0.208 → 8.0.210

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 (76) hide show
  1. package/assets/Android.png +0 -0
  2. package/assets/iOS.png +0 -0
  3. package/package.json +16 -2
  4. package/v2Components/HtmlEditor/HTMLEditor.js +508 -0
  5. package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +1809 -0
  6. package/v2Components/HtmlEditor/__tests__/index.lazy.test.js +532 -0
  7. package/v2Components/HtmlEditor/_htmlEditor.scss +304 -0
  8. package/v2Components/HtmlEditor/_index.lazy.scss +26 -0
  9. package/v2Components/HtmlEditor/components/CodeEditorPane/_codeEditorPane.scss +376 -0
  10. package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +331 -0
  11. package/v2Components/HtmlEditor/components/DeviceToggle/__tests__/index.test.js +314 -0
  12. package/v2Components/HtmlEditor/components/DeviceToggle/_deviceToggle.scss +244 -0
  13. package/v2Components/HtmlEditor/components/DeviceToggle/index.js +111 -0
  14. package/v2Components/HtmlEditor/components/EditorToolbar/PreviewModeGroup.js +72 -0
  15. package/v2Components/HtmlEditor/components/EditorToolbar/__tests__/PreviewModeGroup.test.js +1594 -0
  16. package/v2Components/HtmlEditor/components/EditorToolbar/_editorToolbar.scss +113 -0
  17. package/v2Components/HtmlEditor/components/EditorToolbar/_previewModeGroup.scss +82 -0
  18. package/v2Components/HtmlEditor/components/EditorToolbar/index.js +115 -0
  19. package/v2Components/HtmlEditor/components/FullscreenModal/_fullscreenModal.scss +57 -0
  20. package/v2Components/HtmlEditor/components/InAppPreviewPane/ContentOverlay.js +90 -0
  21. package/v2Components/HtmlEditor/components/InAppPreviewPane/DeviceFrame.js +60 -0
  22. package/v2Components/HtmlEditor/components/InAppPreviewPane/LayoutSelector.js +58 -0
  23. package/v2Components/HtmlEditor/components/InAppPreviewPane/__tests__/ContentOverlay.test.js +403 -0
  24. package/v2Components/HtmlEditor/components/InAppPreviewPane/__tests__/DeviceFrame.test.js +424 -0
  25. package/v2Components/HtmlEditor/components/InAppPreviewPane/__tests__/LayoutSelector.test.js +248 -0
  26. package/v2Components/HtmlEditor/components/InAppPreviewPane/_inAppPreviewPane.scss +253 -0
  27. package/v2Components/HtmlEditor/components/InAppPreviewPane/constants.js +104 -0
  28. package/v2Components/HtmlEditor/components/InAppPreviewPane/index.js +179 -0
  29. package/v2Components/HtmlEditor/components/PreviewPane/_previewPane.scss +220 -0
  30. package/v2Components/HtmlEditor/components/PreviewPane/index.js +229 -0
  31. package/v2Components/HtmlEditor/components/SplitContainer/SplitContainer.js +276 -0
  32. package/v2Components/HtmlEditor/components/SplitContainer/__tests__/SplitContainer.test.js +295 -0
  33. package/v2Components/HtmlEditor/components/SplitContainer/_splitContainer.scss +257 -0
  34. package/v2Components/HtmlEditor/components/SplitContainer/index.js +7 -0
  35. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/__tests__/index.test.js +152 -0
  36. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/_validationErrorDisplay.scss +31 -0
  37. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/index.js +70 -0
  38. package/v2Components/HtmlEditor/components/ValidationPanel/__tests__/index.test.js +98 -0
  39. package/v2Components/HtmlEditor/components/ValidationPanel/_validationPanel.scss +311 -0
  40. package/v2Components/HtmlEditor/components/ValidationPanel/index.js +297 -0
  41. package/v2Components/HtmlEditor/components/ValidationPanel/messages.js +57 -0
  42. package/v2Components/HtmlEditor/components/common/EditorContext.js +84 -0
  43. package/v2Components/HtmlEditor/components/common/__tests__/EditorContext.test.js +660 -0
  44. package/v2Components/HtmlEditor/constants.js +241 -0
  45. package/v2Components/HtmlEditor/hooks/__tests__/useEditorContent.test.js +450 -0
  46. package/v2Components/HtmlEditor/hooks/__tests__/useInAppContent.test.js +785 -0
  47. package/v2Components/HtmlEditor/hooks/__tests__/useLayoutState.test.js +580 -0
  48. package/v2Components/HtmlEditor/hooks/__tests__/useValidation.enhanced.test.js +768 -0
  49. package/v2Components/HtmlEditor/hooks/__tests__/useValidation.test.js +590 -0
  50. package/v2Components/HtmlEditor/hooks/useEditorContent.js +274 -0
  51. package/v2Components/HtmlEditor/hooks/useInAppContent.js +407 -0
  52. package/v2Components/HtmlEditor/hooks/useLayoutState.js +247 -0
  53. package/v2Components/HtmlEditor/hooks/useValidation.js +325 -0
  54. package/v2Components/HtmlEditor/index.js +29 -0
  55. package/v2Components/HtmlEditor/index.lazy.js +114 -0
  56. package/v2Components/HtmlEditor/messages.js +389 -0
  57. package/v2Components/HtmlEditor/utils/__tests__/contentSanitizer.test.js +741 -0
  58. package/v2Components/HtmlEditor/utils/__tests__/htmlValidator.enhanced.test.js +1042 -0
  59. package/v2Components/HtmlEditor/utils/__tests__/liquidTemplateSupport.test.js +515 -0
  60. package/v2Components/HtmlEditor/utils/__tests__/properSyntaxHighlighting.test.js +473 -0
  61. package/v2Components/HtmlEditor/utils/__tests__/simplePerformance.test.js +1109 -0
  62. package/v2Components/HtmlEditor/utils/__tests__/validationAdapter.test.js +240 -0
  63. package/v2Components/HtmlEditor/utils/contentSanitizer.js +433 -0
  64. package/v2Components/HtmlEditor/utils/htmlValidator.js +508 -0
  65. package/v2Components/HtmlEditor/utils/liquidTemplateSupport.js +524 -0
  66. package/v2Components/HtmlEditor/utils/properSyntaxHighlighting.js +163 -0
  67. package/v2Components/HtmlEditor/utils/simplePerformance.js +145 -0
  68. package/v2Components/HtmlEditor/utils/validationAdapter.js +130 -0
  69. package/v2Containers/EmailWrapper/components/HTMLEditorTesting.js +200 -0
  70. package/v2Containers/EmailWrapper/components/__tests__/HTMLEditorTesting.test.js +545 -0
  71. package/v2Containers/EmailWrapper/index.js +8 -1
  72. package/v2Containers/Rcs/index.js +2 -0
  73. package/v2Containers/Templates/constants.js +8 -0
  74. package/v2Containers/Templates/index.js +56 -28
  75. package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +5 -14
  76. package/v2Containers/Whatsapp/index.js +1 -0
@@ -0,0 +1,545 @@
1
+ /**
2
+ * HTMLEditorTesting Component Tests
3
+ *
4
+ * Tests for the console-controlled HTMLEditor testing component
5
+ */
6
+
7
+ import React from 'react';
8
+ import { render, screen, fireEvent, act } from '@testing-library/react';
9
+ import '@testing-library/jest-dom';
10
+ import HTMLEditorTesting from '../HTMLEditorTesting';
11
+ import { HTML_EDITOR_VARIANTS } from '../../../../v2Components/HtmlEditor/constants';
12
+ import { LAYOUT_TYPES } from '../../../../v2Components/HtmlEditor/components/InAppPreviewPane/constants';
13
+
14
+ // Mock the HTMLEditor component
15
+ jest.mock('../../../../v2Components/HtmlEditor', () => {
16
+ return function MockHTMLEditor({ variant, layoutType, initialContent, onContentChange, onSave }) {
17
+ return (
18
+ <div data-testid="mock-html-editor">
19
+ <div data-testid="editor-variant">{variant}</div>
20
+ <div data-testid="editor-layout">{layoutType}</div>
21
+ <div data-testid="editor-content">{initialContent}</div>
22
+ <button
23
+ onClick={() => onContentChange && onContentChange('<p>Changed content</p>')}
24
+ data-testid="trigger-content-change"
25
+ >
26
+ Change Content
27
+ </button>
28
+ <button
29
+ onClick={() => onSave && onSave('<p>Saved content</p>')}
30
+ data-testid="trigger-save"
31
+ >
32
+ Save
33
+ </button>
34
+ </div>
35
+ );
36
+ };
37
+ });
38
+
39
+ // Mock IntlProvider
40
+ jest.mock('react-intl', () => ({
41
+ IntlProvider: ({ children }) => <div data-testid="intl-provider">{children}</div>
42
+ }));
43
+
44
+ describe('HTMLEditorTesting', () => {
45
+ let consoleSpy;
46
+
47
+ beforeEach(() => {
48
+ // Mock console methods
49
+ consoleSpy = {
50
+ log: jest.spyOn(console, 'log').mockImplementation(() => {}),
51
+ error: jest.spyOn(console, 'error').mockImplementation(() => {})
52
+ };
53
+
54
+ // Clear any existing window.htmlEditorTest
55
+ if (window.htmlEditorTest) {
56
+ delete window.htmlEditorTest;
57
+ }
58
+ });
59
+
60
+ afterEach(() => {
61
+ // Restore console methods
62
+ consoleSpy.log.mockRestore();
63
+ consoleSpy.error.mockRestore();
64
+
65
+ // Clean up window.htmlEditorTest
66
+ if (window.htmlEditorTest) {
67
+ delete window.htmlEditorTest;
68
+ }
69
+ });
70
+
71
+ describe('Initial Render', () => {
72
+ it('renders nothing initially (hidden by default)', () => {
73
+ render(<HTMLEditorTesting />);
74
+ expect(screen.queryByTestId('mock-html-editor')).not.toBeInTheDocument();
75
+ });
76
+
77
+ it('sets up console interface on mount', () => {
78
+ render(<HTMLEditorTesting />);
79
+
80
+ expect(window.htmlEditorTest).toBeDefined();
81
+ expect(typeof window.htmlEditorTest.show).toBe('function');
82
+ expect(typeof window.htmlEditorTest.hide).toBe('function');
83
+ expect(typeof window.htmlEditorTest.toggle).toBe('function');
84
+ expect(typeof window.htmlEditorTest.setVariant).toBe('function');
85
+ expect(typeof window.htmlEditorTest.setLayout).toBe('function');
86
+ expect(typeof window.htmlEditorTest.setContent).toBe('function');
87
+ expect(typeof window.htmlEditorTest.getContent).toBe('function');
88
+ expect(typeof window.htmlEditorTest.status).toBe('function');
89
+ expect(typeof window.htmlEditorTest.help).toBe('function');
90
+ });
91
+
92
+ it('logs help message on initial load', () => {
93
+ render(<HTMLEditorTesting />);
94
+
95
+ expect(consoleSpy.log).toHaveBeenCalledWith(
96
+ '🚀 HTMLEditor Testing Ready! Type htmlEditorTest.help() for commands'
97
+ );
98
+ });
99
+ });
100
+
101
+ describe('Visibility Control', () => {
102
+ it('shows editor when show() is called', () => {
103
+ render(<HTMLEditorTesting />);
104
+
105
+ act(() => {
106
+ window.htmlEditorTest.show();
107
+ });
108
+
109
+ expect(screen.getByTestId('mock-html-editor')).toBeInTheDocument();
110
+ expect(consoleSpy.log).toHaveBeenCalledWith('✅ HTMLEditor test mode activated');
111
+ });
112
+
113
+ it('hides editor when hide() is called', () => {
114
+ render(<HTMLEditorTesting />);
115
+
116
+ // Show first
117
+ act(() => {
118
+ window.htmlEditorTest.show();
119
+ });
120
+ expect(screen.getByTestId('mock-html-editor')).toBeInTheDocument();
121
+
122
+ // Then hide
123
+ act(() => {
124
+ window.htmlEditorTest.hide();
125
+ });
126
+ expect(screen.queryByTestId('mock-html-editor')).not.toBeInTheDocument();
127
+ expect(consoleSpy.log).toHaveBeenCalledWith('✅ HTMLEditor test mode deactivated');
128
+ });
129
+
130
+ it('toggles editor visibility with toggle()', () => {
131
+ render(<HTMLEditorTesting />);
132
+
133
+ // Toggle to show
134
+ act(() => {
135
+ window.htmlEditorTest.toggle();
136
+ });
137
+ expect(screen.getByTestId('mock-html-editor')).toBeInTheDocument();
138
+ expect(consoleSpy.log).toHaveBeenCalledWith('✅ HTMLEditor test mode activated');
139
+
140
+ // Toggle to hide
141
+ act(() => {
142
+ window.htmlEditorTest.toggle();
143
+ });
144
+ expect(screen.queryByTestId('mock-html-editor')).not.toBeInTheDocument();
145
+ expect(consoleSpy.log).toHaveBeenCalledWith('✅ HTMLEditor test mode deactivated');
146
+ });
147
+
148
+ it('closes editor when close button is clicked', () => {
149
+ render(<HTMLEditorTesting />);
150
+
151
+ act(() => {
152
+ window.htmlEditorTest.show();
153
+ });
154
+
155
+ const closeButton = screen.getByText('Close');
156
+ fireEvent.click(closeButton);
157
+
158
+ expect(screen.queryByTestId('mock-html-editor')).not.toBeInTheDocument();
159
+ });
160
+ });
161
+
162
+ describe('Variant Control', () => {
163
+ it('sets variant to email', () => {
164
+ render(<HTMLEditorTesting />);
165
+
166
+ act(() => {
167
+ window.htmlEditorTest.show();
168
+ window.htmlEditorTest.setVariant('email');
169
+ });
170
+
171
+ expect(screen.getByTestId('editor-variant')).toHaveTextContent('email');
172
+ expect(consoleSpy.log).toHaveBeenCalledWith('✅ Variant set to: email');
173
+ });
174
+
175
+ it('sets variant to inapp', () => {
176
+ render(<HTMLEditorTesting />);
177
+
178
+ act(() => {
179
+ window.htmlEditorTest.show();
180
+ window.htmlEditorTest.setVariant('inapp');
181
+ });
182
+
183
+ expect(screen.getByTestId('editor-variant')).toHaveTextContent('inapp');
184
+ expect(consoleSpy.log).toHaveBeenCalledWith('✅ Variant set to: inapp');
185
+ });
186
+
187
+ it('rejects invalid variant', () => {
188
+ render(<HTMLEditorTesting />);
189
+
190
+ act(() => {
191
+ window.htmlEditorTest.setVariant('invalid');
192
+ });
193
+
194
+ expect(consoleSpy.error).toHaveBeenCalledWith('❌ Invalid variant. Use: "email" or "inapp"');
195
+ });
196
+
197
+ it('starts with email variant by default', () => {
198
+ render(<HTMLEditorTesting />);
199
+
200
+ act(() => {
201
+ window.htmlEditorTest.show();
202
+ });
203
+
204
+ expect(screen.getByTestId('editor-variant')).toHaveTextContent(HTML_EDITOR_VARIANTS.EMAIL);
205
+ });
206
+ });
207
+
208
+ describe('Layout Control', () => {
209
+ it('sets layout to POPUP (MODAL)', () => {
210
+ render(<HTMLEditorTesting />);
211
+
212
+ act(() => {
213
+ window.htmlEditorTest.show();
214
+ window.htmlEditorTest.setLayout(LAYOUT_TYPES.MODAL);
215
+ });
216
+
217
+ expect(screen.getByTestId('editor-layout')).toHaveTextContent(LAYOUT_TYPES.MODAL);
218
+ expect(consoleSpy.log).toHaveBeenCalledWith(`✅ Layout set to: ${LAYOUT_TYPES.MODAL}`);
219
+ });
220
+
221
+ it('sets layout to HEADER', () => {
222
+ render(<HTMLEditorTesting />);
223
+
224
+ act(() => {
225
+ window.htmlEditorTest.show();
226
+ window.htmlEditorTest.setLayout(LAYOUT_TYPES.HEADER);
227
+ });
228
+
229
+ expect(screen.getByTestId('editor-layout')).toHaveTextContent(LAYOUT_TYPES.HEADER);
230
+ expect(consoleSpy.log).toHaveBeenCalledWith(`✅ Layout set to: ${LAYOUT_TYPES.HEADER}`);
231
+ });
232
+
233
+ it('sets layout to FOOTER', () => {
234
+ render(<HTMLEditorTesting />);
235
+
236
+ act(() => {
237
+ window.htmlEditorTest.show();
238
+ window.htmlEditorTest.setLayout(LAYOUT_TYPES.FOOTER);
239
+ });
240
+
241
+ expect(screen.getByTestId('editor-layout')).toHaveTextContent(LAYOUT_TYPES.FOOTER);
242
+ expect(consoleSpy.log).toHaveBeenCalledWith(`✅ Layout set to: ${LAYOUT_TYPES.FOOTER}`);
243
+ });
244
+
245
+ it('sets layout to FULLSCREEN', () => {
246
+ render(<HTMLEditorTesting />);
247
+
248
+ act(() => {
249
+ window.htmlEditorTest.show();
250
+ window.htmlEditorTest.setLayout(LAYOUT_TYPES.FULLSCREEN);
251
+ });
252
+
253
+ expect(screen.getByTestId('editor-layout')).toHaveTextContent(LAYOUT_TYPES.FULLSCREEN);
254
+ expect(consoleSpy.log).toHaveBeenCalledWith(`✅ Layout set to: ${LAYOUT_TYPES.FULLSCREEN}`);
255
+ });
256
+
257
+ it('rejects invalid layout', () => {
258
+ render(<HTMLEditorTesting />);
259
+
260
+ act(() => {
261
+ window.htmlEditorTest.setLayout('INVALID');
262
+ });
263
+
264
+ const validLayouts = Object.values(LAYOUT_TYPES);
265
+ expect(consoleSpy.error).toHaveBeenCalledWith(
266
+ `❌ Invalid layout. Use: ${validLayouts.join(', ')}`
267
+ );
268
+ });
269
+
270
+ it('starts with MODAL layout by default', () => {
271
+ render(<HTMLEditorTesting />);
272
+
273
+ act(() => {
274
+ window.htmlEditorTest.show();
275
+ });
276
+
277
+ expect(screen.getByTestId('editor-layout')).toHaveTextContent(LAYOUT_TYPES.MODAL);
278
+ });
279
+ });
280
+
281
+ describe('Content Control', () => {
282
+ it('sets content', () => {
283
+ render(<HTMLEditorTesting />);
284
+
285
+ const newContent = '<p>New test content</p>';
286
+ act(() => {
287
+ window.htmlEditorTest.show();
288
+ window.htmlEditorTest.setContent(newContent);
289
+ });
290
+
291
+ expect(screen.getByTestId('editor-content')).toHaveTextContent(newContent);
292
+ expect(consoleSpy.log).toHaveBeenCalledWith('✅ Content updated');
293
+ });
294
+
295
+ it('gets current content', () => {
296
+ render(<HTMLEditorTesting />);
297
+
298
+ const result = window.htmlEditorTest.getContent();
299
+
300
+ expect(result).toBe('<h1>Test HTML Editor</h1><p>This is a test integration.</p>');
301
+ expect(consoleSpy.log).toHaveBeenCalledWith('Current content:', result);
302
+ });
303
+
304
+ it('starts with default content', () => {
305
+ render(<HTMLEditorTesting />);
306
+
307
+ act(() => {
308
+ window.htmlEditorTest.show();
309
+ });
310
+
311
+ expect(screen.getByTestId('editor-content')).toHaveTextContent(
312
+ '<h1>Test HTML Editor</h1><p>This is a test integration.</p>'
313
+ );
314
+ });
315
+
316
+ it('handles content change callback', () => {
317
+ render(<HTMLEditorTesting />);
318
+
319
+ act(() => {
320
+ window.htmlEditorTest.show();
321
+ });
322
+
323
+ const changeButton = screen.getByTestId('trigger-content-change');
324
+ fireEvent.click(changeButton);
325
+
326
+ expect(consoleSpy.log).toHaveBeenCalledWith('📝 Content changed:', '<p>Changed content</p>...');
327
+ });
328
+
329
+ it('handles save callback', () => {
330
+ render(<HTMLEditorTesting />);
331
+
332
+ act(() => {
333
+ window.htmlEditorTest.show();
334
+ });
335
+
336
+ const saveButton = screen.getByTestId('trigger-save');
337
+ fireEvent.click(saveButton);
338
+
339
+ expect(consoleSpy.log).toHaveBeenCalledWith('💾 Content saved:', '<p>Saved content</p>');
340
+ });
341
+ });
342
+
343
+ describe('Status and Help', () => {
344
+ it('shows status information', () => {
345
+ render(<HTMLEditorTesting />);
346
+
347
+ act(() => {
348
+ window.htmlEditorTest.show();
349
+ window.htmlEditorTest.setVariant('inapp');
350
+ window.htmlEditorTest.setLayout(LAYOUT_TYPES.HEADER);
351
+ });
352
+
353
+ // Clear previous console calls
354
+ consoleSpy.log.mockClear();
355
+
356
+ act(() => {
357
+ window.htmlEditorTest.status();
358
+ });
359
+
360
+ expect(consoleSpy.log).toHaveBeenCalledWith('📊 HTMLEditor Test Status:');
361
+ expect(consoleSpy.log).toHaveBeenCalledWith(' Visible: true');
362
+ expect(consoleSpy.log).toHaveBeenCalledWith(' Variant: inapp');
363
+ expect(consoleSpy.log).toHaveBeenCalledWith(' Layout: HEADER');
364
+ expect(consoleSpy.log).toHaveBeenCalledWith(' Content size: 59 chars');
365
+ });
366
+
367
+ it('shows help information', () => {
368
+ render(<HTMLEditorTesting />);
369
+
370
+ act(() => {
371
+ window.htmlEditorTest.help();
372
+ });
373
+
374
+ expect(consoleSpy.log).toHaveBeenCalledWith(expect.stringContaining('🚀 HTMLEditor Testing Console Commands:'));
375
+ expect(consoleSpy.log).toHaveBeenCalledWith(expect.stringContaining('htmlEditorTest.show()'));
376
+ expect(consoleSpy.log).toHaveBeenCalledWith(expect.stringContaining('htmlEditorTest.setVariant(\'email\')'));
377
+ expect(consoleSpy.log).toHaveBeenCalledWith(expect.stringContaining('htmlEditorTest.setLayout(\'POPUP\')'));
378
+ });
379
+ });
380
+
381
+ describe('UI Elements', () => {
382
+ it('displays header with current configuration', () => {
383
+ render(<HTMLEditorTesting />);
384
+
385
+ act(() => {
386
+ window.htmlEditorTest.show();
387
+ window.htmlEditorTest.setVariant('inapp');
388
+ window.htmlEditorTest.setLayout(LAYOUT_TYPES.FOOTER);
389
+ });
390
+
391
+ expect(screen.getByText('HTMLEditor Testing Mode')).toBeInTheDocument();
392
+ expect(screen.getByText('Variant: inapp | Layout: FOOTER')).toBeInTheDocument();
393
+ });
394
+
395
+ it('renders with proper styling structure', () => {
396
+ render(<HTMLEditorTesting />);
397
+
398
+ act(() => {
399
+ window.htmlEditorTest.show();
400
+ });
401
+
402
+ // Check for main container
403
+ const container = screen.getByTestId('mock-html-editor').closest('div[style*="position: fixed"]');
404
+ expect(container).toBeInTheDocument();
405
+
406
+ // Check for IntlProvider wrapper
407
+ expect(screen.getByTestId('intl-provider')).toBeInTheDocument();
408
+ });
409
+ });
410
+
411
+ describe('Cleanup', () => {
412
+ it('cleans up console interface on unmount', () => {
413
+ const { unmount } = render(<HTMLEditorTesting />);
414
+
415
+ expect(window.htmlEditorTest).toBeDefined();
416
+
417
+ unmount();
418
+
419
+ expect(window.htmlEditorTest).toBeUndefined();
420
+ });
421
+
422
+ it('handles cleanup when window.htmlEditorTest does not exist', () => {
423
+ const { unmount } = render(<HTMLEditorTesting />);
424
+
425
+ // Manually delete it first
426
+ delete window.htmlEditorTest;
427
+
428
+ // Should not throw when unmounting
429
+ expect(() => unmount()).not.toThrow();
430
+ });
431
+ });
432
+
433
+ describe('Integration Scenarios', () => {
434
+ it('switches between variants and layouts', () => {
435
+ render(<HTMLEditorTesting />);
436
+
437
+ act(() => {
438
+ window.htmlEditorTest.show();
439
+ window.htmlEditorTest.setVariant('inapp');
440
+ window.htmlEditorTest.setLayout(LAYOUT_TYPES.HEADER);
441
+ });
442
+
443
+ expect(screen.getByTestId('editor-variant')).toHaveTextContent('inapp');
444
+ expect(screen.getByTestId('editor-layout')).toHaveTextContent(LAYOUT_TYPES.HEADER);
445
+
446
+ act(() => {
447
+ window.htmlEditorTest.setVariant('email');
448
+ window.htmlEditorTest.setLayout(LAYOUT_TYPES.FULLSCREEN);
449
+ });
450
+
451
+ expect(screen.getByTestId('editor-variant')).toHaveTextContent('email');
452
+ expect(screen.getByTestId('editor-layout')).toHaveTextContent(LAYOUT_TYPES.FULLSCREEN);
453
+ });
454
+
455
+ it('updates content and checks status', () => {
456
+ render(<HTMLEditorTesting />);
457
+
458
+ const customContent = '<div><h2>Custom Title</h2><p>Custom content here</p></div>';
459
+
460
+ act(() => {
461
+ window.htmlEditorTest.show();
462
+ window.htmlEditorTest.setContent(customContent);
463
+ });
464
+
465
+ expect(screen.getByTestId('editor-content')).toHaveTextContent(customContent);
466
+
467
+ // Clear previous console calls before checking status
468
+ consoleSpy.log.mockClear();
469
+
470
+ act(() => {
471
+ window.htmlEditorTest.status();
472
+ });
473
+
474
+ expect(consoleSpy.log).toHaveBeenCalledWith(` Content size: ${customContent.length} chars`);
475
+ });
476
+
477
+ it('handles multiple rapid operations', () => {
478
+ render(<HTMLEditorTesting />);
479
+
480
+ act(() => {
481
+ window.htmlEditorTest.show();
482
+ window.htmlEditorTest.setVariant('inapp');
483
+ window.htmlEditorTest.setLayout(LAYOUT_TYPES.MODAL);
484
+ window.htmlEditorTest.setContent('<p>Rapid test</p>');
485
+ window.htmlEditorTest.hide();
486
+ window.htmlEditorTest.show();
487
+ });
488
+
489
+ expect(screen.getByTestId('editor-variant')).toHaveTextContent('inapp');
490
+ expect(screen.getByTestId('editor-layout')).toHaveTextContent(LAYOUT_TYPES.MODAL);
491
+ expect(screen.getByTestId('editor-content')).toHaveTextContent('<p>Rapid test</p>');
492
+ });
493
+ });
494
+
495
+ describe('Edge Cases', () => {
496
+ it('handles empty content', () => {
497
+ render(<HTMLEditorTesting />);
498
+
499
+ act(() => {
500
+ window.htmlEditorTest.show();
501
+ window.htmlEditorTest.setContent('');
502
+ });
503
+
504
+ expect(screen.getByTestId('editor-content')).toHaveTextContent('');
505
+ });
506
+
507
+ it('handles very long content', () => {
508
+ render(<HTMLEditorTesting />);
509
+
510
+ const longContent = '<p>' + 'A'.repeat(10000) + '</p>';
511
+
512
+ act(() => {
513
+ window.htmlEditorTest.show();
514
+ window.htmlEditorTest.setContent(longContent);
515
+ });
516
+
517
+ expect(screen.getByTestId('editor-content')).toHaveTextContent(longContent);
518
+ });
519
+
520
+ it('handles special characters in content', () => {
521
+ render(<HTMLEditorTesting />);
522
+
523
+ const specialContent = '<p>Special chars: &lt;&gt;&amp;"\'</p>';
524
+
525
+ act(() => {
526
+ window.htmlEditorTest.show();
527
+ window.htmlEditorTest.setContent(specialContent);
528
+ });
529
+
530
+ expect(screen.getByTestId('editor-content')).toHaveTextContent(specialContent);
531
+ });
532
+
533
+ it('handles null/undefined content gracefully', () => {
534
+ render(<HTMLEditorTesting />);
535
+
536
+ act(() => {
537
+ window.htmlEditorTest.show();
538
+ window.htmlEditorTest.setContent(null);
539
+ });
540
+
541
+ // Should not throw and should handle gracefully
542
+ expect(screen.getByTestId('editor-content')).toBeInTheDocument();
543
+ });
544
+ });
545
+ });
@@ -21,6 +21,8 @@ import * as templatesActionsCreators from '../Templates/actions';
21
21
  import { selectCurrentOrgDetails } from "../../v2Containers/Cap/selectors";
22
22
  import EmailWrapperView from './components/EmailWrapperView';
23
23
  import useEmailWrapper from './hooks/useEmailWrapper';
24
+ import HTMLEditorTesting from './components/HTMLEditorTesting';
25
+
24
26
 
25
27
  const EmailWrapper = (props) => {
26
28
  // Destructure props for clarity before passing to hook
@@ -119,7 +121,8 @@ const EmailWrapper = (props) => {
119
121
 
120
122
  // Render using the presentation component with data from the hook
121
123
  return (
122
- <EmailWrapperView
124
+ <div>
125
+ <EmailWrapperView
123
126
  isUploading={isUploading}
124
127
  emailCreateMode={emailCreateMode}
125
128
  step={step}
@@ -140,6 +143,10 @@ const EmailWrapper = (props) => {
140
143
  onTestContentClicked={onTestContentClicked}
141
144
  editor={editor}
142
145
  />
146
+
147
+ {/* HTMLEditor Testing Component - Console Controlled */}
148
+ <HTMLEditorTesting />
149
+ </div>
143
150
  );
144
151
  };
145
152
 
@@ -1755,7 +1755,9 @@ const splitTemplateVarString = (str) => {
1755
1755
 
1756
1756
  const uploadRcsImage = useCallback((file, type, fileParams, index) => {
1757
1757
  setImageError(null);
1758
+ const isRcsThumbnail = index === 1;
1758
1759
  actions.uploadRcsAsset(file, type, {
1760
+ isRcsThumbnail,
1759
1761
  ...fileParams,
1760
1762
  dimensionType: selectedDimension,
1761
1763
  orientation: RCS_IMAGE_DIMENSIONS[selectedDimension].orientation,
@@ -81,3 +81,11 @@ export const ACCOUNT_MAPPING_ON_CHANNEL = {
81
81
  whatsapp: 'selectedWhatsappAccount',
82
82
  zalo: 'selectedZaloAccount',
83
83
  };
84
+
85
+ export const noFilteredWhatsappZaloTemplatesTitle= 'noFilteredWhatsappZaloTemplatesTitle';
86
+ export const noFilteredWhatsappZaloTemplatesDesc ='noFilteredWhatsappZaloTemplatesDesc';
87
+ export const noApprovedWhatsappZaloTemplatesTitle ='noApprovedWhatsappZaloTemplatesTitle'
88
+ export const noApprovedWhatsappTemplatesDesc ='noApprovedWhatsappTemplatesDesc'
89
+ export const zaloDescIllustration='zaloDescIllustration'
90
+ export const noApprovedRcsTemplatesTitle='noApprovedRcsTemplatesTitle'
91
+ export const noApprovedRcsTemplatesDesc='noApprovedRcsTemplatesDesc'