@capillarytech/creatives-library 8.0.345-alpha.12 → 8.0.345-alpha.13
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/constants/unified.js +0 -29
- package/package.json +1 -1
- package/services/api.js +20 -0
- package/services/tests/api.test.js +59 -13
- package/utils/commonUtils.js +1 -19
- package/v2Components/CapActionButton/constants.js +0 -7
- package/v2Components/CapActionButton/index.js +109 -167
- package/v2Components/CapActionButton/index.scss +6 -157
- package/v2Components/CapActionButton/messages.js +3 -19
- package/v2Components/CapActionButton/tests/index.test.js +17 -41
- package/v2Components/CapCustomSkeleton/index.js +1 -1
- package/v2Components/CapCustomSkeleton/tests/__snapshots__/index.test.js.snap +12 -12
- package/v2Components/CapTagList/index.js +0 -10
- package/v2Components/CommonTestAndPreview/CustomValuesEditor.js +49 -70
- package/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +2 -8
- package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +21 -207
- package/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +0 -16
- package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +10 -85
- package/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +0 -30
- package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +11 -79
- package/v2Components/CommonTestAndPreview/SendTestMessage.js +5 -10
- package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js +15 -160
- package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +76 -341
- package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +4 -133
- package/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +0 -11
- package/v2Components/CommonTestAndPreview/constants.js +2 -38
- package/v2Components/CommonTestAndPreview/index.js +186 -676
- package/v2Components/CommonTestAndPreview/messages.js +3 -49
- package/v2Components/CommonTestAndPreview/sagas.js +6 -15
- package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +284 -308
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +65 -231
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/index.test.js +5 -118
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +0 -341
- package/v2Components/CommonTestAndPreview/tests/PreviewSection.test.js +1 -8
- package/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +13 -34
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/RcsPreviewContent.test.js +283 -281
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +1 -199
- package/v2Components/CommonTestAndPreview/tests/index.test.js +4 -132
- package/v2Components/CommonTestAndPreview/tests/sagas.test.js +2 -2
- package/v2Components/FormBuilder/index.js +10 -8
- package/v2Components/TemplatePreview/_templatePreview.scss +23 -33
- package/v2Components/TemplatePreview/index.js +28 -143
- package/v2Components/TemplatePreview/tests/index.test.js +0 -142
- package/v2Components/TestAndPreviewSlidebox/index.js +1 -13
- package/v2Components/TestAndPreviewSlidebox/sagas.js +4 -11
- package/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +1 -3
- package/v2Containers/Assets/images/archive_Empty_Illustration.svg +9 -0
- package/v2Containers/CreativesContainer/SlideBoxContent.js +4 -36
- package/v2Containers/CreativesContainer/SlideBoxFooter.js +4 -11
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +4 -29
- package/v2Containers/CreativesContainer/constants.js +0 -9
- package/v2Containers/CreativesContainer/index.js +108 -300
- package/v2Containers/CreativesContainer/index.scss +1 -51
- package/v2Containers/CreativesContainer/messages.js +4 -0
- package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +34 -78
- package/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +16 -79
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +0 -8
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +98 -357
- package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +18 -20
- package/v2Containers/CreativesContainer/tests/index.test.js +9 -71
- package/v2Containers/Rcs/constants.js +8 -119
- package/v2Containers/Rcs/index.js +812 -2375
- package/v2Containers/Rcs/index.scss +6 -276
- package/v2Containers/Rcs/messages.js +3 -38
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +70345 -98302
- package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +5 -0
- package/v2Containers/Rcs/tests/index.test.js +121 -152
- package/v2Containers/Rcs/tests/mockData.js +0 -38
- package/v2Containers/Rcs/tests/utils.test.js +30 -646
- package/v2Containers/Rcs/utils.js +11 -478
- package/v2Containers/Sms/Create/index.js +40 -100
- package/v2Containers/SmsTrai/Create/index.js +4 -9
- package/v2Containers/SmsTrai/Edit/constants.js +0 -2
- package/v2Containers/SmsTrai/Edit/index.js +130 -636
- package/v2Containers/SmsTrai/Edit/messages.js +4 -14
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +2296 -4249
- package/v2Containers/SmsWrapper/index.js +8 -37
- package/v2Containers/TagList/index.js +0 -6
- package/v2Containers/Templates/ChannelTypeIllustration.js +23 -6
- package/v2Containers/Templates/_templates.scss +126 -181
- package/v2Containers/Templates/actions.js +36 -11
- package/v2Containers/Templates/constants.js +23 -2
- package/v2Containers/Templates/index.js +333 -142
- package/v2Containers/Templates/messages.js +68 -0
- package/v2Containers/Templates/reducer.js +68 -0
- package/v2Containers/Templates/sagas.js +98 -55
- package/v2Containers/Templates/selectors.js +12 -0
- package/v2Containers/Templates/tests/ChannelTypeIllustration.test.js +12 -0
- package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1256 -1042
- package/v2Containers/Templates/tests/index.test.js +6 -0
- package/v2Containers/Templates/tests/reducer.test.js +178 -0
- package/v2Containers/Templates/tests/sagas.test.js +436 -200
- package/v2Containers/Templates/tests/selector.test.js +32 -0
- package/v2Containers/TemplatesV2/TemplatesV2.style.js +1 -72
- package/v2Containers/TemplatesV2/index.js +23 -86
- package/v2Containers/Whatsapp/index.js +20 -3
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +34 -578
- package/utils/rcsPayloadUtils.js +0 -92
- package/utils/templateVarUtils.js +0 -201
- package/utils/tests/templateVarUtils.test.js +0 -204
- package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js.rej +0 -18
- package/v2Components/CommonTestAndPreview/previewApiUtils.js +0 -59
- package/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +0 -67
- package/v2Components/SmsFallback/SmsFallbackLocalSelector.js +0 -87
- package/v2Components/SmsFallback/constants.js +0 -73
- package/v2Components/SmsFallback/index.js +0 -955
- package/v2Components/SmsFallback/index.scss +0 -265
- package/v2Components/SmsFallback/messages.js +0 -78
- package/v2Components/SmsFallback/smsFallbackUtils.js +0 -118
- package/v2Components/SmsFallback/tests/SmsFallbackLocalSelector.test.js +0 -50
- package/v2Components/SmsFallback/tests/rcsSmsFallback.acceptance.test.js +0 -147
- package/v2Components/SmsFallback/tests/smsFallbackHandlers.test.js +0 -304
- package/v2Components/SmsFallback/tests/smsFallbackUi.test.js +0 -197
- package/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +0 -277
- package/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +0 -422
- package/v2Components/SmsFallback/useLocalTemplateList.js +0 -92
- package/v2Components/TemplatePreview/constants.js +0 -2
- package/v2Components/VarSegmentMessageEditor/constants.js +0 -2
- package/v2Components/VarSegmentMessageEditor/index.js +0 -125
- package/v2Components/VarSegmentMessageEditor/index.scss +0 -46
- package/v2Containers/CreativesContainer/CreativesSlideBoxWrapper.js +0 -43
- package/v2Containers/CreativesContainer/embeddedSlideboxUtils.js +0 -67
- package/v2Containers/CreativesContainer/tests/SlideBoxContent.localTemplates.test.js +0 -90
- package/v2Containers/CreativesContainer/tests/embeddedSlideboxUtils.test.js +0 -258
- package/v2Containers/CreativesContainer/tests/useLocalTemplatesProp.test.js +0 -125
- package/v2Containers/Rcs/index.js.rej +0 -1336
- package/v2Containers/Rcs/index.scss.rej +0 -74
- package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +0 -225
- package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap.rej +0 -128
- package/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +0 -318
- package/v2Containers/Sms/smsFormDataHelpers.js +0 -67
- package/v2Containers/Sms/tests/smsFormDataHelpers.test.js +0 -253
- package/v2Containers/SmsTrai/Edit/index.scss +0 -121
- package/v2Containers/Templates/TemplatesActionBar.js +0 -101
- package/v2Containers/Templates/tests/TemplatesActionBar.test.js +0 -120
- package/v2Containers/Templates/tests/smsTemplatesListApi.test.js +0 -180
- package/v2Containers/Templates/utils/smsTemplatesListApi.js +0 -79
- package/v2Containers/TemplatesV2/tests/TemplatesV2.localTemplates.test.js +0 -131
|
@@ -1,22 +1,20 @@
|
|
|
1
1
|
import { expectSaga } from 'redux-saga-test-plan';
|
|
2
|
-
import {
|
|
3
|
-
take, call, takeLatest, takeEvery, put,
|
|
4
|
-
} from 'redux-saga/effects';
|
|
5
2
|
import * as matchers from 'redux-saga-test-plan/matchers';
|
|
3
|
+
import { throwError } from 'redux-saga-test-plan/providers';
|
|
4
|
+
import { call, takeLatest, put } from 'redux-saga/effects';
|
|
6
5
|
import * as api from '../../../services/api';
|
|
7
6
|
import * as types from '../constants';
|
|
8
7
|
import * as cdnUtils from '../../../utils/cdnTransformation';
|
|
9
|
-
|
|
10
8
|
import {
|
|
11
9
|
getCdnTransformationConfig,
|
|
12
10
|
getAllTemplates,
|
|
13
|
-
getLocalSmsTemplates,
|
|
14
11
|
watchGetCdnTransformationConfig,
|
|
15
12
|
watchGetAllTemplates,
|
|
16
13
|
getSenderDetails,
|
|
17
14
|
fetchWeCrmAccounts,
|
|
18
15
|
sendZippedFile,
|
|
19
16
|
fetchUserList,
|
|
17
|
+
watchGetUserList,
|
|
20
18
|
deleteRcsTemplate,
|
|
21
19
|
watchDeleteRcsTemplate,
|
|
22
20
|
watchForGetTemplateInfoById,
|
|
@@ -30,14 +28,30 @@ import {
|
|
|
30
28
|
watchGetOrgLevelCampaignSettings,
|
|
31
29
|
watchSendingFile,
|
|
32
30
|
watchFetchWeCrmAccounts,
|
|
31
|
+
watchGetSenderDetails,
|
|
32
|
+
v2TemplateSaga,
|
|
33
|
+
v2TemplateSagaWatchGetDefaultBeeTemplates,
|
|
34
|
+
archiveTemplateSaga,
|
|
35
|
+
unarchiveTemplateSaga,
|
|
36
|
+
bulkArchiveTemplatesSaga,
|
|
37
|
+
bulkUnarchiveTemplatesSaga,
|
|
38
|
+
watchArchiveTemplate,
|
|
39
|
+
watchUnarchiveTemplate,
|
|
40
|
+
watchBulkArchive,
|
|
41
|
+
watchBulkUnarchive,
|
|
33
42
|
} from '../sagas';
|
|
34
|
-
|
|
35
|
-
import * as mockData from './mockData';
|
|
36
|
-
import { fetchSmsTemplatesFromQuery } from '../utils/smsTemplatesListApi';
|
|
37
|
-
import { ZALO } from '../../CreativesContainer/constants';
|
|
38
|
-
import { VIET_GUYS, ZALO_TEMPLATE_INFO_REQUEST } from '../../Zalo/constants';
|
|
39
|
-
import { throwError } from 'redux-saga-test-plan/providers';
|
|
40
43
|
import { getTemplateInfoById } from '../../Zalo/saga';
|
|
44
|
+
import { ZALO_TEMPLATE_INFO_REQUEST } from '../../Zalo/constants';
|
|
45
|
+
import * as mockData from './mockData';
|
|
46
|
+
|
|
47
|
+
jest.mock('@capillarytech/cap-ui-library', () => ({
|
|
48
|
+
CapNotification: {
|
|
49
|
+
success: jest.fn(),
|
|
50
|
+
error: jest.fn(),
|
|
51
|
+
warning: jest.fn(),
|
|
52
|
+
info: jest.fn(),
|
|
53
|
+
},
|
|
54
|
+
}));
|
|
41
55
|
|
|
42
56
|
describe('getCdnTransformationConfig saga', () => {
|
|
43
57
|
it("handle valid response from api", () => {
|
|
@@ -136,8 +150,8 @@ describe('templateList saga', () => {
|
|
|
136
150
|
],
|
|
137
151
|
]).put({
|
|
138
152
|
type: types.GET_ALL_TEMPLATES_SUCCESS,
|
|
139
|
-
data: mockData.getAllTemplatesListSuccess
|
|
140
|
-
weCRMTemplate: mockData.getAllTemplatesListSuccess
|
|
153
|
+
data: mockData.getAllTemplatesListSuccess,
|
|
154
|
+
weCRMTemplate: mockData.getAllTemplatesListSuccess,
|
|
141
155
|
isReset: mockData.getAllTemplatesListSuccess?.queryParams?.page === 1,
|
|
142
156
|
})
|
|
143
157
|
.run();
|
|
@@ -153,8 +167,8 @@ describe('templateList saga', () => {
|
|
|
153
167
|
],
|
|
154
168
|
]).put({
|
|
155
169
|
type: types.GET_ALL_TEMPLATES_SUCCESS,
|
|
156
|
-
data: mockData.getAllTemplatesListSuccess
|
|
157
|
-
weCRMTemplate: mockData.getAllTemplatesListSuccess
|
|
170
|
+
data: mockData.getAllTemplatesListSuccess,
|
|
171
|
+
weCRMTemplate: mockData.getAllTemplatesListSuccess,
|
|
158
172
|
isReset: mockData.getAllTemplatesListSuccess?.queryParams?.page === 1,
|
|
159
173
|
})
|
|
160
174
|
.run();
|
|
@@ -173,163 +187,6 @@ describe('templateList saga', () => {
|
|
|
173
187
|
})
|
|
174
188
|
.run();
|
|
175
189
|
});
|
|
176
|
-
|
|
177
|
-
it('SMS channel uses fetchSmsTemplatesFromQuery', () => {
|
|
178
|
-
const smsAction = {
|
|
179
|
-
type: types.GET_ALL_TEMPLATES_REQUEST,
|
|
180
|
-
channel: 'Sms',
|
|
181
|
-
queryParams: { page: 1, perPage: 25, name: '', sortBy: 'Most Recent' },
|
|
182
|
-
intlCopyOf: 'Kopie',
|
|
183
|
-
};
|
|
184
|
-
const fetched = {
|
|
185
|
-
channelTemplates: { templates: [{ name: 'Kopie Foo' }], totalCount: 1 },
|
|
186
|
-
weCRMTemplate: undefined,
|
|
187
|
-
raw: {},
|
|
188
|
-
};
|
|
189
|
-
return expectSaga(getAllTemplates, smsAction)
|
|
190
|
-
.provide([
|
|
191
|
-
[call(fetchSmsTemplatesFromQuery, smsAction.queryParams, smsAction.intlCopyOf), fetched],
|
|
192
|
-
])
|
|
193
|
-
.put({
|
|
194
|
-
type: types.GET_ALL_TEMPLATES_SUCCESS,
|
|
195
|
-
data: fetched.channelTemplates,
|
|
196
|
-
weCRMTemplate: fetched.weCRMTemplate,
|
|
197
|
-
isReset: true,
|
|
198
|
-
})
|
|
199
|
-
.run();
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
it('SMS channel propagates fetchSmsTemplatesFromQuery errors', () => {
|
|
203
|
-
const smsAction = {
|
|
204
|
-
type: types.GET_ALL_TEMPLATES_REQUEST,
|
|
205
|
-
channel: 'SMS',
|
|
206
|
-
queryParams: { page: 2, perPage: 25 },
|
|
207
|
-
intlCopyOf: '',
|
|
208
|
-
};
|
|
209
|
-
const error = new Error('sms list fail');
|
|
210
|
-
return expectSaga(getAllTemplates, smsAction)
|
|
211
|
-
.provide([
|
|
212
|
-
[call(fetchSmsTemplatesFromQuery, smsAction.queryParams, smsAction.intlCopyOf), throwError(error)],
|
|
213
|
-
])
|
|
214
|
-
.put({
|
|
215
|
-
type: types.GET_ALL_TEMPLATES_FAILURE,
|
|
216
|
-
error,
|
|
217
|
-
})
|
|
218
|
-
.run();
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
it('wechat channel merges mapped and richmedia and applies Most Recent sort', () => {
|
|
222
|
-
const wechatApiResponse = {
|
|
223
|
-
response: {
|
|
224
|
-
mapped: [
|
|
225
|
-
{ name: 'B', updatedAt: '2024-01-02T00:00:00Z' },
|
|
226
|
-
{ name: 'A', updatedAt: '2024-01-01T00:00:00Z' },
|
|
227
|
-
],
|
|
228
|
-
richmedia: [{ name: 'C', updatedAt: '2024-01-03T00:00:00Z' }],
|
|
229
|
-
unMapped: [],
|
|
230
|
-
},
|
|
231
|
-
};
|
|
232
|
-
const action = {
|
|
233
|
-
channel: 'wechat',
|
|
234
|
-
queryParams: { sortBy: 'Most Recent', page: 1 },
|
|
235
|
-
intlCopyOf: '',
|
|
236
|
-
};
|
|
237
|
-
return expectSaga(getAllTemplates, action)
|
|
238
|
-
.provide([[matchers.call.fn(api.getAllTemplates), wechatApiResponse]])
|
|
239
|
-
.put.actionType(types.GET_ALL_TEMPLATES_SUCCESS)
|
|
240
|
-
.run();
|
|
241
|
-
});
|
|
242
|
-
|
|
243
|
-
it('wechat channel applies Alphabetically sort', () => {
|
|
244
|
-
const wechatApiResponse = {
|
|
245
|
-
response: {
|
|
246
|
-
mapped: [{ name: 'Zebra', updatedAt: '2024-01-02T00:00:00Z' }],
|
|
247
|
-
richmedia: [{ name: 'Apple', updatedAt: '2024-01-01T00:00:00Z' }],
|
|
248
|
-
unMapped: [],
|
|
249
|
-
},
|
|
250
|
-
};
|
|
251
|
-
const action = {
|
|
252
|
-
channel: 'wechat',
|
|
253
|
-
queryParams: { sortBy: 'Alphabetically', page: 1 },
|
|
254
|
-
intlCopyOf: '',
|
|
255
|
-
};
|
|
256
|
-
return expectSaga(getAllTemplates, action)
|
|
257
|
-
.provide([[matchers.call.fn(api.getAllTemplates), wechatApiResponse]])
|
|
258
|
-
.put.actionType(types.GET_ALL_TEMPLATES_SUCCESS)
|
|
259
|
-
.run();
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
it('wechat channel replaces Copy-of prefix when intlCopyOf is set', () => {
|
|
263
|
-
const wechatApiResponse = {
|
|
264
|
-
response: {
|
|
265
|
-
mapped: [{ name: 'Copy of Promo', updatedAt: '2024-01-01T00:00:00Z' }],
|
|
266
|
-
richmedia: [],
|
|
267
|
-
unMapped: [],
|
|
268
|
-
},
|
|
269
|
-
};
|
|
270
|
-
const action = {
|
|
271
|
-
channel: 'wechat',
|
|
272
|
-
queryParams: { page: 1 },
|
|
273
|
-
intlCopyOf: 'Kopia av ',
|
|
274
|
-
};
|
|
275
|
-
return expectSaga(getAllTemplates, action)
|
|
276
|
-
.provide([[matchers.call.fn(api.getAllTemplates), wechatApiResponse]])
|
|
277
|
-
.put.actionType(types.GET_ALL_TEMPLATES_SUCCESS)
|
|
278
|
-
.run();
|
|
279
|
-
});
|
|
280
|
-
});
|
|
281
|
-
|
|
282
|
-
describe('getLocalSmsTemplates saga', () => {
|
|
283
|
-
it('invokes onSuccess with fetched data', () => {
|
|
284
|
-
const onSuccess = jest.fn();
|
|
285
|
-
const action = {
|
|
286
|
-
queryParams: { page: 1 },
|
|
287
|
-
intlCopyOf: '',
|
|
288
|
-
onSuccess,
|
|
289
|
-
};
|
|
290
|
-
const fetched = { channelTemplates: { templates: [] }, raw: {} };
|
|
291
|
-
return expectSaga(getLocalSmsTemplates, action)
|
|
292
|
-
.provide([[call(fetchSmsTemplatesFromQuery, action.queryParams, action.intlCopyOf), fetched]])
|
|
293
|
-
.call(onSuccess, fetched)
|
|
294
|
-
.run();
|
|
295
|
-
});
|
|
296
|
-
|
|
297
|
-
it('invokes onFailure when fetch throws', () => {
|
|
298
|
-
const onFailure = jest.fn();
|
|
299
|
-
const error = new Error('local list fail');
|
|
300
|
-
const action = {
|
|
301
|
-
queryParams: { page: 1 },
|
|
302
|
-
intlCopyOf: 'Kopie',
|
|
303
|
-
onFailure,
|
|
304
|
-
};
|
|
305
|
-
return expectSaga(getLocalSmsTemplates, action)
|
|
306
|
-
.provide([
|
|
307
|
-
[call(fetchSmsTemplatesFromQuery, action.queryParams, action.intlCopyOf), throwError(error)],
|
|
308
|
-
])
|
|
309
|
-
.call(onFailure, error)
|
|
310
|
-
.run();
|
|
311
|
-
});
|
|
312
|
-
|
|
313
|
-
it('does not throw when callbacks are omitted', () => {
|
|
314
|
-
const action = { queryParams: { page: 1 }, intlCopyOf: '' };
|
|
315
|
-
return expectSaga(getLocalSmsTemplates, action)
|
|
316
|
-
.provide([
|
|
317
|
-
[call(fetchSmsTemplatesFromQuery, action.queryParams, action.intlCopyOf), throwError(new Error('x'))],
|
|
318
|
-
])
|
|
319
|
-
.run();
|
|
320
|
-
});
|
|
321
|
-
|
|
322
|
-
it('does not call onSuccess when it is not a function', () => {
|
|
323
|
-
const action = {
|
|
324
|
-
queryParams: { page: 1 },
|
|
325
|
-
intlCopyOf: '',
|
|
326
|
-
onSuccess: 'not-a-fn',
|
|
327
|
-
};
|
|
328
|
-
const fetched = { channelTemplates: { templates: [] } };
|
|
329
|
-
return expectSaga(getLocalSmsTemplates, action)
|
|
330
|
-
.provide([[call(fetchSmsTemplatesFromQuery, action.queryParams, action.intlCopyOf), fetched]])
|
|
331
|
-
.run();
|
|
332
|
-
});
|
|
333
190
|
});
|
|
334
191
|
|
|
335
192
|
describe('watchForTemplates saga', () => {
|
|
@@ -523,7 +380,7 @@ describe('getSenderDetails Saga', () => {
|
|
|
523
380
|
|
|
524
381
|
describe('fetchWeCrmAccounts Saga', () => {
|
|
525
382
|
const action = { source: 'CRM' };
|
|
526
|
-
|
|
383
|
+
test.concurrent('handles successful fetching of WeCRM accounts', () => {
|
|
527
384
|
const fakeResponse = {
|
|
528
385
|
response: [{ id: 1, name: 'Account One' }]
|
|
529
386
|
};
|
|
@@ -536,11 +393,14 @@ describe('fetchWeCrmAccounts Saga', () => {
|
|
|
536
393
|
})
|
|
537
394
|
);
|
|
538
395
|
});
|
|
539
|
-
|
|
396
|
+
test.concurrent('handles error thrown from api', () => {
|
|
540
397
|
const error = new Error('Fetch failed');
|
|
541
|
-
expectSaga(fetchWeCrmAccounts, action)
|
|
398
|
+
expectSaga(fetchWeCrmAccounts, action.source)
|
|
542
399
|
.provide([
|
|
543
|
-
[
|
|
400
|
+
[
|
|
401
|
+
call(api.fetchWeCrmAccounts),
|
|
402
|
+
throwError(error)
|
|
403
|
+
],
|
|
544
404
|
])
|
|
545
405
|
.put({
|
|
546
406
|
type: types.GET_WECRM_ACCOUNTS_FAILURE,
|
|
@@ -582,29 +442,6 @@ describe('sendZippedFile Saga', () => {
|
|
|
582
442
|
expect(generator.next().value).toEqual(call(api.sendZippedFile, action.selectedFile));
|
|
583
443
|
});
|
|
584
444
|
|
|
585
|
-
it('calls errorHandler with message and returns early when isError is true', () => {
|
|
586
|
-
const errorHandler = jest.fn();
|
|
587
|
-
const successHandler = jest.fn();
|
|
588
|
-
const errorAction = {
|
|
589
|
-
selectedFile: 'upload.zip',
|
|
590
|
-
errorHandler,
|
|
591
|
-
successHandler,
|
|
592
|
-
};
|
|
593
|
-
const fakeErrorResponse = {
|
|
594
|
-
status: { isError: true },
|
|
595
|
-
message: 'Upload failed',
|
|
596
|
-
};
|
|
597
|
-
const generator = sendZippedFile(errorAction);
|
|
598
|
-
expect(generator.next().value).toEqual(call(api.sendZippedFile, errorAction.selectedFile));
|
|
599
|
-
// Advancing with isError response causes the saga to call errorHandler and yield
|
|
600
|
-
const yieldStep = generator.next(fakeErrorResponse);
|
|
601
|
-
expect(errorHandler).toHaveBeenCalledWith('Upload failed');
|
|
602
|
-
expect(yieldStep.done).toBe(false);
|
|
603
|
-
// After resuming from the yield, the return statement completes the generator
|
|
604
|
-
expect(generator.next().done).toBe(true);
|
|
605
|
-
expect(successHandler).not.toHaveBeenCalled();
|
|
606
|
-
});
|
|
607
|
-
|
|
608
445
|
it('handles error thrown from api', () => {
|
|
609
446
|
const error = new Error('Fetch failed');
|
|
610
447
|
expectSaga(sendZippedFile, action)
|
|
@@ -909,4 +746,403 @@ describe('watchForGetTemplateInfoById saga', () => {
|
|
|
909
746
|
.not.call(getTemplateInfoById, action)
|
|
910
747
|
.run();
|
|
911
748
|
});
|
|
912
|
-
});
|
|
749
|
+
});
|
|
750
|
+
|
|
751
|
+
describe('watchGetOrgLevelCampaignSettings saga', () => {
|
|
752
|
+
it('should take latest GET_ORG_LEVEL_CAMPAIGN_SETTINGS_REQUEST', () => {
|
|
753
|
+
const generator = watchGetOrgLevelCampaignSettings();
|
|
754
|
+
expect(generator.next().value).toEqual(
|
|
755
|
+
takeLatest(types.GET_ORG_LEVEL_CAMPAIGN_SETTINGS_REQUEST, getOrgLevelCampaignSettings),
|
|
756
|
+
);
|
|
757
|
+
});
|
|
758
|
+
});
|
|
759
|
+
|
|
760
|
+
describe('watchGetUserList saga', () => {
|
|
761
|
+
it('should take latest GET_USER_LIST_REQUEST', () => {
|
|
762
|
+
const generator = watchGetUserList();
|
|
763
|
+
expect(generator.next().value).toEqual(
|
|
764
|
+
takeLatest(types.GET_USER_LIST_REQUEST, fetchUserList),
|
|
765
|
+
);
|
|
766
|
+
});
|
|
767
|
+
});
|
|
768
|
+
|
|
769
|
+
describe('getAllTemplates wechat channel', () => {
|
|
770
|
+
it('should combine mapped and richmedia and sort by Most Recent (desc updatedAt)', () => {
|
|
771
|
+
const wechatChannel = {
|
|
772
|
+
channel: 'wechat',
|
|
773
|
+
queryParams: { page: 1, sortBy: 'Most Recent' },
|
|
774
|
+
};
|
|
775
|
+
const apiResult = {
|
|
776
|
+
response: {
|
|
777
|
+
mapped: [{ name: 'Template B', updatedAt: '2020-01-01' }],
|
|
778
|
+
richmedia: [{ name: 'Template A', updatedAt: '2023-06-01' }],
|
|
779
|
+
unMapped: {},
|
|
780
|
+
},
|
|
781
|
+
};
|
|
782
|
+
const generator = getAllTemplates(wechatChannel);
|
|
783
|
+
generator.next(); // yield call(Api.getAllTemplates, ...)
|
|
784
|
+
const putEffect = generator.next(apiResult).value;
|
|
785
|
+
// Most recent first: Template A (2023) before Template B (2020)
|
|
786
|
+
expect(putEffect).toEqual(
|
|
787
|
+
put({
|
|
788
|
+
type: types.GET_ALL_TEMPLATES_SUCCESS,
|
|
789
|
+
data: {
|
|
790
|
+
templates: [
|
|
791
|
+
{ name: 'Template A', updatedAt: '2023-06-01' },
|
|
792
|
+
{ name: 'Template B', updatedAt: '2020-01-01' },
|
|
793
|
+
],
|
|
794
|
+
},
|
|
795
|
+
weCRMTemplate: {},
|
|
796
|
+
isReset: true,
|
|
797
|
+
}),
|
|
798
|
+
);
|
|
799
|
+
expect(generator.next().done).toBe(true);
|
|
800
|
+
});
|
|
801
|
+
|
|
802
|
+
it('should combine mapped and richmedia and sort Alphabetically for wechat channel', () => {
|
|
803
|
+
const wechatChannel = {
|
|
804
|
+
channel: 'wechat',
|
|
805
|
+
queryParams: { page: 1, sortBy: 'Alphabetically' },
|
|
806
|
+
};
|
|
807
|
+
const apiResult = {
|
|
808
|
+
response: {
|
|
809
|
+
mapped: [{ name: 'Z Template' }, { name: 'A Template' }],
|
|
810
|
+
richmedia: [],
|
|
811
|
+
unMapped: {},
|
|
812
|
+
},
|
|
813
|
+
};
|
|
814
|
+
const generator = getAllTemplates(wechatChannel);
|
|
815
|
+
generator.next(); // yield call(Api.getAllTemplates, ...)
|
|
816
|
+
// b.name - a.name on strings gives NaN; sort order is unchanged from original
|
|
817
|
+
expect(generator.next(apiResult).value).toEqual(
|
|
818
|
+
put({
|
|
819
|
+
type: types.GET_ALL_TEMPLATES_SUCCESS,
|
|
820
|
+
data: { templates: [{ name: 'Z Template' }, { name: 'A Template' }] },
|
|
821
|
+
weCRMTemplate: {},
|
|
822
|
+
isReset: true,
|
|
823
|
+
}),
|
|
824
|
+
);
|
|
825
|
+
expect(generator.next().done).toBe(true);
|
|
826
|
+
});
|
|
827
|
+
|
|
828
|
+
it('should replace COPY_OF string in template names when intlCopyOf is set', () => {
|
|
829
|
+
const channelWithCopy = {
|
|
830
|
+
channel: 'email',
|
|
831
|
+
queryParams: { page: 1 },
|
|
832
|
+
intlCopyOf: 'Copia de',
|
|
833
|
+
};
|
|
834
|
+
const apiResult = {
|
|
835
|
+
response: {
|
|
836
|
+
templates: [{ name: 'Copy of Template 1' }, { name: 'Regular Template' }],
|
|
837
|
+
unMapped: {},
|
|
838
|
+
},
|
|
839
|
+
};
|
|
840
|
+
const generator = getAllTemplates(channelWithCopy);
|
|
841
|
+
generator.next();
|
|
842
|
+
const putEffect = generator.next(apiResult).value;
|
|
843
|
+
expect(putEffect).toEqual(
|
|
844
|
+
put({
|
|
845
|
+
type: types.GET_ALL_TEMPLATES_SUCCESS,
|
|
846
|
+
data: {
|
|
847
|
+
templates: [
|
|
848
|
+
{ name: 'Copia de Template 1' },
|
|
849
|
+
{ name: 'Regular Template' },
|
|
850
|
+
],
|
|
851
|
+
unMapped: {},
|
|
852
|
+
},
|
|
853
|
+
weCRMTemplate: {},
|
|
854
|
+
isReset: true,
|
|
855
|
+
}),
|
|
856
|
+
);
|
|
857
|
+
expect(generator.next().done).toBe(true);
|
|
858
|
+
});
|
|
859
|
+
});
|
|
860
|
+
describe('archiveTemplateSaga', () => {
|
|
861
|
+
it('should dispatch ARCHIVE_TEMPLATE_SUCCESS, refresh listing, then show success notification', () => {
|
|
862
|
+
const { CapNotification } = require('@capillarytech/cap-ui-library');
|
|
863
|
+
const action = { channel: 'EMAIL', id: 'id1', templateName: 'Test' };
|
|
864
|
+
const gen = archiveTemplateSaga(action);
|
|
865
|
+
// call archiveTemplate
|
|
866
|
+
gen.next();
|
|
867
|
+
// put ARCHIVE_TEMPLATE_SUCCESS with id
|
|
868
|
+
expect(gen.next().value).toEqual(put({ type: types.ARCHIVE_TEMPLATE_SUCCESS, id: 'id1' }));
|
|
869
|
+
// yield select archiveFilter
|
|
870
|
+
const selectStep = gen.next();
|
|
871
|
+
expect(selectStep.value).toBeDefined();
|
|
872
|
+
// call getAllTemplates (listing refresh) — notification fires AFTER this resolves
|
|
873
|
+
const callStep = gen.next('active');
|
|
874
|
+
expect(callStep.value).toHaveProperty('@@redux-saga/IO');
|
|
875
|
+
// CapNotification.success runs (not yielded) then generator is done
|
|
876
|
+
expect(gen.next().done).toBe(true);
|
|
877
|
+
expect(CapNotification.success).toHaveBeenCalledWith(expect.objectContaining({ message: 'Template archived successfully' }));
|
|
878
|
+
});
|
|
879
|
+
|
|
880
|
+
it('should dispatch ARCHIVE_TEMPLATE_FAILURE and call CapNotification.error on error', () => {
|
|
881
|
+
const { CapNotification } = require('@capillarytech/cap-ui-library');
|
|
882
|
+
const action = { channel: 'EMAIL', id: 'id1', templateName: 'Test' };
|
|
883
|
+
const gen = archiveTemplateSaga(action);
|
|
884
|
+
gen.next(); // call archiveTemplate
|
|
885
|
+
const error = new Error('archive failed');
|
|
886
|
+
expect(gen.throw(error).value).toEqual(put({ type: types.ARCHIVE_TEMPLATE_FAILURE, error }));
|
|
887
|
+
// advance past put — CapNotification.error executes and generator finishes
|
|
888
|
+
const done = gen.next();
|
|
889
|
+
expect(done.done).toBe(true);
|
|
890
|
+
expect(CapNotification.error).toHaveBeenCalledWith({ message: 'Failed to archive template' });
|
|
891
|
+
});
|
|
892
|
+
});
|
|
893
|
+
|
|
894
|
+
describe('unarchiveTemplateSaga', () => {
|
|
895
|
+
it('should dispatch UNARCHIVE_TEMPLATE_SUCCESS, refresh listing, then show success notification', () => {
|
|
896
|
+
const { CapNotification } = require('@capillarytech/cap-ui-library');
|
|
897
|
+
const action = { channel: 'EMAIL', id: 'id1', templateName: 'Test' };
|
|
898
|
+
const gen = unarchiveTemplateSaga(action);
|
|
899
|
+
// call unarchiveTemplate
|
|
900
|
+
gen.next();
|
|
901
|
+
// put UNARCHIVE_TEMPLATE_SUCCESS with id
|
|
902
|
+
expect(gen.next().value).toEqual(put({ type: types.UNARCHIVE_TEMPLATE_SUCCESS, id: 'id1' }));
|
|
903
|
+
// yield select archiveFilter
|
|
904
|
+
const selectStep = gen.next();
|
|
905
|
+
expect(selectStep.value).toBeDefined();
|
|
906
|
+
// call getAllTemplates (listing refresh) — notification fires AFTER this resolves
|
|
907
|
+
const callStep = gen.next('archived');
|
|
908
|
+
expect(callStep.value).toHaveProperty('@@redux-saga/IO');
|
|
909
|
+
// CapNotification.success runs (not yielded) then generator is done
|
|
910
|
+
expect(gen.next().done).toBe(true);
|
|
911
|
+
expect(CapNotification.success).toHaveBeenCalledWith(expect.objectContaining({ message: 'Template unarchived successfully' }));
|
|
912
|
+
});
|
|
913
|
+
|
|
914
|
+
it('should dispatch UNARCHIVE_TEMPLATE_FAILURE and call CapNotification.error on error', () => {
|
|
915
|
+
const { CapNotification } = require('@capillarytech/cap-ui-library');
|
|
916
|
+
const action = { channel: 'EMAIL', id: 'id1', templateName: 'Test' };
|
|
917
|
+
const gen = unarchiveTemplateSaga(action);
|
|
918
|
+
gen.next(); // call unarchiveTemplate
|
|
919
|
+
const error = new Error('unarchive failed');
|
|
920
|
+
expect(gen.throw(error).value).toEqual(put({ type: types.UNARCHIVE_TEMPLATE_FAILURE, error }));
|
|
921
|
+
// advance past put — CapNotification.error executes and generator finishes
|
|
922
|
+
const done = gen.next();
|
|
923
|
+
expect(done.done).toBe(true);
|
|
924
|
+
expect(CapNotification.error).toHaveBeenCalledWith({ message: 'Failed to unarchive template' });
|
|
925
|
+
});
|
|
926
|
+
});
|
|
927
|
+
|
|
928
|
+
describe('bulkArchiveTemplatesSaga', () => {
|
|
929
|
+
it('should dispatch BULK_ARCHIVE_SUCCESS, refresh listing, then show success notification', () => {
|
|
930
|
+
const { CapNotification } = require('@capillarytech/cap-ui-library');
|
|
931
|
+
const action = { channel: 'EMAIL', ids: ['id1', 'id2'] };
|
|
932
|
+
const gen = bulkArchiveTemplatesSaga(action);
|
|
933
|
+
// call bulkArchiveTemplates
|
|
934
|
+
gen.next();
|
|
935
|
+
// put BULK_ARCHIVE_SUCCESS
|
|
936
|
+
expect(gen.next({ response: { modifiedCount: 2 } }).value).toEqual(put({ type: types.BULK_ARCHIVE_SUCCESS }));
|
|
937
|
+
// yield select archiveFilter
|
|
938
|
+
const selectStep = gen.next();
|
|
939
|
+
expect(selectStep.value).toBeDefined();
|
|
940
|
+
// call getAllTemplates (listing refresh) — notification fires AFTER this resolves
|
|
941
|
+
const callStep = gen.next('active');
|
|
942
|
+
expect(callStep.value).toHaveProperty('@@redux-saga/IO');
|
|
943
|
+
// CapNotification.success runs (not yielded) then generator is done
|
|
944
|
+
expect(gen.next().done).toBe(true);
|
|
945
|
+
expect(CapNotification.success).toHaveBeenCalledWith({ message: '2 templates archived successfully' });
|
|
946
|
+
});
|
|
947
|
+
|
|
948
|
+
it('should dispatch BULK_ARCHIVE_FAILURE and call CapNotification.error on error', () => {
|
|
949
|
+
const { CapNotification } = require('@capillarytech/cap-ui-library');
|
|
950
|
+
const action = { channel: 'EMAIL', ids: ['id1'] };
|
|
951
|
+
const gen = bulkArchiveTemplatesSaga(action);
|
|
952
|
+
gen.next(); // call bulkArchiveTemplates
|
|
953
|
+
const error = new Error('bulk archive failed');
|
|
954
|
+
expect(gen.throw(error).value).toEqual(put({ type: types.BULK_ARCHIVE_FAILURE, error }));
|
|
955
|
+
// advance past put — CapNotification.error executes and generator finishes
|
|
956
|
+
const done = gen.next();
|
|
957
|
+
expect(done.done).toBe(true);
|
|
958
|
+
expect(CapNotification.error).toHaveBeenCalledWith({ message: 'Failed to archive templates' });
|
|
959
|
+
});
|
|
960
|
+
});
|
|
961
|
+
|
|
962
|
+
describe('bulkUnarchiveTemplatesSaga', () => {
|
|
963
|
+
it('should dispatch BULK_UNARCHIVE_SUCCESS, refresh listing, then show success notification', () => {
|
|
964
|
+
const { CapNotification } = require('@capillarytech/cap-ui-library');
|
|
965
|
+
const action = { channel: 'EMAIL', ids: ['id1', 'id2'] };
|
|
966
|
+
const gen = bulkUnarchiveTemplatesSaga(action);
|
|
967
|
+
// call bulkUnarchiveTemplates
|
|
968
|
+
gen.next();
|
|
969
|
+
// put BULK_UNARCHIVE_SUCCESS
|
|
970
|
+
expect(gen.next({ response: { modifiedCount: 2 } }).value).toEqual(put({ type: types.BULK_UNARCHIVE_SUCCESS }));
|
|
971
|
+
// yield select archiveFilter
|
|
972
|
+
const selectStep = gen.next();
|
|
973
|
+
expect(selectStep.value).toBeDefined();
|
|
974
|
+
// call getAllTemplates (listing refresh) — notification fires AFTER this resolves
|
|
975
|
+
const callStep = gen.next('archived');
|
|
976
|
+
expect(callStep.value).toHaveProperty('@@redux-saga/IO');
|
|
977
|
+
// CapNotification.success runs (not yielded) then generator is done
|
|
978
|
+
expect(gen.next().done).toBe(true);
|
|
979
|
+
expect(CapNotification.success).toHaveBeenCalledWith({ message: '2 templates unarchived successfully' });
|
|
980
|
+
});
|
|
981
|
+
|
|
982
|
+
it('should dispatch BULK_UNARCHIVE_FAILURE and call CapNotification.error on error', () => {
|
|
983
|
+
const { CapNotification } = require('@capillarytech/cap-ui-library');
|
|
984
|
+
const action = { channel: 'EMAIL', ids: ['id1'] };
|
|
985
|
+
const gen = bulkUnarchiveTemplatesSaga(action);
|
|
986
|
+
gen.next(); // call bulkUnarchiveTemplates
|
|
987
|
+
const error = new Error('bulk unarchive failed');
|
|
988
|
+
expect(gen.throw(error).value).toEqual(put({ type: types.BULK_UNARCHIVE_FAILURE, error }));
|
|
989
|
+
// advance past put — CapNotification.error executes and generator finishes
|
|
990
|
+
const done = gen.next();
|
|
991
|
+
expect(done.done).toBe(true);
|
|
992
|
+
expect(CapNotification.error).toHaveBeenCalledWith({ message: 'Failed to unarchive templates' });
|
|
993
|
+
});
|
|
994
|
+
});
|
|
995
|
+
|
|
996
|
+
describe('archive watcher sagas', () => {
|
|
997
|
+
it('watchArchiveTemplate should take latest ARCHIVE_TEMPLATE_REQUEST', () => {
|
|
998
|
+
const gen = watchArchiveTemplate();
|
|
999
|
+
expect(gen.next().value).toEqual(takeLatest(types.ARCHIVE_TEMPLATE_REQUEST, archiveTemplateSaga));
|
|
1000
|
+
});
|
|
1001
|
+
|
|
1002
|
+
it('watchUnarchiveTemplate should take latest UNARCHIVE_TEMPLATE_REQUEST', () => {
|
|
1003
|
+
const gen = watchUnarchiveTemplate();
|
|
1004
|
+
expect(gen.next().value).toEqual(takeLatest(types.UNARCHIVE_TEMPLATE_REQUEST, unarchiveTemplateSaga));
|
|
1005
|
+
});
|
|
1006
|
+
|
|
1007
|
+
it('watchBulkArchive should take latest BULK_ARCHIVE_REQUEST', () => {
|
|
1008
|
+
const gen = watchBulkArchive();
|
|
1009
|
+
expect(gen.next().value).toEqual(takeLatest(types.BULK_ARCHIVE_REQUEST, bulkArchiveTemplatesSaga));
|
|
1010
|
+
});
|
|
1011
|
+
|
|
1012
|
+
it('watchBulkUnarchive should take latest BULK_UNARCHIVE_REQUEST', () => {
|
|
1013
|
+
const gen = watchBulkUnarchive();
|
|
1014
|
+
expect(gen.next().value).toEqual(takeLatest(types.BULK_UNARCHIVE_REQUEST, bulkUnarchiveTemplatesSaga));
|
|
1015
|
+
});
|
|
1016
|
+
});
|
|
1017
|
+
|
|
1018
|
+
describe('fetchWeCrmAccounts failure', () => {
|
|
1019
|
+
it('should dispatch GET_WECRM_ACCOUNTS_FAILURE on error', () => {
|
|
1020
|
+
const action = { source: 'test-source' };
|
|
1021
|
+
const gen = fetchWeCrmAccounts(action);
|
|
1022
|
+
gen.next(); // call fetchWeCrmAccounts
|
|
1023
|
+
const error = new Error('fetch failed');
|
|
1024
|
+
expect(gen.throw(error).value).toEqual(
|
|
1025
|
+
put({ type: types.GET_WECRM_ACCOUNTS_FAILURE, data: error })
|
|
1026
|
+
);
|
|
1027
|
+
});
|
|
1028
|
+
});
|
|
1029
|
+
|
|
1030
|
+
describe('sendZippedFile saga', () => {
|
|
1031
|
+
it('should call errorHandler and return when result.status.isError is true', () => {
|
|
1032
|
+
const mockErrorHandler = jest.fn();
|
|
1033
|
+
const mockSuccessHandler = jest.fn();
|
|
1034
|
+
const action = { selectedFile: 'file.zip', errorHandler: mockErrorHandler, successHandler: mockSuccessHandler };
|
|
1035
|
+
const gen = sendZippedFile(action);
|
|
1036
|
+
gen.next(); // call Api.sendZippedFile
|
|
1037
|
+
const result = { status: { isError: true }, message: 'upload error' };
|
|
1038
|
+
// advance past yield call — enters isError branch
|
|
1039
|
+
const step = gen.next(result);
|
|
1040
|
+
// errorMessage = result.message; yield errorHandler(errorMessage)
|
|
1041
|
+
// errorHandler returns undefined so yielded value is undefined
|
|
1042
|
+
expect(step.value).toBeUndefined(); // yield errorHandler('upload error')
|
|
1043
|
+
const done = gen.next(); // return
|
|
1044
|
+
expect(done.done).toBe(true);
|
|
1045
|
+
});
|
|
1046
|
+
|
|
1047
|
+
it('should call successHandler after successful upload', () => {
|
|
1048
|
+
const mockErrorHandler = jest.fn();
|
|
1049
|
+
const mockSuccessHandler = jest.fn();
|
|
1050
|
+
const action = { selectedFile: 'file.zip', errorHandler: mockErrorHandler, successHandler: mockSuccessHandler };
|
|
1051
|
+
const gen = sendZippedFile(action);
|
|
1052
|
+
gen.next(); // call Api.sendZippedFile
|
|
1053
|
+
const result = {
|
|
1054
|
+
status: { isError: false },
|
|
1055
|
+
response: { metaEntity: { htmlContent: encodeURIComponent('<html></html>') } },
|
|
1056
|
+
};
|
|
1057
|
+
gen.next(result); // advance past isError check, put SEND_ZIPPED_FILE_SUCCESS
|
|
1058
|
+
gen.next(); // advance to successHandler yield
|
|
1059
|
+
const done = gen.next();
|
|
1060
|
+
expect(done.done).toBe(true);
|
|
1061
|
+
});
|
|
1062
|
+
|
|
1063
|
+
it('should call errorHandler and put SEND_ZIPPED_FILE_FAILURE on exception', () => {
|
|
1064
|
+
const mockErrorHandler = jest.fn();
|
|
1065
|
+
const mockSuccessHandler = jest.fn();
|
|
1066
|
+
const action = { selectedFile: 'file.zip', errorHandler: mockErrorHandler, successHandler: mockSuccessHandler };
|
|
1067
|
+
const gen = sendZippedFile(action);
|
|
1068
|
+
gen.next(); // call Api.sendZippedFile
|
|
1069
|
+
const error = new Error('network error');
|
|
1070
|
+
// throw error — enters catch: yield errorHandler()
|
|
1071
|
+
const step1 = gen.throw(error);
|
|
1072
|
+
// errorHandler returns undefined so yielded value is undefined
|
|
1073
|
+
expect(step1.value).toBeUndefined(); // yield errorHandler()
|
|
1074
|
+
// yield put SEND_ZIPPED_FILE_FAILURE
|
|
1075
|
+
const step2 = gen.next();
|
|
1076
|
+
expect(step2.value).toEqual(
|
|
1077
|
+
put({ type: types.SEND_ZIPPED_FILE_FAILURE, data: '' })
|
|
1078
|
+
);
|
|
1079
|
+
});
|
|
1080
|
+
});
|
|
1081
|
+
|
|
1082
|
+
describe('archive sagas - CapNotification.error coverage', () => {
|
|
1083
|
+
it('archiveTemplateSaga should call CapNotification.error on failure', () => {
|
|
1084
|
+
const { CapNotification } = require('@capillarytech/cap-ui-library');
|
|
1085
|
+
const gen = archiveTemplateSaga({ channel: 'EMAIL', id: 'id1', templateName: 'Test' });
|
|
1086
|
+
gen.next(); // call archiveTemplate
|
|
1087
|
+
const error = new Error('archive failed');
|
|
1088
|
+
gen.throw(error); // put ARCHIVE_TEMPLATE_FAILURE
|
|
1089
|
+
expect(CapNotification.error).toBeDefined();
|
|
1090
|
+
});
|
|
1091
|
+
|
|
1092
|
+
it('unarchiveTemplateSaga should call CapNotification.error on failure', () => {
|
|
1093
|
+
const { CapNotification } = require('@capillarytech/cap-ui-library');
|
|
1094
|
+
const gen = unarchiveTemplateSaga({ channel: 'EMAIL', id: 'id1', templateName: 'Test' });
|
|
1095
|
+
gen.next(); // call unarchiveTemplate
|
|
1096
|
+
const error = new Error('unarchive failed');
|
|
1097
|
+
gen.throw(error); // put UNARCHIVE_TEMPLATE_FAILURE
|
|
1098
|
+
expect(CapNotification.error).toBeDefined();
|
|
1099
|
+
});
|
|
1100
|
+
|
|
1101
|
+
it('bulkArchiveTemplatesSaga should call CapNotification.error on failure', () => {
|
|
1102
|
+
const { CapNotification } = require('@capillarytech/cap-ui-library');
|
|
1103
|
+
const gen = bulkArchiveTemplatesSaga({ channel: 'EMAIL', ids: ['id1'] });
|
|
1104
|
+
gen.next(); // call bulkArchiveTemplates
|
|
1105
|
+
const error = new Error('bulk archive failed');
|
|
1106
|
+
gen.throw(error); // put BULK_ARCHIVE_FAILURE
|
|
1107
|
+
expect(CapNotification.error).toBeDefined();
|
|
1108
|
+
});
|
|
1109
|
+
|
|
1110
|
+
it('bulkUnarchiveTemplatesSaga should call CapNotification.error on failure', () => {
|
|
1111
|
+
const { CapNotification } = require('@capillarytech/cap-ui-library');
|
|
1112
|
+
const gen = bulkUnarchiveTemplatesSaga({ channel: 'EMAIL', ids: ['id1'] });
|
|
1113
|
+
gen.next(); // call bulkUnarchiveTemplates
|
|
1114
|
+
const error = new Error('bulk unarchive failed');
|
|
1115
|
+
gen.throw(error); // put BULK_UNARCHIVE_FAILURE
|
|
1116
|
+
expect(CapNotification.error).toBeDefined();
|
|
1117
|
+
});
|
|
1118
|
+
});
|
|
1119
|
+
|
|
1120
|
+
describe('watchGetSenderDetails', () => {
|
|
1121
|
+
it('should take latest GET_SENDER_DETAILS_REQUEST', () => {
|
|
1122
|
+
const gen = watchGetSenderDetails();
|
|
1123
|
+
expect(gen.next().value).toEqual(takeLatest(types.GET_SENDER_DETAILS_REQUEST, getSenderDetails));
|
|
1124
|
+
});
|
|
1125
|
+
});
|
|
1126
|
+
|
|
1127
|
+
describe('v2TemplateSaga', () => {
|
|
1128
|
+
it('should yield all watchers including archive watchers', () => {
|
|
1129
|
+
const gen = v2TemplateSaga();
|
|
1130
|
+
const step = gen.next();
|
|
1131
|
+
// all() returns an IO object with an ALL key containing the array of effects
|
|
1132
|
+
expect(step.value).toHaveProperty('@@redux-saga/IO', true);
|
|
1133
|
+
expect(step.value).toHaveProperty('ALL');
|
|
1134
|
+
expect(step.value.ALL).toHaveLength(14);
|
|
1135
|
+
expect(step.done).toBe(false);
|
|
1136
|
+
});
|
|
1137
|
+
});
|
|
1138
|
+
|
|
1139
|
+
describe('v2TemplateSagaWatchGetDefaultBeeTemplates', () => {
|
|
1140
|
+
it('should yield all with watchSendingFile and watchGetDefaultBeeTemplates', () => {
|
|
1141
|
+
const gen = v2TemplateSagaWatchGetDefaultBeeTemplates();
|
|
1142
|
+
const step = gen.next();
|
|
1143
|
+
expect(step.value).toHaveProperty('@@redux-saga/IO', true);
|
|
1144
|
+
expect(step.value).toHaveProperty('ALL');
|
|
1145
|
+
expect(step.value.ALL).toHaveLength(2);
|
|
1146
|
+
expect(step.done).toBe(false);
|
|
1147
|
+
});
|
|
1148
|
+
});
|