@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.
- package/assets/Android.png +0 -0
- package/assets/iOS.png +0 -0
- package/package.json +16 -2
- package/v2Components/HtmlEditor/HTMLEditor.js +508 -0
- package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +1809 -0
- package/v2Components/HtmlEditor/__tests__/index.lazy.test.js +532 -0
- package/v2Components/HtmlEditor/_htmlEditor.scss +304 -0
- package/v2Components/HtmlEditor/_index.lazy.scss +26 -0
- package/v2Components/HtmlEditor/components/CodeEditorPane/_codeEditorPane.scss +376 -0
- package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +331 -0
- package/v2Components/HtmlEditor/components/DeviceToggle/__tests__/index.test.js +314 -0
- package/v2Components/HtmlEditor/components/DeviceToggle/_deviceToggle.scss +244 -0
- package/v2Components/HtmlEditor/components/DeviceToggle/index.js +111 -0
- package/v2Components/HtmlEditor/components/EditorToolbar/PreviewModeGroup.js +72 -0
- package/v2Components/HtmlEditor/components/EditorToolbar/__tests__/PreviewModeGroup.test.js +1594 -0
- package/v2Components/HtmlEditor/components/EditorToolbar/_editorToolbar.scss +113 -0
- package/v2Components/HtmlEditor/components/EditorToolbar/_previewModeGroup.scss +82 -0
- package/v2Components/HtmlEditor/components/EditorToolbar/index.js +115 -0
- package/v2Components/HtmlEditor/components/FullscreenModal/_fullscreenModal.scss +57 -0
- package/v2Components/HtmlEditor/components/InAppPreviewPane/ContentOverlay.js +90 -0
- package/v2Components/HtmlEditor/components/InAppPreviewPane/DeviceFrame.js +60 -0
- package/v2Components/HtmlEditor/components/InAppPreviewPane/LayoutSelector.js +58 -0
- package/v2Components/HtmlEditor/components/InAppPreviewPane/__tests__/ContentOverlay.test.js +403 -0
- package/v2Components/HtmlEditor/components/InAppPreviewPane/__tests__/DeviceFrame.test.js +424 -0
- package/v2Components/HtmlEditor/components/InAppPreviewPane/__tests__/LayoutSelector.test.js +248 -0
- package/v2Components/HtmlEditor/components/InAppPreviewPane/_inAppPreviewPane.scss +253 -0
- package/v2Components/HtmlEditor/components/InAppPreviewPane/constants.js +104 -0
- package/v2Components/HtmlEditor/components/InAppPreviewPane/index.js +179 -0
- package/v2Components/HtmlEditor/components/PreviewPane/_previewPane.scss +220 -0
- package/v2Components/HtmlEditor/components/PreviewPane/index.js +229 -0
- package/v2Components/HtmlEditor/components/SplitContainer/SplitContainer.js +276 -0
- package/v2Components/HtmlEditor/components/SplitContainer/__tests__/SplitContainer.test.js +295 -0
- package/v2Components/HtmlEditor/components/SplitContainer/_splitContainer.scss +257 -0
- package/v2Components/HtmlEditor/components/SplitContainer/index.js +7 -0
- package/v2Components/HtmlEditor/components/ValidationErrorDisplay/__tests__/index.test.js +152 -0
- package/v2Components/HtmlEditor/components/ValidationErrorDisplay/_validationErrorDisplay.scss +31 -0
- package/v2Components/HtmlEditor/components/ValidationErrorDisplay/index.js +70 -0
- package/v2Components/HtmlEditor/components/ValidationPanel/__tests__/index.test.js +98 -0
- package/v2Components/HtmlEditor/components/ValidationPanel/_validationPanel.scss +311 -0
- package/v2Components/HtmlEditor/components/ValidationPanel/index.js +297 -0
- package/v2Components/HtmlEditor/components/ValidationPanel/messages.js +57 -0
- package/v2Components/HtmlEditor/components/common/EditorContext.js +84 -0
- package/v2Components/HtmlEditor/components/common/__tests__/EditorContext.test.js +660 -0
- package/v2Components/HtmlEditor/constants.js +241 -0
- package/v2Components/HtmlEditor/hooks/__tests__/useEditorContent.test.js +450 -0
- package/v2Components/HtmlEditor/hooks/__tests__/useInAppContent.test.js +785 -0
- package/v2Components/HtmlEditor/hooks/__tests__/useLayoutState.test.js +580 -0
- package/v2Components/HtmlEditor/hooks/__tests__/useValidation.enhanced.test.js +768 -0
- package/v2Components/HtmlEditor/hooks/__tests__/useValidation.test.js +590 -0
- package/v2Components/HtmlEditor/hooks/useEditorContent.js +274 -0
- package/v2Components/HtmlEditor/hooks/useInAppContent.js +407 -0
- package/v2Components/HtmlEditor/hooks/useLayoutState.js +247 -0
- package/v2Components/HtmlEditor/hooks/useValidation.js +325 -0
- package/v2Components/HtmlEditor/index.js +29 -0
- package/v2Components/HtmlEditor/index.lazy.js +114 -0
- package/v2Components/HtmlEditor/messages.js +389 -0
- package/v2Components/HtmlEditor/utils/__tests__/contentSanitizer.test.js +741 -0
- package/v2Components/HtmlEditor/utils/__tests__/htmlValidator.enhanced.test.js +1042 -0
- package/v2Components/HtmlEditor/utils/__tests__/liquidTemplateSupport.test.js +515 -0
- package/v2Components/HtmlEditor/utils/__tests__/properSyntaxHighlighting.test.js +473 -0
- package/v2Components/HtmlEditor/utils/__tests__/simplePerformance.test.js +1109 -0
- package/v2Components/HtmlEditor/utils/__tests__/validationAdapter.test.js +240 -0
- package/v2Components/HtmlEditor/utils/contentSanitizer.js +433 -0
- package/v2Components/HtmlEditor/utils/htmlValidator.js +508 -0
- package/v2Components/HtmlEditor/utils/liquidTemplateSupport.js +524 -0
- package/v2Components/HtmlEditor/utils/properSyntaxHighlighting.js +163 -0
- package/v2Components/HtmlEditor/utils/simplePerformance.js +145 -0
- package/v2Components/HtmlEditor/utils/validationAdapter.js +130 -0
- package/v2Containers/EmailWrapper/components/HTMLEditorTesting.js +200 -0
- package/v2Containers/EmailWrapper/components/__tests__/HTMLEditorTesting.test.js +545 -0
- package/v2Containers/EmailWrapper/index.js +8 -1
- package/v2Containers/Rcs/index.js +2 -0
- package/v2Containers/Templates/constants.js +8 -0
- package/v2Containers/Templates/index.js +56 -28
- package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +5 -14
- 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: <>&"\'</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
|
-
<
|
|
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'
|