@capillarytech/creatives-library 8.0.345 → 8.0.347
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/utils/tests/v2Common.test.js +46 -1
- package/utils/v2common.js +18 -0
- package/v2Containers/Email/reducer.js +12 -3
- package/v2Containers/Email/sagas.js +9 -4
- package/v2Containers/Email/tests/__snapshots__/reducer.test.js.snap +4 -0
- package/v2Containers/Email/tests/reducer.test.js +47 -0
- package/v2Containers/Email/tests/sagas.test.js +146 -6
- package/v2Containers/Templates/_templates.scss +53 -4
- package/v2Containers/Templates/actions.js +16 -8
- package/v2Containers/Templates/index.js +187 -123
- package/v2Containers/Templates/messages.js +20 -0
- package/v2Containers/Templates/reducer.js +26 -11
- package/v2Containers/Templates/sagas.js +13 -37
- package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +45 -0
- package/v2Containers/Templates/tests/sagas.test.js +142 -66
- package/v2Containers/TemplatesV2/TemplatesV2.style.js +1 -1
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
1
|
import {
|
|
3
|
-
call, put,
|
|
2
|
+
call, put, takeLatest, all,
|
|
4
3
|
} from 'redux-saga/effects';
|
|
5
4
|
import get from 'lodash/get';
|
|
6
5
|
import { CapNotification } from '@capillarytech/cap-ui-library';
|
|
@@ -12,17 +11,6 @@ import { COPY_OF } from '../../constants/unified';
|
|
|
12
11
|
import { ZALO_TEMPLATE_INFO_REQUEST } from '../Zalo/constants';
|
|
13
12
|
import { getTemplateInfoById } from '../Zalo/saga';
|
|
14
13
|
|
|
15
|
-
const templateNameDescription = (templateName) => (
|
|
16
|
-
templateName
|
|
17
|
-
? (
|
|
18
|
-
<span>
|
|
19
|
-
<span className="notification-template-label">Template name </span>
|
|
20
|
-
<span className="notification-template-name">{templateName}</span>
|
|
21
|
-
</span>
|
|
22
|
-
)
|
|
23
|
-
: undefined
|
|
24
|
-
);
|
|
25
|
-
|
|
26
14
|
// Individual exports for testing
|
|
27
15
|
export function* getAllTemplates(channel, queryParams) {
|
|
28
16
|
try {
|
|
@@ -215,57 +203,45 @@ export function* getSenderDetails({
|
|
|
215
203
|
}
|
|
216
204
|
}
|
|
217
205
|
|
|
218
|
-
export function* archiveTemplateSaga({ channel, id,
|
|
206
|
+
export function* archiveTemplateSaga({ channel, id, successMessage, description }) {
|
|
219
207
|
try {
|
|
220
208
|
yield call(Api.archiveTemplate, { channel, id });
|
|
221
|
-
yield put({ type: types.ARCHIVE_TEMPLATE_SUCCESS, id });
|
|
222
|
-
const archiveFilter = yield select((state) => state.get('templates') ? state.get('templates').get('archiveFilter', 'active') : 'active');
|
|
223
|
-
yield call(getAllTemplates, { channel, queryParams: { page: 1, archiveStatus: archiveFilter } });
|
|
224
|
-
CapNotification.success({ message: 'Template archived successfully', description: templateNameDescription(templateName) });
|
|
209
|
+
yield put({ type: types.ARCHIVE_TEMPLATE_SUCCESS, id, successMessage, description });
|
|
225
210
|
} catch (error) {
|
|
226
211
|
yield put({ type: types.ARCHIVE_TEMPLATE_FAILURE, error });
|
|
227
|
-
CapNotification.error({ message: 'Failed to archive template' });
|
|
212
|
+
CapNotification.error({ message: error.message || 'Failed to archive template' });
|
|
228
213
|
}
|
|
229
214
|
}
|
|
230
215
|
|
|
231
|
-
export function* unarchiveTemplateSaga({ channel, id,
|
|
216
|
+
export function* unarchiveTemplateSaga({ channel, id, successMessage, description }) {
|
|
232
217
|
try {
|
|
233
218
|
yield call(Api.unarchiveTemplate, { channel, id });
|
|
234
|
-
yield put({ type: types.UNARCHIVE_TEMPLATE_SUCCESS, id });
|
|
235
|
-
const archiveFilter = yield select((state) => state.get('templates') ? state.get('templates').get('archiveFilter', 'active') : 'active');
|
|
236
|
-
yield call(getAllTemplates, { channel, queryParams: { page: 1, archiveStatus: archiveFilter } });
|
|
237
|
-
CapNotification.success({ message: 'Template unarchived successfully', description: templateNameDescription(templateName) });
|
|
219
|
+
yield put({ type: types.UNARCHIVE_TEMPLATE_SUCCESS, id, successMessage, description });
|
|
238
220
|
} catch (error) {
|
|
239
221
|
yield put({ type: types.UNARCHIVE_TEMPLATE_FAILURE, error });
|
|
240
|
-
CapNotification.error({ message: 'Failed to unarchive template' });
|
|
222
|
+
CapNotification.error({ message: error.message || 'Failed to unarchive template' });
|
|
241
223
|
}
|
|
242
224
|
}
|
|
243
225
|
|
|
244
|
-
export function* bulkArchiveTemplatesSaga({ channel, ids }) {
|
|
226
|
+
export function* bulkArchiveTemplatesSaga({ channel, ids, successMessage }) {
|
|
245
227
|
try {
|
|
246
228
|
const result = yield call(Api.bulkArchiveTemplates, { channel, ids });
|
|
247
|
-
yield put({ type: types.BULK_ARCHIVE_SUCCESS });
|
|
248
229
|
const count = get(result, 'response.modifiedCount', ids.length);
|
|
249
|
-
|
|
250
|
-
yield call(getAllTemplates, { channel, queryParams: { page: 1, archiveStatus: archiveFilter } });
|
|
251
|
-
CapNotification.success({ message: `${count} templates archived successfully` });
|
|
230
|
+
yield put({ type: types.BULK_ARCHIVE_SUCCESS, successMessage, count });
|
|
252
231
|
} catch (error) {
|
|
253
232
|
yield put({ type: types.BULK_ARCHIVE_FAILURE, error });
|
|
254
|
-
CapNotification.error({ message: 'Failed to archive templates' });
|
|
233
|
+
CapNotification.error({ message: error.message || 'Failed to archive templates' });
|
|
255
234
|
}
|
|
256
235
|
}
|
|
257
236
|
|
|
258
|
-
export function* bulkUnarchiveTemplatesSaga({ channel, ids }) {
|
|
237
|
+
export function* bulkUnarchiveTemplatesSaga({ channel, ids, successMessage }) {
|
|
259
238
|
try {
|
|
260
239
|
const result = yield call(Api.bulkUnarchiveTemplates, { channel, ids });
|
|
261
|
-
yield put({ type: types.BULK_UNARCHIVE_SUCCESS });
|
|
262
240
|
const count = get(result, 'response.modifiedCount', ids.length);
|
|
263
|
-
|
|
264
|
-
yield call(getAllTemplates, { channel, queryParams: { page: 1, archiveStatus: archiveFilter } });
|
|
265
|
-
CapNotification.success({ message: `${count} templates unarchived successfully` });
|
|
241
|
+
yield put({ type: types.BULK_UNARCHIVE_SUCCESS, successMessage, count });
|
|
266
242
|
} catch (error) {
|
|
267
243
|
yield put({ type: types.BULK_UNARCHIVE_FAILURE, error });
|
|
268
|
-
CapNotification.error({ message: 'Failed to unarchive templates' });
|
|
244
|
+
CapNotification.error({ message: error.message || 'Failed to unarchive templates' });
|
|
269
245
|
}
|
|
270
246
|
}
|
|
271
247
|
|
|
@@ -192,6 +192,11 @@ exports[`Test Templates container Should render sms illustration when no templat
|
|
|
192
192
|
<Fragment>
|
|
193
193
|
<div
|
|
194
194
|
className="creatives-templates-list library-mode"
|
|
195
|
+
style={
|
|
196
|
+
Object {
|
|
197
|
+
"position": "relative",
|
|
198
|
+
}
|
|
199
|
+
}
|
|
195
200
|
>
|
|
196
201
|
<input
|
|
197
202
|
accept=".zip, .html, .htm"
|
|
@@ -376,6 +381,11 @@ exports[`Test Templates container Should render temlates when whatsapp templates
|
|
|
376
381
|
<Fragment>
|
|
377
382
|
<div
|
|
378
383
|
className="creatives-templates-list library-mode"
|
|
384
|
+
style={
|
|
385
|
+
Object {
|
|
386
|
+
"position": "relative",
|
|
387
|
+
}
|
|
388
|
+
}
|
|
379
389
|
>
|
|
380
390
|
<input
|
|
381
391
|
accept=".zip, .html, .htm"
|
|
@@ -628,6 +638,11 @@ exports[`Test Templates container Should render temlates when whatsapp templates
|
|
|
628
638
|
<Fragment>
|
|
629
639
|
<div
|
|
630
640
|
className="creatives-templates-list full-mode"
|
|
641
|
+
style={
|
|
642
|
+
Object {
|
|
643
|
+
"position": "relative",
|
|
644
|
+
}
|
|
645
|
+
}
|
|
631
646
|
>
|
|
632
647
|
<input
|
|
633
648
|
accept=".zip, .html, .htm"
|
|
@@ -1079,6 +1094,11 @@ exports[`Test Templates container Test max templates exceeded 1`] = `
|
|
|
1079
1094
|
<Fragment>
|
|
1080
1095
|
<div
|
|
1081
1096
|
className="creatives-templates-list full-mode"
|
|
1097
|
+
style={
|
|
1098
|
+
Object {
|
|
1099
|
+
"position": "relative",
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1082
1102
|
>
|
|
1083
1103
|
<input
|
|
1084
1104
|
accept=".zip, .html, .htm"
|
|
@@ -1583,6 +1603,11 @@ exports[`Test Templates container Test max templates not exceeded 1`] = `
|
|
|
1583
1603
|
<Fragment>
|
|
1584
1604
|
<div
|
|
1585
1605
|
className="creatives-templates-list full-mode"
|
|
1606
|
+
style={
|
|
1607
|
+
Object {
|
|
1608
|
+
"position": "relative",
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1586
1611
|
>
|
|
1587
1612
|
<input
|
|
1588
1613
|
accept=".zip, .html, .htm"
|
|
@@ -2087,6 +2112,11 @@ exports[`Test Templates container Test max templates warning 1`] = `
|
|
|
2087
2112
|
<Fragment>
|
|
2088
2113
|
<div
|
|
2089
2114
|
className="creatives-templates-list full-mode"
|
|
2115
|
+
style={
|
|
2116
|
+
Object {
|
|
2117
|
+
"position": "relative",
|
|
2118
|
+
}
|
|
2119
|
+
}
|
|
2090
2120
|
>
|
|
2091
2121
|
<input
|
|
2092
2122
|
accept=".zip, .html, .htm"
|
|
@@ -2591,6 +2621,11 @@ exports[`Test Templates container Test removing all whatsapp filterss 1`] = `
|
|
|
2591
2621
|
<Fragment>
|
|
2592
2622
|
<div
|
|
2593
2623
|
className="creatives-templates-list library-mode"
|
|
2624
|
+
style={
|
|
2625
|
+
Object {
|
|
2626
|
+
"position": "relative",
|
|
2627
|
+
}
|
|
2628
|
+
}
|
|
2594
2629
|
>
|
|
2595
2630
|
<input
|
|
2596
2631
|
accept=".zip, .html, .htm"
|
|
@@ -2869,6 +2904,11 @@ exports[`Test Templates container Test removing all whatsapp filterss 2`] = `
|
|
|
2869
2904
|
<Fragment>
|
|
2870
2905
|
<div
|
|
2871
2906
|
className="creatives-templates-list library-mode"
|
|
2907
|
+
style={
|
|
2908
|
+
Object {
|
|
2909
|
+
"position": "relative",
|
|
2910
|
+
}
|
|
2911
|
+
}
|
|
2872
2912
|
>
|
|
2873
2913
|
<input
|
|
2874
2914
|
accept=".zip, .html, .htm"
|
|
@@ -3121,6 +3161,11 @@ exports[`Test Templates container Test removing single filter 1`] = `
|
|
|
3121
3161
|
<Fragment>
|
|
3122
3162
|
<div
|
|
3123
3163
|
className="creatives-templates-list library-mode"
|
|
3164
|
+
style={
|
|
3165
|
+
Object {
|
|
3166
|
+
"position": "relative",
|
|
3167
|
+
}
|
|
3168
|
+
}
|
|
3124
3169
|
>
|
|
3125
3170
|
<input
|
|
3126
3171
|
accept=".zip, .html, .htm"
|
|
@@ -858,91 +858,80 @@ describe('getAllTemplates wechat channel', () => {
|
|
|
858
858
|
});
|
|
859
859
|
});
|
|
860
860
|
describe('archiveTemplateSaga', () => {
|
|
861
|
-
it('should
|
|
862
|
-
const
|
|
863
|
-
const
|
|
861
|
+
it('should call archiveTemplate API then dispatch ARCHIVE_TEMPLATE_SUCCESS with payload', () => {
|
|
862
|
+
const successMessage = 'Template archived successfully';
|
|
863
|
+
const description = 'Template name Test';
|
|
864
|
+
const action = { channel: 'EMAIL', id: 'id1', successMessage, description };
|
|
864
865
|
const gen = archiveTemplateSaga(action);
|
|
865
|
-
// call archiveTemplate
|
|
866
|
+
// first yield: call archiveTemplate
|
|
866
867
|
gen.next();
|
|
867
|
-
// put ARCHIVE_TEMPLATE_SUCCESS with id
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
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
|
|
868
|
+
// second yield: put ARCHIVE_TEMPLATE_SUCCESS with id and success payload
|
|
869
|
+
const successStep = gen.next();
|
|
870
|
+
expect(successStep.value).toEqual(put({ type: types.ARCHIVE_TEMPLATE_SUCCESS, id: 'id1', successMessage, description }));
|
|
871
|
+
// done — no more yields
|
|
876
872
|
expect(gen.next().done).toBe(true);
|
|
877
|
-
expect(CapNotification.success).toHaveBeenCalledWith(expect.objectContaining({ message: 'Template archived successfully' }));
|
|
878
873
|
});
|
|
879
874
|
|
|
880
875
|
it('should dispatch ARCHIVE_TEMPLATE_FAILURE and call CapNotification.error on error', () => {
|
|
881
876
|
const { CapNotification } = require('@capillarytech/cap-ui-library');
|
|
882
|
-
const action = { channel: 'EMAIL', id: 'id1',
|
|
877
|
+
const action = { channel: 'EMAIL', id: 'id1', successMessage: 'archived' };
|
|
883
878
|
const gen = archiveTemplateSaga(action);
|
|
884
879
|
gen.next(); // call archiveTemplate
|
|
885
880
|
const error = new Error('archive failed');
|
|
886
881
|
expect(gen.throw(error).value).toEqual(put({ type: types.ARCHIVE_TEMPLATE_FAILURE, error }));
|
|
887
|
-
// advance past put — CapNotification.error executes and generator finishes
|
|
888
882
|
const done = gen.next();
|
|
889
883
|
expect(done.done).toBe(true);
|
|
890
|
-
expect(CapNotification.error).toHaveBeenCalledWith({ message: '
|
|
884
|
+
expect(CapNotification.error).toHaveBeenCalledWith({ message: 'archive failed' });
|
|
891
885
|
});
|
|
892
886
|
});
|
|
893
887
|
|
|
894
888
|
describe('unarchiveTemplateSaga', () => {
|
|
895
|
-
it('should
|
|
896
|
-
const
|
|
897
|
-
const
|
|
889
|
+
it('should call unarchiveTemplate API then dispatch UNARCHIVE_TEMPLATE_SUCCESS with payload', () => {
|
|
890
|
+
const successMessage = 'Template unarchived successfully';
|
|
891
|
+
const description = 'Template name Test';
|
|
892
|
+
const action = { channel: 'EMAIL', id: 'id1', successMessage, description };
|
|
898
893
|
const gen = unarchiveTemplateSaga(action);
|
|
899
|
-
// call unarchiveTemplate
|
|
894
|
+
// first yield: call unarchiveTemplate
|
|
900
895
|
gen.next();
|
|
901
|
-
// put UNARCHIVE_TEMPLATE_SUCCESS with id
|
|
902
|
-
|
|
903
|
-
|
|
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
|
|
896
|
+
// second yield: put UNARCHIVE_TEMPLATE_SUCCESS with id and success payload
|
|
897
|
+
const successStep = gen.next();
|
|
898
|
+
expect(successStep.value).toEqual(put({ type: types.UNARCHIVE_TEMPLATE_SUCCESS, id: 'id1', successMessage, description }));
|
|
910
899
|
expect(gen.next().done).toBe(true);
|
|
911
|
-
expect(CapNotification.success).toHaveBeenCalledWith(expect.objectContaining({ message: 'Template unarchived successfully' }));
|
|
912
900
|
});
|
|
913
901
|
|
|
914
902
|
it('should dispatch UNARCHIVE_TEMPLATE_FAILURE and call CapNotification.error on error', () => {
|
|
915
903
|
const { CapNotification } = require('@capillarytech/cap-ui-library');
|
|
916
|
-
const action = { channel: 'EMAIL', id: 'id1',
|
|
904
|
+
const action = { channel: 'EMAIL', id: 'id1', successMessage: 'unarchived' };
|
|
917
905
|
const gen = unarchiveTemplateSaga(action);
|
|
918
906
|
gen.next(); // call unarchiveTemplate
|
|
919
907
|
const error = new Error('unarchive failed');
|
|
920
908
|
expect(gen.throw(error).value).toEqual(put({ type: types.UNARCHIVE_TEMPLATE_FAILURE, error }));
|
|
921
|
-
// advance past put — CapNotification.error executes and generator finishes
|
|
922
909
|
const done = gen.next();
|
|
923
910
|
expect(done.done).toBe(true);
|
|
924
|
-
expect(CapNotification.error).toHaveBeenCalledWith({ message: '
|
|
911
|
+
expect(CapNotification.error).toHaveBeenCalledWith({ message: 'unarchive failed' });
|
|
925
912
|
});
|
|
926
913
|
});
|
|
927
914
|
|
|
928
915
|
describe('bulkArchiveTemplatesSaga', () => {
|
|
929
|
-
it('should
|
|
930
|
-
const
|
|
931
|
-
const action = { channel: 'EMAIL', ids: ['id1', 'id2'] };
|
|
916
|
+
it('should call bulkArchiveTemplates API then dispatch BULK_ARCHIVE_SUCCESS with count', () => {
|
|
917
|
+
const successMessage = (count) => `${count} templates archived`;
|
|
918
|
+
const action = { channel: 'EMAIL', ids: ['id1', 'id2'], successMessage };
|
|
932
919
|
const gen = bulkArchiveTemplatesSaga(action);
|
|
933
|
-
// call bulkArchiveTemplates
|
|
920
|
+
// first yield: call bulkArchiveTemplates
|
|
934
921
|
gen.next();
|
|
935
|
-
// put BULK_ARCHIVE_SUCCESS
|
|
936
|
-
|
|
937
|
-
|
|
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
|
|
922
|
+
// second yield: put BULK_ARCHIVE_SUCCESS with successMessage and count
|
|
923
|
+
const successStep = gen.next({ response: { modifiedCount: 2 } });
|
|
924
|
+
expect(successStep.value).toEqual(put({ type: types.BULK_ARCHIVE_SUCCESS, successMessage, count: 2 }));
|
|
944
925
|
expect(gen.next().done).toBe(true);
|
|
945
|
-
|
|
926
|
+
});
|
|
927
|
+
|
|
928
|
+
it('should use ids.length as count fallback when modifiedCount is missing', () => {
|
|
929
|
+
const successMessage = (count) => `${count} templates archived`;
|
|
930
|
+
const action = { channel: 'EMAIL', ids: ['id1', 'id2', 'id3'], successMessage };
|
|
931
|
+
const gen = bulkArchiveTemplatesSaga(action);
|
|
932
|
+
gen.next();
|
|
933
|
+
const successStep = gen.next({ response: {} });
|
|
934
|
+
expect(successStep.value).toEqual(put({ type: types.BULK_ARCHIVE_SUCCESS, successMessage, count: 3 }));
|
|
946
935
|
});
|
|
947
936
|
|
|
948
937
|
it('should dispatch BULK_ARCHIVE_FAILURE and call CapNotification.error on error', () => {
|
|
@@ -952,31 +941,32 @@ describe('bulkArchiveTemplatesSaga', () => {
|
|
|
952
941
|
gen.next(); // call bulkArchiveTemplates
|
|
953
942
|
const error = new Error('bulk archive failed');
|
|
954
943
|
expect(gen.throw(error).value).toEqual(put({ type: types.BULK_ARCHIVE_FAILURE, error }));
|
|
955
|
-
// advance past put — CapNotification.error executes and generator finishes
|
|
956
944
|
const done = gen.next();
|
|
957
945
|
expect(done.done).toBe(true);
|
|
958
|
-
expect(CapNotification.error).toHaveBeenCalledWith({ message: '
|
|
946
|
+
expect(CapNotification.error).toHaveBeenCalledWith({ message: 'bulk archive failed' });
|
|
959
947
|
});
|
|
960
948
|
});
|
|
961
949
|
|
|
962
950
|
describe('bulkUnarchiveTemplatesSaga', () => {
|
|
963
|
-
it('should
|
|
964
|
-
const
|
|
965
|
-
const action = { channel: 'EMAIL', ids: ['id1', 'id2'] };
|
|
951
|
+
it('should call bulkUnarchiveTemplates API then dispatch BULK_UNARCHIVE_SUCCESS with count', () => {
|
|
952
|
+
const successMessage = (count) => `${count} templates unarchived`;
|
|
953
|
+
const action = { channel: 'EMAIL', ids: ['id1', 'id2'], successMessage };
|
|
966
954
|
const gen = bulkUnarchiveTemplatesSaga(action);
|
|
967
|
-
// call bulkUnarchiveTemplates
|
|
955
|
+
// first yield: call bulkUnarchiveTemplates
|
|
968
956
|
gen.next();
|
|
969
|
-
// put BULK_UNARCHIVE_SUCCESS
|
|
970
|
-
|
|
971
|
-
|
|
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
|
|
957
|
+
// second yield: put BULK_UNARCHIVE_SUCCESS with successMessage and count
|
|
958
|
+
const successStep = gen.next({ response: { modifiedCount: 2 } });
|
|
959
|
+
expect(successStep.value).toEqual(put({ type: types.BULK_UNARCHIVE_SUCCESS, successMessage, count: 2 }));
|
|
978
960
|
expect(gen.next().done).toBe(true);
|
|
979
|
-
|
|
961
|
+
});
|
|
962
|
+
|
|
963
|
+
it('should use ids.length as count fallback when modifiedCount is missing', () => {
|
|
964
|
+
const successMessage = (count) => `${count} templates unarchived`;
|
|
965
|
+
const action = { channel: 'EMAIL', ids: ['id1', 'id2'], successMessage };
|
|
966
|
+
const gen = bulkUnarchiveTemplatesSaga(action);
|
|
967
|
+
gen.next();
|
|
968
|
+
const successStep = gen.next({ response: {} });
|
|
969
|
+
expect(successStep.value).toEqual(put({ type: types.BULK_UNARCHIVE_SUCCESS, successMessage, count: 2 }));
|
|
980
970
|
});
|
|
981
971
|
|
|
982
972
|
it('should dispatch BULK_UNARCHIVE_FAILURE and call CapNotification.error on error', () => {
|
|
@@ -986,10 +976,9 @@ describe('bulkUnarchiveTemplatesSaga', () => {
|
|
|
986
976
|
gen.next(); // call bulkUnarchiveTemplates
|
|
987
977
|
const error = new Error('bulk unarchive failed');
|
|
988
978
|
expect(gen.throw(error).value).toEqual(put({ type: types.BULK_UNARCHIVE_FAILURE, error }));
|
|
989
|
-
// advance past put — CapNotification.error executes and generator finishes
|
|
990
979
|
const done = gen.next();
|
|
991
980
|
expect(done.done).toBe(true);
|
|
992
|
-
expect(CapNotification.error).toHaveBeenCalledWith({ message: '
|
|
981
|
+
expect(CapNotification.error).toHaveBeenCalledWith({ message: 'bulk unarchive failed' });
|
|
993
982
|
});
|
|
994
983
|
});
|
|
995
984
|
|
|
@@ -1117,6 +1106,93 @@ describe('archive sagas - CapNotification.error coverage', () => {
|
|
|
1117
1106
|
});
|
|
1118
1107
|
});
|
|
1119
1108
|
|
|
1109
|
+
describe('archive sagas - first yield and fallback message coverage', () => {
|
|
1110
|
+
it('archiveTemplateSaga first yield should be a redux-saga call effect', () => {
|
|
1111
|
+
const gen = archiveTemplateSaga({ channel: 'EMAIL', id: 'id1', successMessage: 'ok' });
|
|
1112
|
+
const firstStep = gen.next();
|
|
1113
|
+
expect(firstStep.value).toHaveProperty('@@redux-saga/IO', true);
|
|
1114
|
+
expect(firstStep.value).toHaveProperty('CALL');
|
|
1115
|
+
expect(firstStep.value.CALL.args).toEqual([{ channel: 'EMAIL', id: 'id1' }]);
|
|
1116
|
+
});
|
|
1117
|
+
|
|
1118
|
+
it('archiveTemplateSaga error with no message property should use fallback string', () => {
|
|
1119
|
+
const { CapNotification } = require('@capillarytech/cap-ui-library');
|
|
1120
|
+
const gen = archiveTemplateSaga({ channel: 'EMAIL', id: 'id1', successMessage: 'ok' });
|
|
1121
|
+
gen.next(); // call archiveTemplate
|
|
1122
|
+
const error = {}; // no .message
|
|
1123
|
+
gen.throw(error); // put ARCHIVE_TEMPLATE_FAILURE
|
|
1124
|
+
gen.next(); // CapNotification.error runs
|
|
1125
|
+
expect(CapNotification.error).toHaveBeenCalledWith({ message: 'Failed to archive template' });
|
|
1126
|
+
});
|
|
1127
|
+
|
|
1128
|
+
it('unarchiveTemplateSaga first yield should be a redux-saga call effect', () => {
|
|
1129
|
+
const gen = unarchiveTemplateSaga({ channel: 'EMAIL', id: 'id1', successMessage: 'ok' });
|
|
1130
|
+
const firstStep = gen.next();
|
|
1131
|
+
expect(firstStep.value).toHaveProperty('@@redux-saga/IO', true);
|
|
1132
|
+
expect(firstStep.value).toHaveProperty('CALL');
|
|
1133
|
+
expect(firstStep.value.CALL.args).toEqual([{ channel: 'EMAIL', id: 'id1' }]);
|
|
1134
|
+
});
|
|
1135
|
+
|
|
1136
|
+
it('unarchiveTemplateSaga error with no message property should use fallback string', () => {
|
|
1137
|
+
const { CapNotification } = require('@capillarytech/cap-ui-library');
|
|
1138
|
+
const gen = unarchiveTemplateSaga({ channel: 'EMAIL', id: 'id1', successMessage: 'ok' });
|
|
1139
|
+
gen.next(); // call unarchiveTemplate
|
|
1140
|
+
const error = {}; // no .message
|
|
1141
|
+
gen.throw(error); // put UNARCHIVE_TEMPLATE_FAILURE
|
|
1142
|
+
gen.next(); // CapNotification.error runs
|
|
1143
|
+
expect(CapNotification.error).toHaveBeenCalledWith({ message: 'Failed to unarchive template' });
|
|
1144
|
+
});
|
|
1145
|
+
|
|
1146
|
+
it('bulkArchiveTemplatesSaga error with no message property should use fallback string', () => {
|
|
1147
|
+
const { CapNotification } = require('@capillarytech/cap-ui-library');
|
|
1148
|
+
const gen = bulkArchiveTemplatesSaga({ channel: 'EMAIL', ids: ['id1'] });
|
|
1149
|
+
gen.next(); // call bulkArchiveTemplates
|
|
1150
|
+
const error = {}; // no .message
|
|
1151
|
+
gen.throw(error); // put BULK_ARCHIVE_FAILURE
|
|
1152
|
+
gen.next(); // CapNotification.error runs
|
|
1153
|
+
expect(CapNotification.error).toHaveBeenCalledWith({ message: 'Failed to archive templates' });
|
|
1154
|
+
});
|
|
1155
|
+
|
|
1156
|
+
it('bulkArchiveTemplatesSaga with no successMessage stores undefined successMessage in BULK_ARCHIVE_SUCCESS', () => {
|
|
1157
|
+
const gen = bulkArchiveTemplatesSaga({ channel: 'EMAIL', ids: ['id1', 'id2'] });
|
|
1158
|
+
gen.next(); // call bulkArchiveTemplates
|
|
1159
|
+
const successStep = gen.next({ response: { modifiedCount: 2 } });
|
|
1160
|
+
// successMessage is undefined (not provided); component will use fallback
|
|
1161
|
+
expect(successStep.value).toEqual(put({ type: types.BULK_ARCHIVE_SUCCESS, successMessage: undefined, count: 2 }));
|
|
1162
|
+
});
|
|
1163
|
+
|
|
1164
|
+
it('bulkArchiveTemplatesSaga with no modifiedCount in response falls back to ids.length', () => {
|
|
1165
|
+
const gen = bulkArchiveTemplatesSaga({ channel: 'EMAIL', ids: ['id1', 'id2', 'id3'] });
|
|
1166
|
+
gen.next(); // call bulkArchiveTemplates
|
|
1167
|
+
const successStep = gen.next({ response: {} }); // no modifiedCount
|
|
1168
|
+
expect(successStep.value).toEqual(put({ type: types.BULK_ARCHIVE_SUCCESS, successMessage: undefined, count: 3 }));
|
|
1169
|
+
});
|
|
1170
|
+
|
|
1171
|
+
it('bulkUnarchiveTemplatesSaga error with no message property should use fallback string', () => {
|
|
1172
|
+
const { CapNotification } = require('@capillarytech/cap-ui-library');
|
|
1173
|
+
const gen = bulkUnarchiveTemplatesSaga({ channel: 'EMAIL', ids: ['id1'] });
|
|
1174
|
+
gen.next(); // call bulkUnarchiveTemplates
|
|
1175
|
+
const error = {}; // no .message
|
|
1176
|
+
gen.throw(error); // put BULK_UNARCHIVE_FAILURE
|
|
1177
|
+
gen.next(); // CapNotification.error runs
|
|
1178
|
+
expect(CapNotification.error).toHaveBeenCalledWith({ message: 'Failed to unarchive templates' });
|
|
1179
|
+
});
|
|
1180
|
+
|
|
1181
|
+
it('bulkUnarchiveTemplatesSaga with no successMessage stores undefined successMessage in BULK_UNARCHIVE_SUCCESS', () => {
|
|
1182
|
+
const gen = bulkUnarchiveTemplatesSaga({ channel: 'EMAIL', ids: ['id1', 'id2'] });
|
|
1183
|
+
gen.next(); // call bulkUnarchiveTemplates
|
|
1184
|
+
const successStep = gen.next({ response: { modifiedCount: 2 } });
|
|
1185
|
+
expect(successStep.value).toEqual(put({ type: types.BULK_UNARCHIVE_SUCCESS, successMessage: undefined, count: 2 }));
|
|
1186
|
+
});
|
|
1187
|
+
|
|
1188
|
+
it('bulkUnarchiveTemplatesSaga with no modifiedCount in response falls back to ids.length', () => {
|
|
1189
|
+
const gen = bulkUnarchiveTemplatesSaga({ channel: 'EMAIL', ids: ['id1', 'id2', 'id3'] });
|
|
1190
|
+
gen.next(); // call bulkUnarchiveTemplates
|
|
1191
|
+
const successStep = gen.next({ response: {} }); // no modifiedCount
|
|
1192
|
+
expect(successStep.value).toEqual(put({ type: types.BULK_UNARCHIVE_SUCCESS, successMessage: undefined, count: 3 }));
|
|
1193
|
+
});
|
|
1194
|
+
});
|
|
1195
|
+
|
|
1120
1196
|
describe('watchGetSenderDetails', () => {
|
|
1121
1197
|
it('should take latest GET_SENDER_DETAILS_REQUEST', () => {
|
|
1122
1198
|
const gen = watchGetSenderDetails();
|
|
@@ -13,7 +13,7 @@ export default css`
|
|
|
13
13
|
max-width: 1140px;
|
|
14
14
|
margin: 0 auto;
|
|
15
15
|
width: 100%;
|
|
16
|
-
padding:
|
|
16
|
+
padding: 0.714rem 0;
|
|
17
17
|
/* Only main channel tabs content, not HTML Editor validation panel tabs */
|
|
18
18
|
> .cap-tab-v2 > .ant-tabs-content-holder > .ant-tabs-content,
|
|
19
19
|
> .cap-tab-v2 > .ant-tabs-content {
|