@capillarytech/creatives-library 8.0.346 → 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/services/api.js +20 -0
- package/services/tests/api.test.js +59 -0
- package/utils/tests/v2Common.test.js +46 -1
- package/utils/v2common.js +18 -0
- package/v2Components/CapCustomSkeleton/index.js +1 -1
- package/v2Components/CapCustomSkeleton/tests/__snapshots__/index.test.js.snap +12 -12
- package/v2Containers/Assets/images/archive_Empty_Illustration.svg +9 -0
- package/v2Containers/CreativesContainer/SlideBoxFooter.js +3 -1
- package/v2Containers/CreativesContainer/index.js +5 -0
- package/v2Containers/CreativesContainer/messages.js +4 -0
- package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +3 -0
- package/v2Containers/Templates/ChannelTypeIllustration.js +23 -6
- package/v2Containers/Templates/_templates.scss +179 -24
- package/v2Containers/Templates/actions.js +44 -0
- package/v2Containers/Templates/constants.js +23 -0
- package/v2Containers/Templates/index.js +378 -58
- package/v2Containers/Templates/messages.js +88 -0
- package/v2Containers/Templates/reducer.js +84 -1
- package/v2Containers/Templates/sagas.js +64 -0
- 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 +1345 -1122
- 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 +390 -8
- package/v2Containers/Templates/tests/selector.test.js +32 -0
- package/v2Containers/TemplatesV2/TemplatesV2.style.js +1 -1
|
@@ -23,6 +23,9 @@ describe('Test Templates container', () => {
|
|
|
23
23
|
const getUserList = jest.fn();
|
|
24
24
|
const getSenderDetails = jest.fn();
|
|
25
25
|
const resetTemplate = jest.fn();
|
|
26
|
+
const setArchivedMode = jest.fn();
|
|
27
|
+
const clearTemplateSelection = jest.fn();
|
|
28
|
+
const toggleTemplateSelection = jest.fn();
|
|
26
29
|
let renderedComponent;
|
|
27
30
|
|
|
28
31
|
beforeEach(() => {
|
|
@@ -56,6 +59,9 @@ describe('Test Templates container', () => {
|
|
|
56
59
|
getUserList,
|
|
57
60
|
getSenderDetails,
|
|
58
61
|
resetTemplate,
|
|
62
|
+
setArchivedMode,
|
|
63
|
+
clearTemplateSelection,
|
|
64
|
+
toggleTemplateSelection,
|
|
59
65
|
}}
|
|
60
66
|
location={{
|
|
61
67
|
pathname: `/${channel}`,
|
|
@@ -353,3 +353,181 @@ describe("test reducer - SET account actions clear templates", () => {
|
|
|
353
353
|
expect(result.templates).toEqual([]);
|
|
354
354
|
});
|
|
355
355
|
});
|
|
356
|
+
|
|
357
|
+
describe("test reducer - archive actions", () => {
|
|
358
|
+
afterEach(() => {
|
|
359
|
+
jest.clearAllMocks();
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
it("should handle SET_ARCHIVE_FILTER", () => {
|
|
363
|
+
const action = { type: types.SET_ARCHIVE_FILTER, filter: 'archived' };
|
|
364
|
+
const result = reducer(initialState, action).toJS();
|
|
365
|
+
expect(result.archiveFilter).toBe('archived');
|
|
366
|
+
expect(result.templates).toEqual([]);
|
|
367
|
+
expect(result.selectedTemplateIds).toEqual([]);
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
it("should handle SET_ARCHIVED_MODE with isArchived true", () => {
|
|
371
|
+
const action = { type: types.SET_ARCHIVED_MODE, isArchived: true };
|
|
372
|
+
const result = reducer(initialState, action).toJS();
|
|
373
|
+
expect(result.isArchivedMode).toBe(true);
|
|
374
|
+
expect(result.archiveFilter).toBe('archived');
|
|
375
|
+
expect(result.templates).toEqual([]);
|
|
376
|
+
expect(result.selectedTemplateIds).toEqual([]);
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
it("should handle SET_ARCHIVED_MODE with isArchived false", () => {
|
|
380
|
+
const action = { type: types.SET_ARCHIVED_MODE, isArchived: false };
|
|
381
|
+
const result = reducer(initialState, action).toJS();
|
|
382
|
+
expect(result.isArchivedMode).toBe(false);
|
|
383
|
+
expect(result.archiveFilter).toBe('active');
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
it("should handle TOGGLE_TEMPLATE_SELECTION - add id", () => {
|
|
387
|
+
const action = { type: types.TOGGLE_TEMPLATE_SELECTION, id: 'id1' };
|
|
388
|
+
const result = reducer(initialState, action).toJS();
|
|
389
|
+
expect(result.selectedTemplateIds).toEqual(['id1']);
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
it("should handle TOGGLE_TEMPLATE_SELECTION - remove id if already selected", () => {
|
|
393
|
+
const { fromJS } = require('immutable');
|
|
394
|
+
const stateWithSelected = initialState.set('selectedTemplateIds', fromJS(['id1', 'id2']));
|
|
395
|
+
const action = { type: types.TOGGLE_TEMPLATE_SELECTION, id: 'id1' };
|
|
396
|
+
const result = reducer(stateWithSelected, action).toJS();
|
|
397
|
+
expect(result.selectedTemplateIds).toEqual(['id2']);
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
it("should handle TOGGLE_TEMPLATE_SELECTION - add id when selectedTemplateIds is a plain array (legacy state)", () => {
|
|
401
|
+
// Covers the Array.isArray branch of the defensive fallback
|
|
402
|
+
const stateWithPlainArray = initialState.set('selectedTemplateIds', ['id1']);
|
|
403
|
+
const action = { type: types.TOGGLE_TEMPLATE_SELECTION, id: 'id2' };
|
|
404
|
+
const result = reducer(stateWithPlainArray, action).toJS();
|
|
405
|
+
expect(result.selectedTemplateIds).toEqual(['id1', 'id2']);
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
it("should handle TOGGLE_TEMPLATE_SELECTION - remove id when selectedTemplateIds is a plain array (legacy state)", () => {
|
|
409
|
+
// Covers the Array.isArray branch of the defensive fallback
|
|
410
|
+
const stateWithPlainArray = initialState.set('selectedTemplateIds', ['id1', 'id2']);
|
|
411
|
+
const action = { type: types.TOGGLE_TEMPLATE_SELECTION, id: 'id1' };
|
|
412
|
+
const result = reducer(stateWithPlainArray, action).toJS();
|
|
413
|
+
expect(result.selectedTemplateIds).toEqual(['id2']);
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
it("should handle TOGGLE_TEMPLATE_SELECTION - add id when selectedTemplateIds is undefined (stale persisted state)", () => {
|
|
417
|
+
// Covers the final fallback to [] when rawSelected is neither Immutable nor Array
|
|
418
|
+
const stateWithUndefined = initialState.set('selectedTemplateIds', undefined);
|
|
419
|
+
const action = { type: types.TOGGLE_TEMPLATE_SELECTION, id: 'id1' };
|
|
420
|
+
const result = reducer(stateWithUndefined, action).toJS();
|
|
421
|
+
expect(result.selectedTemplateIds).toEqual(['id1']);
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
it("should handle SELECT_ALL_TEMPLATES", () => {
|
|
425
|
+
const action = { type: types.SELECT_ALL_TEMPLATES, ids: ['id1', 'id2', 'id3'] };
|
|
426
|
+
const result = reducer(initialState, action).toJS();
|
|
427
|
+
expect(result.selectedTemplateIds).toEqual(['id1', 'id2', 'id3']);
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
it("should handle CLEAR_TEMPLATE_SELECTION", () => {
|
|
431
|
+
const { fromJS } = require('immutable');
|
|
432
|
+
const stateWithSelected = initialState.set('selectedTemplateIds', fromJS(['id1', 'id2']));
|
|
433
|
+
const action = { type: types.CLEAR_TEMPLATE_SELECTION };
|
|
434
|
+
const result = reducer(stateWithSelected, action).toJS();
|
|
435
|
+
expect(result.selectedTemplateIds).toEqual([]);
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
it("should handle ARCHIVE_TEMPLATE_REQUEST", () => {
|
|
439
|
+
const action = { type: types.ARCHIVE_TEMPLATE_REQUEST };
|
|
440
|
+
const result = reducer(initialState, action).toJS();
|
|
441
|
+
expect(result.archiveInProgress).toBe(true);
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
it("should handle ARCHIVE_TEMPLATE_SUCCESS", () => {
|
|
445
|
+
const action = { type: types.ARCHIVE_TEMPLATE_SUCCESS };
|
|
446
|
+
const result = reducer(initialState, action).toJS();
|
|
447
|
+
expect(result.archiveInProgress).toBe(false);
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
it("should remove archived template id from selectedTemplateIds on ARCHIVE_TEMPLATE_SUCCESS", () => {
|
|
451
|
+
const { fromJS } = require('immutable');
|
|
452
|
+
const stateWithSelected = initialState.set('selectedTemplateIds', fromJS(['id1', 'id2', 'id3']));
|
|
453
|
+
const action = { type: types.ARCHIVE_TEMPLATE_SUCCESS, id: 'id2' };
|
|
454
|
+
const result = reducer(stateWithSelected, action).toJS();
|
|
455
|
+
expect(result.archiveInProgress).toBe(false);
|
|
456
|
+
expect(result.selectedTemplateIds).toEqual(['id1', 'id3']);
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
it("should handle ARCHIVE_TEMPLATE_FAILURE", () => {
|
|
460
|
+
const action = { type: types.ARCHIVE_TEMPLATE_FAILURE };
|
|
461
|
+
const result = reducer(initialState, action).toJS();
|
|
462
|
+
expect(result.archiveInProgress).toBe(false);
|
|
463
|
+
});
|
|
464
|
+
|
|
465
|
+
it("should handle UNARCHIVE_TEMPLATE_REQUEST", () => {
|
|
466
|
+
const action = { type: types.UNARCHIVE_TEMPLATE_REQUEST };
|
|
467
|
+
const result = reducer(initialState, action).toJS();
|
|
468
|
+
expect(result.unarchiveInProgress).toBe(true);
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
it("should handle UNARCHIVE_TEMPLATE_SUCCESS", () => {
|
|
472
|
+
const action = { type: types.UNARCHIVE_TEMPLATE_SUCCESS };
|
|
473
|
+
const result = reducer(initialState, action).toJS();
|
|
474
|
+
expect(result.unarchiveInProgress).toBe(false);
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
it("should remove unarchived template id from selectedTemplateIds on UNARCHIVE_TEMPLATE_SUCCESS", () => {
|
|
478
|
+
const { fromJS } = require('immutable');
|
|
479
|
+
const stateWithSelected = initialState.set('selectedTemplateIds', fromJS(['id1', 'id2', 'id3']));
|
|
480
|
+
const action = { type: types.UNARCHIVE_TEMPLATE_SUCCESS, id: 'id1' };
|
|
481
|
+
const result = reducer(stateWithSelected, action).toJS();
|
|
482
|
+
expect(result.unarchiveInProgress).toBe(false);
|
|
483
|
+
expect(result.selectedTemplateIds).toEqual(['id2', 'id3']);
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
it("should handle UNARCHIVE_TEMPLATE_FAILURE", () => {
|
|
487
|
+
const action = { type: types.UNARCHIVE_TEMPLATE_FAILURE };
|
|
488
|
+
const result = reducer(initialState, action).toJS();
|
|
489
|
+
expect(result.unarchiveInProgress).toBe(false);
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
it("should handle BULK_ARCHIVE_REQUEST", () => {
|
|
493
|
+
const action = { type: types.BULK_ARCHIVE_REQUEST };
|
|
494
|
+
const result = reducer(initialState, action).toJS();
|
|
495
|
+
expect(result.bulkArchiveInProgress).toBe(true);
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
it("should handle BULK_ARCHIVE_SUCCESS", () => {
|
|
499
|
+
const { fromJS } = require('immutable');
|
|
500
|
+
const stateWithSelected = initialState.set('selectedTemplateIds', fromJS(['id1']));
|
|
501
|
+
const action = { type: types.BULK_ARCHIVE_SUCCESS };
|
|
502
|
+
const result = reducer(stateWithSelected, action).toJS();
|
|
503
|
+
expect(result.bulkArchiveInProgress).toBe(false);
|
|
504
|
+
expect(result.selectedTemplateIds).toEqual([]);
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
it("should handle BULK_ARCHIVE_FAILURE", () => {
|
|
508
|
+
const action = { type: types.BULK_ARCHIVE_FAILURE };
|
|
509
|
+
const result = reducer(initialState, action).toJS();
|
|
510
|
+
expect(result.bulkArchiveInProgress).toBe(false);
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
it("should handle BULK_UNARCHIVE_REQUEST", () => {
|
|
514
|
+
const action = { type: types.BULK_UNARCHIVE_REQUEST };
|
|
515
|
+
const result = reducer(initialState, action).toJS();
|
|
516
|
+
expect(result.bulkUnarchiveInProgress).toBe(true);
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
it("should handle BULK_UNARCHIVE_SUCCESS", () => {
|
|
520
|
+
const { fromJS } = require('immutable');
|
|
521
|
+
const stateWithSelected = initialState.set('selectedTemplateIds', fromJS(['id1']));
|
|
522
|
+
const action = { type: types.BULK_UNARCHIVE_SUCCESS };
|
|
523
|
+
const result = reducer(stateWithSelected, action).toJS();
|
|
524
|
+
expect(result.bulkUnarchiveInProgress).toBe(false);
|
|
525
|
+
expect(result.selectedTemplateIds).toEqual([]);
|
|
526
|
+
});
|
|
527
|
+
|
|
528
|
+
it("should handle BULK_UNARCHIVE_FAILURE", () => {
|
|
529
|
+
const action = { type: types.BULK_UNARCHIVE_FAILURE };
|
|
530
|
+
const result = reducer(initialState, action).toJS();
|
|
531
|
+
expect(result.bulkUnarchiveInProgress).toBe(false);
|
|
532
|
+
});
|
|
533
|
+
});
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { expectSaga } from 'redux-saga-test-plan';
|
|
2
|
-
import { take, call, takeLatest, takeEvery, put } from 'redux-saga/effects';
|
|
3
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';
|
|
4
5
|
import * as api from '../../../services/api';
|
|
5
6
|
import * as types from '../constants';
|
|
6
7
|
import * as cdnUtils from '../../../utils/cdnTransformation';
|
|
7
|
-
|
|
8
8
|
import {
|
|
9
9
|
getCdnTransformationConfig,
|
|
10
10
|
getAllTemplates,
|
|
@@ -28,13 +28,30 @@ import {
|
|
|
28
28
|
watchGetOrgLevelCampaignSettings,
|
|
29
29
|
watchSendingFile,
|
|
30
30
|
watchFetchWeCrmAccounts,
|
|
31
|
+
watchGetSenderDetails,
|
|
32
|
+
v2TemplateSaga,
|
|
33
|
+
v2TemplateSagaWatchGetDefaultBeeTemplates,
|
|
34
|
+
archiveTemplateSaga,
|
|
35
|
+
unarchiveTemplateSaga,
|
|
36
|
+
bulkArchiveTemplatesSaga,
|
|
37
|
+
bulkUnarchiveTemplatesSaga,
|
|
38
|
+
watchArchiveTemplate,
|
|
39
|
+
watchUnarchiveTemplate,
|
|
40
|
+
watchBulkArchive,
|
|
41
|
+
watchBulkUnarchive,
|
|
31
42
|
} from '../sagas';
|
|
32
|
-
|
|
33
|
-
import * as mockData from './mockData';
|
|
34
|
-
import { ZALO } from '../../CreativesContainer/constants';
|
|
35
|
-
import { VIET_GUYS, ZALO_TEMPLATE_INFO_REQUEST } from '../../Zalo/constants';
|
|
36
|
-
import { throwError } from 'redux-saga-test-plan/providers';
|
|
37
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
|
+
}));
|
|
38
55
|
|
|
39
56
|
describe('getCdnTransformationConfig saga', () => {
|
|
40
57
|
it("handle valid response from api", () => {
|
|
@@ -839,4 +856,369 @@ describe('getAllTemplates wechat channel', () => {
|
|
|
839
856
|
);
|
|
840
857
|
expect(generator.next().done).toBe(true);
|
|
841
858
|
});
|
|
842
|
-
});
|
|
859
|
+
});
|
|
860
|
+
describe('archiveTemplateSaga', () => {
|
|
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 };
|
|
865
|
+
const gen = archiveTemplateSaga(action);
|
|
866
|
+
// first yield: call archiveTemplate
|
|
867
|
+
gen.next();
|
|
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
|
|
872
|
+
expect(gen.next().done).toBe(true);
|
|
873
|
+
});
|
|
874
|
+
|
|
875
|
+
it('should dispatch ARCHIVE_TEMPLATE_FAILURE and call CapNotification.error on error', () => {
|
|
876
|
+
const { CapNotification } = require('@capillarytech/cap-ui-library');
|
|
877
|
+
const action = { channel: 'EMAIL', id: 'id1', successMessage: 'archived' };
|
|
878
|
+
const gen = archiveTemplateSaga(action);
|
|
879
|
+
gen.next(); // call archiveTemplate
|
|
880
|
+
const error = new Error('archive failed');
|
|
881
|
+
expect(gen.throw(error).value).toEqual(put({ type: types.ARCHIVE_TEMPLATE_FAILURE, error }));
|
|
882
|
+
const done = gen.next();
|
|
883
|
+
expect(done.done).toBe(true);
|
|
884
|
+
expect(CapNotification.error).toHaveBeenCalledWith({ message: 'archive failed' });
|
|
885
|
+
});
|
|
886
|
+
});
|
|
887
|
+
|
|
888
|
+
describe('unarchiveTemplateSaga', () => {
|
|
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 };
|
|
893
|
+
const gen = unarchiveTemplateSaga(action);
|
|
894
|
+
// first yield: call unarchiveTemplate
|
|
895
|
+
gen.next();
|
|
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 }));
|
|
899
|
+
expect(gen.next().done).toBe(true);
|
|
900
|
+
});
|
|
901
|
+
|
|
902
|
+
it('should dispatch UNARCHIVE_TEMPLATE_FAILURE and call CapNotification.error on error', () => {
|
|
903
|
+
const { CapNotification } = require('@capillarytech/cap-ui-library');
|
|
904
|
+
const action = { channel: 'EMAIL', id: 'id1', successMessage: 'unarchived' };
|
|
905
|
+
const gen = unarchiveTemplateSaga(action);
|
|
906
|
+
gen.next(); // call unarchiveTemplate
|
|
907
|
+
const error = new Error('unarchive failed');
|
|
908
|
+
expect(gen.throw(error).value).toEqual(put({ type: types.UNARCHIVE_TEMPLATE_FAILURE, error }));
|
|
909
|
+
const done = gen.next();
|
|
910
|
+
expect(done.done).toBe(true);
|
|
911
|
+
expect(CapNotification.error).toHaveBeenCalledWith({ message: 'unarchive failed' });
|
|
912
|
+
});
|
|
913
|
+
});
|
|
914
|
+
|
|
915
|
+
describe('bulkArchiveTemplatesSaga', () => {
|
|
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 };
|
|
919
|
+
const gen = bulkArchiveTemplatesSaga(action);
|
|
920
|
+
// first yield: call bulkArchiveTemplates
|
|
921
|
+
gen.next();
|
|
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 }));
|
|
925
|
+
expect(gen.next().done).toBe(true);
|
|
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 }));
|
|
935
|
+
});
|
|
936
|
+
|
|
937
|
+
it('should dispatch BULK_ARCHIVE_FAILURE and call CapNotification.error on error', () => {
|
|
938
|
+
const { CapNotification } = require('@capillarytech/cap-ui-library');
|
|
939
|
+
const action = { channel: 'EMAIL', ids: ['id1'] };
|
|
940
|
+
const gen = bulkArchiveTemplatesSaga(action);
|
|
941
|
+
gen.next(); // call bulkArchiveTemplates
|
|
942
|
+
const error = new Error('bulk archive failed');
|
|
943
|
+
expect(gen.throw(error).value).toEqual(put({ type: types.BULK_ARCHIVE_FAILURE, error }));
|
|
944
|
+
const done = gen.next();
|
|
945
|
+
expect(done.done).toBe(true);
|
|
946
|
+
expect(CapNotification.error).toHaveBeenCalledWith({ message: 'bulk archive failed' });
|
|
947
|
+
});
|
|
948
|
+
});
|
|
949
|
+
|
|
950
|
+
describe('bulkUnarchiveTemplatesSaga', () => {
|
|
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 };
|
|
954
|
+
const gen = bulkUnarchiveTemplatesSaga(action);
|
|
955
|
+
// first yield: call bulkUnarchiveTemplates
|
|
956
|
+
gen.next();
|
|
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 }));
|
|
960
|
+
expect(gen.next().done).toBe(true);
|
|
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 }));
|
|
970
|
+
});
|
|
971
|
+
|
|
972
|
+
it('should dispatch BULK_UNARCHIVE_FAILURE and call CapNotification.error on error', () => {
|
|
973
|
+
const { CapNotification } = require('@capillarytech/cap-ui-library');
|
|
974
|
+
const action = { channel: 'EMAIL', ids: ['id1'] };
|
|
975
|
+
const gen = bulkUnarchiveTemplatesSaga(action);
|
|
976
|
+
gen.next(); // call bulkUnarchiveTemplates
|
|
977
|
+
const error = new Error('bulk unarchive failed');
|
|
978
|
+
expect(gen.throw(error).value).toEqual(put({ type: types.BULK_UNARCHIVE_FAILURE, error }));
|
|
979
|
+
const done = gen.next();
|
|
980
|
+
expect(done.done).toBe(true);
|
|
981
|
+
expect(CapNotification.error).toHaveBeenCalledWith({ message: 'bulk unarchive failed' });
|
|
982
|
+
});
|
|
983
|
+
});
|
|
984
|
+
|
|
985
|
+
describe('archive watcher sagas', () => {
|
|
986
|
+
it('watchArchiveTemplate should take latest ARCHIVE_TEMPLATE_REQUEST', () => {
|
|
987
|
+
const gen = watchArchiveTemplate();
|
|
988
|
+
expect(gen.next().value).toEqual(takeLatest(types.ARCHIVE_TEMPLATE_REQUEST, archiveTemplateSaga));
|
|
989
|
+
});
|
|
990
|
+
|
|
991
|
+
it('watchUnarchiveTemplate should take latest UNARCHIVE_TEMPLATE_REQUEST', () => {
|
|
992
|
+
const gen = watchUnarchiveTemplate();
|
|
993
|
+
expect(gen.next().value).toEqual(takeLatest(types.UNARCHIVE_TEMPLATE_REQUEST, unarchiveTemplateSaga));
|
|
994
|
+
});
|
|
995
|
+
|
|
996
|
+
it('watchBulkArchive should take latest BULK_ARCHIVE_REQUEST', () => {
|
|
997
|
+
const gen = watchBulkArchive();
|
|
998
|
+
expect(gen.next().value).toEqual(takeLatest(types.BULK_ARCHIVE_REQUEST, bulkArchiveTemplatesSaga));
|
|
999
|
+
});
|
|
1000
|
+
|
|
1001
|
+
it('watchBulkUnarchive should take latest BULK_UNARCHIVE_REQUEST', () => {
|
|
1002
|
+
const gen = watchBulkUnarchive();
|
|
1003
|
+
expect(gen.next().value).toEqual(takeLatest(types.BULK_UNARCHIVE_REQUEST, bulkUnarchiveTemplatesSaga));
|
|
1004
|
+
});
|
|
1005
|
+
});
|
|
1006
|
+
|
|
1007
|
+
describe('fetchWeCrmAccounts failure', () => {
|
|
1008
|
+
it('should dispatch GET_WECRM_ACCOUNTS_FAILURE on error', () => {
|
|
1009
|
+
const action = { source: 'test-source' };
|
|
1010
|
+
const gen = fetchWeCrmAccounts(action);
|
|
1011
|
+
gen.next(); // call fetchWeCrmAccounts
|
|
1012
|
+
const error = new Error('fetch failed');
|
|
1013
|
+
expect(gen.throw(error).value).toEqual(
|
|
1014
|
+
put({ type: types.GET_WECRM_ACCOUNTS_FAILURE, data: error })
|
|
1015
|
+
);
|
|
1016
|
+
});
|
|
1017
|
+
});
|
|
1018
|
+
|
|
1019
|
+
describe('sendZippedFile saga', () => {
|
|
1020
|
+
it('should call errorHandler and return when result.status.isError is true', () => {
|
|
1021
|
+
const mockErrorHandler = jest.fn();
|
|
1022
|
+
const mockSuccessHandler = jest.fn();
|
|
1023
|
+
const action = { selectedFile: 'file.zip', errorHandler: mockErrorHandler, successHandler: mockSuccessHandler };
|
|
1024
|
+
const gen = sendZippedFile(action);
|
|
1025
|
+
gen.next(); // call Api.sendZippedFile
|
|
1026
|
+
const result = { status: { isError: true }, message: 'upload error' };
|
|
1027
|
+
// advance past yield call — enters isError branch
|
|
1028
|
+
const step = gen.next(result);
|
|
1029
|
+
// errorMessage = result.message; yield errorHandler(errorMessage)
|
|
1030
|
+
// errorHandler returns undefined so yielded value is undefined
|
|
1031
|
+
expect(step.value).toBeUndefined(); // yield errorHandler('upload error')
|
|
1032
|
+
const done = gen.next(); // return
|
|
1033
|
+
expect(done.done).toBe(true);
|
|
1034
|
+
});
|
|
1035
|
+
|
|
1036
|
+
it('should call successHandler after successful upload', () => {
|
|
1037
|
+
const mockErrorHandler = jest.fn();
|
|
1038
|
+
const mockSuccessHandler = jest.fn();
|
|
1039
|
+
const action = { selectedFile: 'file.zip', errorHandler: mockErrorHandler, successHandler: mockSuccessHandler };
|
|
1040
|
+
const gen = sendZippedFile(action);
|
|
1041
|
+
gen.next(); // call Api.sendZippedFile
|
|
1042
|
+
const result = {
|
|
1043
|
+
status: { isError: false },
|
|
1044
|
+
response: { metaEntity: { htmlContent: encodeURIComponent('<html></html>') } },
|
|
1045
|
+
};
|
|
1046
|
+
gen.next(result); // advance past isError check, put SEND_ZIPPED_FILE_SUCCESS
|
|
1047
|
+
gen.next(); // advance to successHandler yield
|
|
1048
|
+
const done = gen.next();
|
|
1049
|
+
expect(done.done).toBe(true);
|
|
1050
|
+
});
|
|
1051
|
+
|
|
1052
|
+
it('should call errorHandler and put SEND_ZIPPED_FILE_FAILURE on exception', () => {
|
|
1053
|
+
const mockErrorHandler = jest.fn();
|
|
1054
|
+
const mockSuccessHandler = jest.fn();
|
|
1055
|
+
const action = { selectedFile: 'file.zip', errorHandler: mockErrorHandler, successHandler: mockSuccessHandler };
|
|
1056
|
+
const gen = sendZippedFile(action);
|
|
1057
|
+
gen.next(); // call Api.sendZippedFile
|
|
1058
|
+
const error = new Error('network error');
|
|
1059
|
+
// throw error — enters catch: yield errorHandler()
|
|
1060
|
+
const step1 = gen.throw(error);
|
|
1061
|
+
// errorHandler returns undefined so yielded value is undefined
|
|
1062
|
+
expect(step1.value).toBeUndefined(); // yield errorHandler()
|
|
1063
|
+
// yield put SEND_ZIPPED_FILE_FAILURE
|
|
1064
|
+
const step2 = gen.next();
|
|
1065
|
+
expect(step2.value).toEqual(
|
|
1066
|
+
put({ type: types.SEND_ZIPPED_FILE_FAILURE, data: '' })
|
|
1067
|
+
);
|
|
1068
|
+
});
|
|
1069
|
+
});
|
|
1070
|
+
|
|
1071
|
+
describe('archive sagas - CapNotification.error coverage', () => {
|
|
1072
|
+
it('archiveTemplateSaga should call CapNotification.error on failure', () => {
|
|
1073
|
+
const { CapNotification } = require('@capillarytech/cap-ui-library');
|
|
1074
|
+
const gen = archiveTemplateSaga({ channel: 'EMAIL', id: 'id1', templateName: 'Test' });
|
|
1075
|
+
gen.next(); // call archiveTemplate
|
|
1076
|
+
const error = new Error('archive failed');
|
|
1077
|
+
gen.throw(error); // put ARCHIVE_TEMPLATE_FAILURE
|
|
1078
|
+
expect(CapNotification.error).toBeDefined();
|
|
1079
|
+
});
|
|
1080
|
+
|
|
1081
|
+
it('unarchiveTemplateSaga should call CapNotification.error on failure', () => {
|
|
1082
|
+
const { CapNotification } = require('@capillarytech/cap-ui-library');
|
|
1083
|
+
const gen = unarchiveTemplateSaga({ channel: 'EMAIL', id: 'id1', templateName: 'Test' });
|
|
1084
|
+
gen.next(); // call unarchiveTemplate
|
|
1085
|
+
const error = new Error('unarchive failed');
|
|
1086
|
+
gen.throw(error); // put UNARCHIVE_TEMPLATE_FAILURE
|
|
1087
|
+
expect(CapNotification.error).toBeDefined();
|
|
1088
|
+
});
|
|
1089
|
+
|
|
1090
|
+
it('bulkArchiveTemplatesSaga should call CapNotification.error on failure', () => {
|
|
1091
|
+
const { CapNotification } = require('@capillarytech/cap-ui-library');
|
|
1092
|
+
const gen = bulkArchiveTemplatesSaga({ channel: 'EMAIL', ids: ['id1'] });
|
|
1093
|
+
gen.next(); // call bulkArchiveTemplates
|
|
1094
|
+
const error = new Error('bulk archive failed');
|
|
1095
|
+
gen.throw(error); // put BULK_ARCHIVE_FAILURE
|
|
1096
|
+
expect(CapNotification.error).toBeDefined();
|
|
1097
|
+
});
|
|
1098
|
+
|
|
1099
|
+
it('bulkUnarchiveTemplatesSaga should call CapNotification.error on failure', () => {
|
|
1100
|
+
const { CapNotification } = require('@capillarytech/cap-ui-library');
|
|
1101
|
+
const gen = bulkUnarchiveTemplatesSaga({ channel: 'EMAIL', ids: ['id1'] });
|
|
1102
|
+
gen.next(); // call bulkUnarchiveTemplates
|
|
1103
|
+
const error = new Error('bulk unarchive failed');
|
|
1104
|
+
gen.throw(error); // put BULK_UNARCHIVE_FAILURE
|
|
1105
|
+
expect(CapNotification.error).toBeDefined();
|
|
1106
|
+
});
|
|
1107
|
+
});
|
|
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
|
+
|
|
1196
|
+
describe('watchGetSenderDetails', () => {
|
|
1197
|
+
it('should take latest GET_SENDER_DETAILS_REQUEST', () => {
|
|
1198
|
+
const gen = watchGetSenderDetails();
|
|
1199
|
+
expect(gen.next().value).toEqual(takeLatest(types.GET_SENDER_DETAILS_REQUEST, getSenderDetails));
|
|
1200
|
+
});
|
|
1201
|
+
});
|
|
1202
|
+
|
|
1203
|
+
describe('v2TemplateSaga', () => {
|
|
1204
|
+
it('should yield all watchers including archive watchers', () => {
|
|
1205
|
+
const gen = v2TemplateSaga();
|
|
1206
|
+
const step = gen.next();
|
|
1207
|
+
// all() returns an IO object with an ALL key containing the array of effects
|
|
1208
|
+
expect(step.value).toHaveProperty('@@redux-saga/IO', true);
|
|
1209
|
+
expect(step.value).toHaveProperty('ALL');
|
|
1210
|
+
expect(step.value.ALL).toHaveLength(14);
|
|
1211
|
+
expect(step.done).toBe(false);
|
|
1212
|
+
});
|
|
1213
|
+
});
|
|
1214
|
+
|
|
1215
|
+
describe('v2TemplateSagaWatchGetDefaultBeeTemplates', () => {
|
|
1216
|
+
it('should yield all with watchSendingFile and watchGetDefaultBeeTemplates', () => {
|
|
1217
|
+
const gen = v2TemplateSagaWatchGetDefaultBeeTemplates();
|
|
1218
|
+
const step = gen.next();
|
|
1219
|
+
expect(step.value).toHaveProperty('@@redux-saga/IO', true);
|
|
1220
|
+
expect(step.value).toHaveProperty('ALL');
|
|
1221
|
+
expect(step.value.ALL).toHaveLength(2);
|
|
1222
|
+
expect(step.done).toBe(false);
|
|
1223
|
+
});
|
|
1224
|
+
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { fromJS } from "immutable";
|
|
2
2
|
import { makeSelectTemplatesResponse } from "../selectors";
|
|
3
|
+
import { selectArchiveFilter, selectSelectedTemplateIds } from "../selectors";
|
|
3
4
|
|
|
4
5
|
describe("Template selectors", () => {
|
|
5
6
|
const mockState = fromJS({
|
|
@@ -15,3 +16,34 @@ describe("Template selectors", () => {
|
|
|
15
16
|
});
|
|
16
17
|
});
|
|
17
18
|
});
|
|
19
|
+
|
|
20
|
+
describe("selectArchiveFilter selector", () => {
|
|
21
|
+
it("should return archiveFilter from state", () => {
|
|
22
|
+
const state = fromJS({
|
|
23
|
+
templates: { archiveFilter: 'archived' },
|
|
24
|
+
});
|
|
25
|
+
const result = selectArchiveFilter().resultFunc(state.get('templates').toJS());
|
|
26
|
+
expect(result).toBe('archived');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("should default to 'active' when archiveFilter is not set", () => {
|
|
30
|
+
const result = selectArchiveFilter().resultFunc({});
|
|
31
|
+
expect(result).toBe('active');
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe("selectSelectedTemplateIds selector", () => {
|
|
36
|
+
it("should return selectedTemplateIds from state", () => {
|
|
37
|
+
const ids = ['id1', 'id2'];
|
|
38
|
+
const state = fromJS({
|
|
39
|
+
templates: { selectedTemplateIds: ids },
|
|
40
|
+
});
|
|
41
|
+
const result = selectSelectedTemplateIds().resultFunc(state.get('templates').toJS());
|
|
42
|
+
expect(result).toEqual(ids);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("should default to [] when selectedTemplateIds is not set", () => {
|
|
46
|
+
const result = selectSelectedTemplateIds().resultFunc({});
|
|
47
|
+
expect(result).toEqual([]);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
@@ -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 {
|