@capillarytech/creatives-library 8.0.353-alpha.2 → 8.0.353-alpha.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.
- package/package.json +1 -1
- package/v2Components/CommonTestAndPreview/UnifiedPreview/PreviewHeader.js +17 -0
- package/v2Components/CommonTestAndPreview/UnifiedPreview/WebPushPreviewContent.js +169 -0
- package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +70 -0
- package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +44 -5
- package/v2Components/CommonTestAndPreview/constants.js +2 -0
- package/v2Components/CommonTestAndPreview/index.js +51 -2
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/PreviewHeader.test.js +159 -0
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/WebPushPreviewContent.test.js +522 -0
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +255 -0
- package/v2Components/CommonTestAndPreview/tests/constants.test.js +2 -1
- package/v2Components/CommonTestAndPreview/tests/index.test.js +194 -0
- package/v2Components/FormBuilder/index.js +10 -48
- package/v2Components/TestAndPreviewSlidebox/index.js +2 -2
- package/v2Containers/App/constants.js +3 -0
- package/v2Containers/App/tests/constants.test.js +61 -0
- package/v2Containers/CreativesContainer/index.js +25 -61
- package/v2Containers/Email/index.js +2 -33
- package/v2Containers/Templates/index.js +68 -2
- package/v2Containers/Templates/tests/webpush.test.js +375 -0
- package/v2Containers/WebPush/Create/index.js +91 -8
- package/v2Containers/WebPush/Create/index.scss +7 -0
- package/v2Containers/WebPush/Create/tests/getTemplateContent.test.js +338 -0
- package/v2Containers/WebPush/Create/tests/testAndPreviewIntegration.test.js +325 -0
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration tests for TestAndPreviewSlidebox in WebPushCreate
|
|
3
|
+
*
|
|
4
|
+
* Tests:
|
|
5
|
+
* - Test & Preview button renders and opens the slidebox
|
|
6
|
+
* - handleTestAndPreview sets showTestAndPreviewSlidebox=true
|
|
7
|
+
* - handleCloseTestAndPreview sets showTestAndPreviewSlidebox=false
|
|
8
|
+
* - TestAndPreviewSlidebox receives correct props (currentChannel, accountId, content)
|
|
9
|
+
*
|
|
10
|
+
* Note: all relative mock paths are resolved from THIS test file's location
|
|
11
|
+
* (app/v2Containers/WebPush/Create/tests/), not from the component.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import React from 'react';
|
|
15
|
+
import { render, screen, fireEvent } from '@testing-library/react';
|
|
16
|
+
import '@testing-library/jest-dom';
|
|
17
|
+
import { IntlProvider } from 'react-intl';
|
|
18
|
+
|
|
19
|
+
// ── Infrastructure / HOC mocks ──────────────────────────────────────────────
|
|
20
|
+
jest.mock('../../../../hoc/withCreatives', () => ({
|
|
21
|
+
__esModule: true,
|
|
22
|
+
default: ({ WrappedComponent }) => WrappedComponent,
|
|
23
|
+
}));
|
|
24
|
+
|
|
25
|
+
jest.mock('@capillarytech/vulcan-react-sdk/utils', () => ({
|
|
26
|
+
injectReducer: () => (Component) => Component,
|
|
27
|
+
injectSaga: () => (Component) => Component,
|
|
28
|
+
}));
|
|
29
|
+
jest.mock('@capillarytech/vulcan-react-sdk/utils/sagaInjectorTypes', () => ({
|
|
30
|
+
DAEMON: 'DAEMON',
|
|
31
|
+
}));
|
|
32
|
+
|
|
33
|
+
// ── Redux slices (paths relative to this test file) ─────────────────────────
|
|
34
|
+
jest.mock('../../../Templates/selectors', () => ({
|
|
35
|
+
makeSelectTemplates: () => () => {},
|
|
36
|
+
}));
|
|
37
|
+
jest.mock('../../../Templates/actions', () => ({}));
|
|
38
|
+
jest.mock('../../selectors', () => ({
|
|
39
|
+
makeSelectWebPush: () => () => ({}),
|
|
40
|
+
makeSelectCreateError: () => () => null,
|
|
41
|
+
makeSelectCreateTemplateInProgress: () => () => false,
|
|
42
|
+
makeSelectEditTemplateInProgress: () => () => false,
|
|
43
|
+
makeSelectEditError: () => () => null,
|
|
44
|
+
}));
|
|
45
|
+
jest.mock('../../actions', () => ({}));
|
|
46
|
+
jest.mock('../../reducer', () => () => ({}));
|
|
47
|
+
jest.mock('../../sagas', () => ({}));
|
|
48
|
+
jest.mock('../../../Templates/sagas', () => ({ v2TemplateSaga: {} }));
|
|
49
|
+
jest.mock('../../../Cap/selectors', () => ({
|
|
50
|
+
makeSelectMetaEntities: () => () => [],
|
|
51
|
+
setInjectedTags: () => () => [],
|
|
52
|
+
}));
|
|
53
|
+
jest.mock('../../../CreativesContainer/constants', () => ({
|
|
54
|
+
WEBPUSH: 'WEBPUSH',
|
|
55
|
+
}));
|
|
56
|
+
jest.mock('../../../CreativesContainer/messages', () => ({
|
|
57
|
+
testAndPreview: { id: 'testAndPreview', defaultMessage: 'Test & Preview' },
|
|
58
|
+
}));
|
|
59
|
+
jest.mock('../../../../utils/common', () => ({
|
|
60
|
+
isAiContentBotDisabled: () => false,
|
|
61
|
+
}));
|
|
62
|
+
|
|
63
|
+
// ── Form section components ──────────────────────────────────────────────────
|
|
64
|
+
jest.mock('../components/TemplateNameSection', () => ({
|
|
65
|
+
__esModule: true,
|
|
66
|
+
default: () => <div data-testid="template-name-section" />,
|
|
67
|
+
}));
|
|
68
|
+
jest.mock('../components/NotificationTitleSection', () => ({
|
|
69
|
+
__esModule: true,
|
|
70
|
+
default: () => <div data-testid="notification-title-section" />,
|
|
71
|
+
}));
|
|
72
|
+
jest.mock('../components/MessageSection', () => ({
|
|
73
|
+
__esModule: true,
|
|
74
|
+
default: () => <div data-testid="message-section" />,
|
|
75
|
+
}));
|
|
76
|
+
jest.mock('../components/MediaSection', () => ({
|
|
77
|
+
__esModule: true,
|
|
78
|
+
default: () => <div data-testid="media-section" />,
|
|
79
|
+
}));
|
|
80
|
+
jest.mock('../components/BrandIconSection', () => ({
|
|
81
|
+
__esModule: true,
|
|
82
|
+
default: () => <div data-testid="brand-icon-section" />,
|
|
83
|
+
}));
|
|
84
|
+
jest.mock('../components/ButtonsLinksSection', () => ({
|
|
85
|
+
__esModule: true,
|
|
86
|
+
default: () => <div data-testid="buttons-links-section" />,
|
|
87
|
+
}));
|
|
88
|
+
jest.mock('../components/FormActions', () => ({
|
|
89
|
+
__esModule: true,
|
|
90
|
+
default: () => <div data-testid="form-actions" />,
|
|
91
|
+
}));
|
|
92
|
+
jest.mock('../preview/WebPushPreview', () => ({
|
|
93
|
+
__esModule: true,
|
|
94
|
+
default: () => <div data-testid="webpush-preview" />,
|
|
95
|
+
}));
|
|
96
|
+
jest.mock('../../../TagList', () => ({
|
|
97
|
+
__esModule: true,
|
|
98
|
+
default: () => <div data-testid="tag-list" />,
|
|
99
|
+
}));
|
|
100
|
+
|
|
101
|
+
// ── Hooks ────────────────────────────────────────────────────────────────────
|
|
102
|
+
jest.mock('../hooks/useCharacterCount', () => ({
|
|
103
|
+
useCharacterCount: () => ({ updateCharacterCount: jest.fn() }),
|
|
104
|
+
}));
|
|
105
|
+
jest.mock('../hooks/useButtonManagement', () => ({
|
|
106
|
+
useButtonManagement: () => ({ buttons: [], setButtons: jest.fn() }),
|
|
107
|
+
}));
|
|
108
|
+
jest.mock('../hooks/useImageUpload', () => ({
|
|
109
|
+
useImageUpload: () => ({
|
|
110
|
+
imageSrc: '',
|
|
111
|
+
imageUrl: '',
|
|
112
|
+
isValidating: false,
|
|
113
|
+
isUploading: false,
|
|
114
|
+
setImageSrc: jest.fn(),
|
|
115
|
+
setImageUrl: jest.fn(),
|
|
116
|
+
}),
|
|
117
|
+
}));
|
|
118
|
+
jest.mock('../hooks/useTagManagement', () => ({
|
|
119
|
+
useTagManagement: () => ({ tags: [], extractTags: jest.fn() }),
|
|
120
|
+
}));
|
|
121
|
+
|
|
122
|
+
// ── Capture TestAndPreviewSlidebox props ─────────────────────────────────────
|
|
123
|
+
let capturedSlideboxProps = {};
|
|
124
|
+
jest.mock('../../../../v2Components/TestAndPreviewSlidebox', () => ({
|
|
125
|
+
__esModule: true,
|
|
126
|
+
default: (props) => {
|
|
127
|
+
capturedSlideboxProps = props;
|
|
128
|
+
return (
|
|
129
|
+
<div data-testid="test-and-preview-slidebox" data-show={props.show ? 'true' : 'false'}>
|
|
130
|
+
{props.show && <div data-testid="slidebox-open">Slidebox Open</div>}
|
|
131
|
+
<button data-testid="slidebox-close-btn" onClick={props.onClose}>
|
|
132
|
+
Close
|
|
133
|
+
</button>
|
|
134
|
+
</div>
|
|
135
|
+
);
|
|
136
|
+
},
|
|
137
|
+
}));
|
|
138
|
+
|
|
139
|
+
// ── CapUI library ─────────────────────────────────────────────────────────────
|
|
140
|
+
jest.mock('@capillarytech/cap-ui-library/CapRow', () => ({
|
|
141
|
+
__esModule: true,
|
|
142
|
+
default: ({ children, className }) => <div className={className}>{children}</div>,
|
|
143
|
+
}));
|
|
144
|
+
jest.mock('@capillarytech/cap-ui-library/CapColumn', () => ({
|
|
145
|
+
__esModule: true,
|
|
146
|
+
default: ({ children, className }) => <div className={className}>{children}</div>,
|
|
147
|
+
}));
|
|
148
|
+
jest.mock('@capillarytech/cap-ui-library/CapButton', () => ({
|
|
149
|
+
__esModule: true,
|
|
150
|
+
default: ({ children, onClick, className, type }) => (
|
|
151
|
+
<button className={className} onClick={onClick} data-type={type}>
|
|
152
|
+
{children}
|
|
153
|
+
</button>
|
|
154
|
+
),
|
|
155
|
+
}));
|
|
156
|
+
|
|
157
|
+
// ── Import component AFTER mocks ─────────────────────────────────────────────
|
|
158
|
+
// eslint-disable-next-line import/first
|
|
159
|
+
import WebPushCreateDefault from '../index';
|
|
160
|
+
|
|
161
|
+
const baseProps = {
|
|
162
|
+
isFullMode: false,
|
|
163
|
+
handleClose: jest.fn(),
|
|
164
|
+
webPushActions: {
|
|
165
|
+
createTemplate: jest.fn(),
|
|
166
|
+
editTemplate: jest.fn(),
|
|
167
|
+
uploadImage: jest.fn(),
|
|
168
|
+
clearCreateError: jest.fn(),
|
|
169
|
+
clearEditError: jest.fn(),
|
|
170
|
+
clearCreateResponse: jest.fn(),
|
|
171
|
+
clearEditResponse: jest.fn(),
|
|
172
|
+
setSelectedAccount: jest.fn(),
|
|
173
|
+
clearState: jest.fn(),
|
|
174
|
+
},
|
|
175
|
+
createTemplateInProgress: false,
|
|
176
|
+
createTemplateError: null,
|
|
177
|
+
editTemplateInProgress: false,
|
|
178
|
+
editTemplateError: null,
|
|
179
|
+
accountData: null,
|
|
180
|
+
webPush: {},
|
|
181
|
+
onCreateComplete: jest.fn(),
|
|
182
|
+
getFormData: jest.fn(),
|
|
183
|
+
isGetFormData: false,
|
|
184
|
+
templateData: null,
|
|
185
|
+
creativesMode: 'create',
|
|
186
|
+
params: {},
|
|
187
|
+
globalActions: { getMetaEntities: jest.fn() },
|
|
188
|
+
location: { pathname: '/webpush', query: {}, search: '', state: {} },
|
|
189
|
+
metaEntities: [],
|
|
190
|
+
injectedTags: [],
|
|
191
|
+
getDefaultTags: jest.fn(),
|
|
192
|
+
supportedTags: [],
|
|
193
|
+
forwardedTags: [],
|
|
194
|
+
selectedOfferDetails: [],
|
|
195
|
+
eventContextTags: [],
|
|
196
|
+
waitEventContextTags: {},
|
|
197
|
+
templateActions: {},
|
|
198
|
+
Templates: { templates: [] },
|
|
199
|
+
restrictPersonalization: false,
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
const TestWrapper = ({ children }) => (
|
|
203
|
+
<IntlProvider locale="en" messages={{ testAndPreview: 'Test & Preview' }}>
|
|
204
|
+
{children}
|
|
205
|
+
</IntlProvider>
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
describe('WebPushCreate - Test & Preview integration', () => {
|
|
209
|
+
beforeEach(() => {
|
|
210
|
+
jest.clearAllMocks();
|
|
211
|
+
capturedSlideboxProps = {};
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it('should render the Test & Preview button', () => {
|
|
215
|
+
render(
|
|
216
|
+
<TestWrapper>
|
|
217
|
+
<WebPushCreateDefault {...baseProps} />
|
|
218
|
+
</TestWrapper>
|
|
219
|
+
);
|
|
220
|
+
|
|
221
|
+
expect(screen.getByText('Test & Preview')).toBeTruthy();
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
it('should render TestAndPreviewSlidebox with show=false initially', () => {
|
|
225
|
+
render(
|
|
226
|
+
<TestWrapper>
|
|
227
|
+
<WebPushCreateDefault {...baseProps} />
|
|
228
|
+
</TestWrapper>
|
|
229
|
+
);
|
|
230
|
+
|
|
231
|
+
const slidebox = screen.getByTestId('test-and-preview-slidebox');
|
|
232
|
+
expect(slidebox.getAttribute('data-show')).toBe('false');
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
it('should open TestAndPreviewSlidebox when Test & Preview button is clicked', () => {
|
|
236
|
+
render(
|
|
237
|
+
<TestWrapper>
|
|
238
|
+
<WebPushCreateDefault {...baseProps} />
|
|
239
|
+
</TestWrapper>
|
|
240
|
+
);
|
|
241
|
+
|
|
242
|
+
fireEvent.click(screen.getByText('Test & Preview'));
|
|
243
|
+
|
|
244
|
+
const slidebox = screen.getByTestId('test-and-preview-slidebox');
|
|
245
|
+
expect(slidebox.getAttribute('data-show')).toBe('true');
|
|
246
|
+
expect(screen.getByTestId('slidebox-open')).toBeTruthy();
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
it('should close TestAndPreviewSlidebox when onClose is called', () => {
|
|
250
|
+
render(
|
|
251
|
+
<TestWrapper>
|
|
252
|
+
<WebPushCreateDefault {...baseProps} />
|
|
253
|
+
</TestWrapper>
|
|
254
|
+
);
|
|
255
|
+
|
|
256
|
+
// Open it
|
|
257
|
+
fireEvent.click(screen.getByText('Test & Preview'));
|
|
258
|
+
expect(screen.getByTestId('test-and-preview-slidebox').getAttribute('data-show')).toBe('true');
|
|
259
|
+
|
|
260
|
+
// Close it
|
|
261
|
+
fireEvent.click(screen.getByTestId('slidebox-close-btn'));
|
|
262
|
+
expect(screen.getByTestId('test-and-preview-slidebox').getAttribute('data-show')).toBe('false');
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
it('should pass currentChannel="WEBPUSH" to TestAndPreviewSlidebox', () => {
|
|
266
|
+
render(
|
|
267
|
+
<TestWrapper>
|
|
268
|
+
<WebPushCreateDefault {...baseProps} />
|
|
269
|
+
</TestWrapper>
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
expect(capturedSlideboxProps.currentChannel).toBe('WEBPUSH');
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
it('should pass null accountId when accountData is null', () => {
|
|
276
|
+
render(
|
|
277
|
+
<TestWrapper>
|
|
278
|
+
<WebPushCreateDefault {...baseProps} accountData={null} />
|
|
279
|
+
</TestWrapper>
|
|
280
|
+
);
|
|
281
|
+
|
|
282
|
+
expect(capturedSlideboxProps.accountId).toBeNull();
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
it('should pass content object with channel WEBPUSH to TestAndPreviewSlidebox', () => {
|
|
286
|
+
render(
|
|
287
|
+
<TestWrapper>
|
|
288
|
+
<WebPushCreateDefault {...baseProps} />
|
|
289
|
+
</TestWrapper>
|
|
290
|
+
);
|
|
291
|
+
|
|
292
|
+
expect(capturedSlideboxProps.content).toBeDefined();
|
|
293
|
+
expect(capturedSlideboxProps.content.channel).toBe('WEBPUSH');
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
it('should pass content with offers array to TestAndPreviewSlidebox', () => {
|
|
297
|
+
render(
|
|
298
|
+
<TestWrapper>
|
|
299
|
+
<WebPushCreateDefault {...baseProps} />
|
|
300
|
+
</TestWrapper>
|
|
301
|
+
);
|
|
302
|
+
|
|
303
|
+
expect(capturedSlideboxProps.content.offers).toEqual([]);
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
it('should pass onClose handler to TestAndPreviewSlidebox', () => {
|
|
307
|
+
render(
|
|
308
|
+
<TestWrapper>
|
|
309
|
+
<WebPushCreateDefault {...baseProps} />
|
|
310
|
+
</TestWrapper>
|
|
311
|
+
);
|
|
312
|
+
|
|
313
|
+
expect(typeof capturedSlideboxProps.onClose).toBe('function');
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
it('should pass show=false to TestAndPreviewSlidebox before button click', () => {
|
|
317
|
+
render(
|
|
318
|
+
<TestWrapper>
|
|
319
|
+
<WebPushCreateDefault {...baseProps} />
|
|
320
|
+
</TestWrapper>
|
|
321
|
+
);
|
|
322
|
+
|
|
323
|
+
expect(capturedSlideboxProps.show).toBe(false);
|
|
324
|
+
});
|
|
325
|
+
});
|