@capillarytech/creatives-library 9.0.56-alpha.6 → 9.0.56-betaa.0
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 +4 -2
- package/package.json +1 -1
- package/services/api.js +0 -20
- package/utils/common.js +12 -0
- package/utils/templateVarUtils.js +0 -32
- package/utils/tests/templateVarUtils.test.js +0 -44
- package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +0 -14
- package/v2Components/CommonTestAndPreview/actions.js +0 -13
- package/v2Components/CommonTestAndPreview/constants.js +0 -8
- package/v2Components/CommonTestAndPreview/index.js +2 -57
- package/v2Components/CommonTestAndPreview/reducer.js +0 -20
- package/v2Components/CommonTestAndPreview/sagas.js +0 -28
- package/v2Components/CommonTestAndPreview/selectors.js +0 -6
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +0 -106
- package/v2Components/CommonTestAndPreview/tests/actions.test.js +0 -15
- package/v2Components/CommonTestAndPreview/tests/constants.test.js +1 -9
- package/v2Components/CommonTestAndPreview/tests/index.test.js +0 -101
- package/v2Components/CommonTestAndPreview/tests/reducer.test.js +0 -41
- package/v2Components/CommonTestAndPreview/tests/sagas.test.js +0 -84
- package/v2Components/CommonTestAndPreview/tests/selectors.test.js +0 -12
- package/v2Components/FormBuilder/Functional/FormBuilderShell.js +320 -46
- package/v2Components/FormBuilder/Functional/channels/mobilepush/buildSubmitPayload.js +10 -0
- package/v2Components/FormBuilder/Functional/channels/mobilepush/config.js +82 -0
- package/v2Components/FormBuilder/Functional/channels/mobilepush/getEditorErrorDescriptor.js +74 -0
- package/v2Components/FormBuilder/Functional/channels/mobilepush/index.js +28 -0
- package/v2Components/FormBuilder/Functional/channels/mobilepush/modals.js +19 -0
- package/v2Components/FormBuilder/Functional/channels/mobilepush/runSubmitPipeline.js +45 -0
- package/v2Components/FormBuilder/Functional/channels/mobilepush/tests/getEditorErrorDescriptor.test.js +162 -0
- package/v2Components/FormBuilder/Functional/channels/mobilepush/tests/modals.test.js +37 -0
- package/v2Components/FormBuilder/Functional/channels/mobilepush/tests/runSubmitPipeline.test.js +70 -0
- package/v2Components/FormBuilder/Functional/channels/mobilepush/tests/validate.test.js +274 -0
- package/v2Components/FormBuilder/Functional/channels/mobilepush/validate.js +251 -0
- package/v2Components/FormBuilder/Functional/channels/registry.js +2 -0
- package/v2Components/FormBuilder/Functional/constants.js +43 -8
- package/v2Components/FormBuilder/Functional/core/schema/initializeFormState.js +175 -28
- package/v2Components/FormBuilder/Functional/core/store/formReducer.js +75 -6
- package/v2Components/FormBuilder/Functional/core/store/toLegacyFormData.js +10 -20
- package/v2Components/FormBuilder/Functional/layout/FieldSlot.js +9 -1
- package/v2Components/FormBuilder/Functional/layout/SchemaForm.js +20 -3
- package/v2Components/FormBuilder/Functional/layout/Section.js +6 -1
- package/v2Components/FormBuilder/Functional/layout/TabsContainer.js +89 -0
- package/v2Components/FormBuilder/Functional/renderers/mpushRenderers.js +440 -0
- package/v2Components/FormBuilder/Functional/tests/fieldSlot.test.js +9 -2
- package/v2Components/FormBuilder/Functional/tests/mpush.crossFlowParity.test.js +430 -0
- package/v2Components/FormBuilder/Functional/tests/mpush.ctaFlows.parity.test.js +282 -0
- package/v2Components/FormBuilder/Functional/tests/mpush.editContainer.parity.test.js +141 -0
- package/v2Components/FormBuilder/Functional/tests/mpush.engine.test.js +306 -0
- package/v2Components/FormBuilder/Functional/tests/mpush.shellEvents.test.js +151 -0
- package/v2Components/FormBuilder/Functional/tests/mpushRenderers.test.js +342 -0
- package/v2Components/FormBuilder/Functional/tests/schemaForm.test.js +17 -0
- package/v2Components/FormBuilder/Functional/tests/tabsContainer.test.js +110 -0
- package/v2Components/FormBuilder/index.js +34 -12
- package/v2Components/FormBuilder/tests/entryGate.test.js +94 -7
- package/v2Components/FormBuilder/tests/mpush.characterization.test.js +459 -0
- package/v2Components/TestAndPreviewSlidebox/index.js +0 -9
- package/v2Containers/CommunicationFlow/CommunicationFlow.js +75 -128
- package/v2Containers/CommunicationFlow/CommunicationFlow.scss +2 -30
- package/v2Containers/CommunicationFlow/CommunicationFlowCard.js +27 -58
- package/v2Containers/CommunicationFlow/Tests/CommunicationFlow.test.js +51 -471
- package/v2Containers/CommunicationFlow/Tests/CommunicationFlowCard.test.js +4 -40
- package/v2Containers/CommunicationFlow/constants.js +4 -67
- package/v2Containers/CommunicationFlow/index.js +23 -16
- package/v2Containers/CommunicationFlow/messages.js +3 -7
- package/v2Containers/CommunicationFlow/steps/ChannelSelectionStep/ChannelSelectionStep.js +10 -22
- package/v2Containers/CommunicationFlow/steps/ChannelSelectionStep/ChannelSelectionStep.scss +0 -4
- package/v2Containers/CommunicationFlow/steps/ChannelSelectionStep/Tests/ChannelSelectionStep.test.js +4 -112
- package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/DeliverySettingsSection.js +0 -3
- package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/SenderDetails.js +0 -6
- package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/SenderDetails.test.js +0 -25
- package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/deliverySettingsConfig.test.js +4 -11
- package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/deliverySettingsConfig.js +5 -19
- package/v2Containers/CreativesContainer/index.js +3 -2
- package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +5 -5
- package/v2Containers/CreativesContainer/tests/index.test.js +0 -12
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +19 -115
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +3 -27
- package/v2Containers/WebPush/Create/preview/WebPushPreview.js +12 -17
- package/v2Containers/WebPush/Create/preview/tests/WebPushPreview.test.js +0 -5
- package/v2Containers/Whatsapp/index.js +3 -8
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +34 -306
- package/v2Containers/mockdata.js +0 -25
- package/v2Containers/CommunicationFlow/Tests/constants.test.js +0 -85
package/constants/unified.js
CHANGED
|
@@ -45,9 +45,10 @@ export const GIFT_CARDS = 'GIFT_CARDS';
|
|
|
45
45
|
export const PROMO_ENGINE = 'PROMO_ENGINE';
|
|
46
46
|
export const ENABLE_NEW_MPUSH = 'ENABLE_NEW_MPUSH';
|
|
47
47
|
export const ENABLE_NEW_EDITOR_FLOW_INAPP = 'ENABLE_NEW_EDITOR_FLOW_INAPP';
|
|
48
|
-
// Per-channel
|
|
49
|
-
// new functional FormBuilder; later channels get their own flags (…
|
|
48
|
+
// Per-channel flags for the FormBuilder V3 migration. Each routes its channel to
|
|
49
|
+
// the new functional FormBuilder; later channels get their own flags (…_EMAIL).
|
|
50
50
|
export const ENABLE_NEW_FORMBUILDER_SMS = 'ENABLE_NEW_FORMBUILDER_SMS';
|
|
51
|
+
export const ENABLE_NEW_FORMBUILDER_MPUSH = 'ENABLE_NEW_FORMBUILDER_MPUSH';
|
|
51
52
|
export const SUPPORT_CK_EDITOR = 'SUPPORT_CK_EDITOR';
|
|
52
53
|
export const CUSTOM_TAG = 'CustomTagMessage';
|
|
53
54
|
export const CUSTOMER_EXTENDED_FIELD = 'Customer extended fields';
|
|
@@ -63,6 +64,7 @@ export const ENABLE_AI_SUGGESTIONS = 'ENABLE_AI_SUGGESTIONS';
|
|
|
63
64
|
export const AI_CONTENT_BOT_DISABLED = 'AI_CONTENT_BOT_DISABLED';
|
|
64
65
|
export const AI_DOCUMENTATION_BOT_ENABLED = 'AI_DOCUMENTATION_BOT_ENABLED';
|
|
65
66
|
export const ENABLE_PRODUCT_SUPPORT_VIDEOS = 'ENABLE_PRODUCT_SUPPORT_VIDEOS';
|
|
67
|
+
export const SUPPORT_ENGAGEMENT_MODULE = 'SUPPORT_ENGAGEMENT_MODULE';
|
|
66
68
|
export const EMBEDDED = 'embedded';
|
|
67
69
|
// --- Tag/Validation Constants ---
|
|
68
70
|
export const CARD_RELATED_TAGS = [
|
package/package.json
CHANGED
package/services/api.js
CHANGED
|
@@ -701,26 +701,6 @@ export const createCentralCommsMetaId = (payload, metaType = TRANSACTION) => {
|
|
|
701
701
|
return request(url, getAPICallObject('POST', payload, false, false, false, true));
|
|
702
702
|
};
|
|
703
703
|
|
|
704
|
-
// CCS CommDefinition API, proxied through cap-creatives-api; used by CommunicationFlow's Save, while legacy messageMeta functions remain for CreativesContainer's save flow.
|
|
705
|
-
const COMM_DEFINITIONS_PATH = `${API_ENDPOINT}/comm-definitions`;
|
|
706
|
-
|
|
707
|
-
export const createCommDefinition = (payload) => {
|
|
708
|
-
const url = COMM_DEFINITIONS_PATH;
|
|
709
|
-
return request(url, getAPICallObject('POST', payload, false, false, false, true));
|
|
710
|
-
};
|
|
711
|
-
|
|
712
|
-
// Opens a new DRAFT version on an existing CommDefinition, preserving its id/referenceId.
|
|
713
|
-
export const editCommDefinition = (commDefinitionId, payload) => {
|
|
714
|
-
const url = `${COMM_DEFINITIONS_PATH}/${commDefinitionId}/edit`;
|
|
715
|
-
return request(url, getAPICallObject('POST', payload, false, false, false, true));
|
|
716
|
-
};
|
|
717
|
-
|
|
718
|
-
// notify/ui's "Send test" uses this instead of the legacy createMessageMeta/sendTestMessage flow.
|
|
719
|
-
export const sendTransactionalComm = (payload) => {
|
|
720
|
-
const url = `${COMM_DEFINITIONS_PATH}/send/transaction`;
|
|
721
|
-
return request(url, getAPICallObject('POST', payload, false, false, false, true));
|
|
722
|
-
};
|
|
723
|
-
|
|
724
704
|
export const getCentralCommsMetaIds = (metaIds, metaType = TRANSACTION) => {
|
|
725
705
|
const url = `${API_ENDPOINT}/common/central-comms/meta-id/${metaType}?metaIds=${metaIds}`;
|
|
726
706
|
return request(url, getAPICallObject('GET', null, false, false, false, true));
|
package/utils/common.js
CHANGED
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
ENABLE_NEW_MPUSH,
|
|
28
28
|
ENABLE_NEW_EDITOR_FLOW_INAPP,
|
|
29
29
|
ENABLE_NEW_FORMBUILDER_SMS,
|
|
30
|
+
ENABLE_NEW_FORMBUILDER_MPUSH,
|
|
30
31
|
SUPPORT_ENGAGEMENT_MODULE,
|
|
31
32
|
ENABLE_CREATIVES_ARCHIVAL,
|
|
32
33
|
} from '../constants/unified';
|
|
@@ -99,6 +100,10 @@ export const hasSupportCKEditor = Auth.hasFeatureAccess.bind(
|
|
|
99
100
|
null,
|
|
100
101
|
SUPPORT_CK_EDITOR,
|
|
101
102
|
);
|
|
103
|
+
export const hasSupportEngagementModule = Auth.hasFeatureAccess.bind(
|
|
104
|
+
null,
|
|
105
|
+
SUPPORT_ENGAGEMENT_MODULE,
|
|
106
|
+
);
|
|
102
107
|
|
|
103
108
|
export const hasGiftVoucherFeature = Auth.hasFeatureAccess.bind(
|
|
104
109
|
null,
|
|
@@ -166,6 +171,13 @@ export const hasNewFormBuilderEnabledForSms = Auth.hasFeatureAccess.bind(
|
|
|
166
171
|
ENABLE_NEW_FORMBUILDER_SMS,
|
|
167
172
|
);
|
|
168
173
|
|
|
174
|
+
// FormBuilder V3 — per-org flag that routes the MOBILEPUSH channel to the new
|
|
175
|
+
// functional FormBuilder. Off => the legacy class implementation (Classic).
|
|
176
|
+
export const hasNewFormBuilderEnabledForMpush = Auth.hasFeatureAccess.bind(
|
|
177
|
+
null,
|
|
178
|
+
ENABLE_NEW_FORMBUILDER_MPUSH,
|
|
179
|
+
);
|
|
180
|
+
|
|
169
181
|
//filtering tags based on scope
|
|
170
182
|
export const filterTags = (tagsToFilter, tagsList) => tagsList?.filter(
|
|
171
183
|
(tag) => !tagsToFilter?.includes(tag?.definition?.value)
|
|
@@ -115,38 +115,6 @@ export const extractTemplateVariables = (templateStr = '', captureRegex) => {
|
|
|
115
115
|
return variables;
|
|
116
116
|
};
|
|
117
117
|
|
|
118
|
-
/**
|
|
119
|
-
* Reconciles a var-value map from an external source (e.g. a saved CommDefinition) into this
|
|
120
|
-
* UI's own `${token}_${segmentIndex}` slot-key format used by the WhatsApp/RCS editors' own
|
|
121
|
-
* text-merge logic.
|
|
122
|
-
*
|
|
123
|
-
* Two shapes are recognized:
|
|
124
|
-
* - Slot format: keys already look like `${token}_${index}` (contain an underscore) — used as-is.
|
|
125
|
-
* - CCS format: keys are plain sequential occurrence indices ("0", "1", ...), one per variable in
|
|
126
|
-
* template order — unrelated to this UI's own array-position indexing (which depends on how many
|
|
127
|
-
* plain-text segments fall between variables) — so it's remapped by walking `segments` in order
|
|
128
|
-
* and assigning the Nth variable occurrence to `rawVarMap[N]`.
|
|
129
|
-
*
|
|
130
|
-
* @param {Object} rawVarMap
|
|
131
|
-
* @param {string[]} segments - text+var segments, e.g. from `splitContentByOrderedVarTokens`
|
|
132
|
-
* @param {RegExp} regex - matches a variable token
|
|
133
|
-
* @returns {Object} `${token}_${segmentIndex}` -> value
|
|
134
|
-
*/
|
|
135
|
-
export const reconcileVarMapToSlotFormat = (rawVarMap = {}, segments = [], regex) => {
|
|
136
|
-
if (Object.keys(rawVarMap ?? {}).length === 0) return {};
|
|
137
|
-
const isSlotFormat = Object.keys(rawVarMap).some((key) => key.includes('_'));
|
|
138
|
-
if (isSlotFormat) return { ...rawVarMap };
|
|
139
|
-
const slotMap = {};
|
|
140
|
-
let occurrenceIndex = 0;
|
|
141
|
-
(segments ?? []).forEach((segment, segmentIndex) => {
|
|
142
|
-
if (typeof segment === 'string' && (segment.match(regex) || []).length > 0) {
|
|
143
|
-
slotMap[`${segment}_${segmentIndex}`] = rawVarMap[occurrenceIndex] ?? '';
|
|
144
|
-
occurrenceIndex += 1;
|
|
145
|
-
}
|
|
146
|
-
});
|
|
147
|
-
return slotMap;
|
|
148
|
-
};
|
|
149
|
-
|
|
150
118
|
/**
|
|
151
119
|
* Looks up the inner name of a `{{name}}` or `{#name#}` token in a flat key→value map.
|
|
152
120
|
* Handles both exact matches and dot-path suffixes (e.g. `tag.FORMAT_1` → name `FORMAT_1`).
|
|
@@ -6,11 +6,8 @@ import {
|
|
|
6
6
|
getFallbackResolvedContentForCardDisplay,
|
|
7
7
|
isDltHashVarToken,
|
|
8
8
|
isAnyTemplateVarToken,
|
|
9
|
-
reconcileVarMapToSlotFormat,
|
|
10
9
|
} from '../templateVarUtils';
|
|
11
10
|
|
|
12
|
-
const MUSTACHE_VAR_REGEX = /\{\{\d+\}\}/g;
|
|
13
|
-
|
|
14
11
|
describe('templateVarUtils', () => {
|
|
15
12
|
describe('splitContentByOrderedVarTokens', () => {
|
|
16
13
|
it('pushes remainder when next token is not found in string', () => {
|
|
@@ -204,45 +201,4 @@ describe('templateVarUtils', () => {
|
|
|
204
201
|
expect(getFallbackResolvedContent('{#a#}', {}, { a: '' })).toBe('{#a#}');
|
|
205
202
|
});
|
|
206
203
|
});
|
|
207
|
-
|
|
208
|
-
describe('reconcileVarMapToSlotFormat', () => {
|
|
209
|
-
it('returns an empty object for an empty/absent rawVarMap', () => {
|
|
210
|
-
expect(reconcileVarMapToSlotFormat({}, ['{{1}}'], MUSTACHE_VAR_REGEX)).toEqual({});
|
|
211
|
-
expect(reconcileVarMapToSlotFormat(undefined, ['{{1}}'], MUSTACHE_VAR_REGEX)).toEqual({});
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
it('uses slot-format keys (containing an underscore) as-is', () => {
|
|
215
|
-
const rawVarMap = { '{{1}}_1': 'test', '{{2}}_3': 'test2' };
|
|
216
|
-
expect(
|
|
217
|
-
reconcileVarMapToSlotFormat(rawVarMap, ['x', '{{1}}', 'y', '{{2}}'], MUSTACHE_VAR_REGEX),
|
|
218
|
-
).toEqual(rawVarMap);
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
it('remaps CCS-format sequential-occurrence-index keys ("0","1",...) onto this UI\'s own slot keys (regression: CCS sends plain occurrence indices, not this UI\'s `${token}_${arrayIndex}` format, which silently blanked WhatsApp edit fields and desynced the segment array)', () => {
|
|
222
|
-
// Mirrors the real CCS response: "Hi! Here is your latest tier progress summary with us.\n\nTo
|
|
223
|
-
// move up to the next tier, you still need to spend {{1}} more,\nearn {{2}} more points, ..."
|
|
224
|
-
// — varMapped keys "0".."10" map to {{1}}.."{{11}}" in template order.
|
|
225
|
-
const segments = [
|
|
226
|
-
'spend ',
|
|
227
|
-
'{{1}}',
|
|
228
|
-
' more,\nearn ',
|
|
229
|
-
'{{2}}',
|
|
230
|
-
' more points',
|
|
231
|
-
];
|
|
232
|
-
const rawVarMap = { 0: 'dasda', 1: 'dasd' };
|
|
233
|
-
expect(reconcileVarMapToSlotFormat(rawVarMap, segments, MUSTACHE_VAR_REGEX)).toEqual({
|
|
234
|
-
'{{1}}_1': 'dasda',
|
|
235
|
-
'{{2}}_3': 'dasd',
|
|
236
|
-
});
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
it('defaults a missing occurrence-index entry to an empty string rather than dropping the slot', () => {
|
|
240
|
-
const segments = ['a ', '{{1}}', ' b ', '{{2}}'];
|
|
241
|
-
const rawVarMap = { 0: 'filled' }; // no entry for occurrence index 1
|
|
242
|
-
expect(reconcileVarMapToSlotFormat(rawVarMap, segments, MUSTACHE_VAR_REGEX)).toEqual({
|
|
243
|
-
'{{1}}_1': 'filled',
|
|
244
|
-
'{{2}}_3': '',
|
|
245
|
-
});
|
|
246
|
-
});
|
|
247
|
-
});
|
|
248
204
|
});
|
|
@@ -139,20 +139,6 @@ const UnifiedPreview = ({
|
|
|
139
139
|
);
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
-
case CHANNELS.LINE:
|
|
143
|
-
// LINE carries a single plain-text message today, so it reuses the SMS chat-bubble
|
|
144
|
-
// preview. Rich types (image/video/sticker/imageMap/carousel/flex) aren't rendered yet.
|
|
145
|
-
return (
|
|
146
|
-
<SmsPreviewContent
|
|
147
|
-
content={typeof content === 'string' ? content : (content?.resolvedBody || '')}
|
|
148
|
-
device={device}
|
|
149
|
-
isUpdating={isUpdating}
|
|
150
|
-
error={error}
|
|
151
|
-
formatMessage={formatMessage}
|
|
152
|
-
showHeader={showHeader}
|
|
153
|
-
/>
|
|
154
|
-
);
|
|
155
|
-
|
|
156
142
|
case CHANNELS.WHATSAPP: {
|
|
157
143
|
// WhatsApp content is an object with templateMsg, media, CTA, etc.
|
|
158
144
|
const whatsappContent = typeof content === 'object' ? content : {};
|
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
EXTRACT_TAGS_REQUESTED,
|
|
11
11
|
UPDATE_PREVIEW_REQUESTED,
|
|
12
12
|
SEND_TEST_MESSAGE_REQUESTED,
|
|
13
|
-
SEND_CCS_TEST_MESSAGE_REQUESTED,
|
|
14
13
|
CLEAR_CUSTOMER_SEARCH_STATE,
|
|
15
14
|
GET_TEST_CUSTOMERS_REQUESTED,
|
|
16
15
|
GET_TEST_GROUPS_REQUESTED,
|
|
@@ -66,18 +65,6 @@ export const sendTestMessageRequested = (payload, callback) => ({
|
|
|
66
65
|
callback,
|
|
67
66
|
});
|
|
68
67
|
|
|
69
|
-
/**
|
|
70
|
-
* notify/ui only — send a test message through CCS's send/transaction endpoint
|
|
71
|
-
* against a real CommDefinition, instead of the legacy createMessageMeta/sendTestMessage flow.
|
|
72
|
-
* @param {Object} payload - { commDefinitionId|referenceId, uniqueKey, isTest, recipient }
|
|
73
|
-
* @param {Function} callback - Success/error callback
|
|
74
|
-
*/
|
|
75
|
-
export const sendCcsTestMessageRequested = (payload, callback) => ({
|
|
76
|
-
type: SEND_CCS_TEST_MESSAGE_REQUESTED,
|
|
77
|
-
payload,
|
|
78
|
-
callback,
|
|
79
|
-
});
|
|
80
|
-
|
|
81
68
|
/**
|
|
82
69
|
* Clear all customer search state
|
|
83
70
|
*/
|
|
@@ -29,11 +29,6 @@ export const SEND_TEST_MESSAGE_REQUESTED = 'app/CommonTestAndPreview/SEND_TEST_M
|
|
|
29
29
|
export const SEND_TEST_MESSAGE_SUCCESS = 'app/CommonTestAndPreview/SEND_TEST_MESSAGE_SUCCESS';
|
|
30
30
|
export const SEND_TEST_MESSAGE_FAILURE = 'app/CommonTestAndPreview/SEND_TEST_MESSAGE_FAILURE';
|
|
31
31
|
|
|
32
|
-
// Send CCS Test Message (notify/ui — send/transaction against a real CommDefinition)
|
|
33
|
-
export const SEND_CCS_TEST_MESSAGE_REQUESTED = 'app/CommonTestAndPreview/SEND_CCS_TEST_MESSAGE_REQUESTED';
|
|
34
|
-
export const SEND_CCS_TEST_MESSAGE_SUCCESS = 'app/CommonTestAndPreview/SEND_CCS_TEST_MESSAGE_SUCCESS';
|
|
35
|
-
export const SEND_CCS_TEST_MESSAGE_FAILURE = 'app/CommonTestAndPreview/SEND_CCS_TEST_MESSAGE_FAILURE';
|
|
36
|
-
|
|
37
32
|
// Test Customers
|
|
38
33
|
export const GET_TEST_CUSTOMERS_REQUESTED = 'app/CommonTestAndPreview/GET_TEST_CUSTOMERS_REQUESTED';
|
|
39
34
|
export const GET_TEST_CUSTOMERS_SUCCESS = 'app/CommonTestAndPreview/GET_TEST_CUSTOMERS_SUCCESS';
|
|
@@ -90,7 +85,6 @@ export const CHANNELS = {
|
|
|
90
85
|
VIBER: 'VIBER',
|
|
91
86
|
ZALO: 'ZALO',
|
|
92
87
|
WEBPUSH: 'WEBPUSH',
|
|
93
|
-
LINE: 'LINE',
|
|
94
88
|
};
|
|
95
89
|
|
|
96
90
|
/** Unified preview tab keys when RCS shows RCS + SMS fallback panes. */
|
|
@@ -106,7 +100,6 @@ export const CHANNELS_USING_ANDROID_PREVIEW_DEVICE = [
|
|
|
106
100
|
CHANNELS.INAPP,
|
|
107
101
|
CHANNELS.MOBILEPUSH,
|
|
108
102
|
CHANNELS.VIBER,
|
|
109
|
-
CHANNELS.LINE,
|
|
110
103
|
];
|
|
111
104
|
|
|
112
105
|
/** RCS createMessageMeta test payload — rich card envelope literals. */
|
|
@@ -297,7 +290,6 @@ export const ERROR_MESSAGES = {
|
|
|
297
290
|
FAILED_TO_EXTRACT_TAGS: 'Failed to extract tags',
|
|
298
291
|
FAILED_TO_UPDATE_PREVIEW: 'Failed to update preview',
|
|
299
292
|
FAILED_TO_SEND_TEST_EMAIL: 'Failed to send test email',
|
|
300
|
-
FAILED_TO_SEND_CCS_TEST_MESSAGE: 'Failed to send test message',
|
|
301
293
|
PROFILE_IS_EMPTY: 'Profile is empty',
|
|
302
294
|
NO_TEST_CUSTOMERS_FOUND: 'No test customers found',
|
|
303
295
|
FAILED_TO_FETCH_TEST_CUSTOMERS: 'Failed to fetch test customers',
|
|
@@ -200,7 +200,6 @@ const CommonTestAndPreview = (props) => {
|
|
|
200
200
|
messageMetaConfigId,
|
|
201
201
|
prefilledValues,
|
|
202
202
|
isSendingTestMessage,
|
|
203
|
-
isSendingCcsTestMessage,
|
|
204
203
|
updatePreviewError,
|
|
205
204
|
updatePreviewErrors,
|
|
206
205
|
fetchPrefilledValuesError,
|
|
@@ -209,8 +208,6 @@ const CommonTestAndPreview = (props) => {
|
|
|
209
208
|
wecrmAccounts = [],
|
|
210
209
|
isLoadingSenderDetails = false,
|
|
211
210
|
orgUnitId = -1,
|
|
212
|
-
// notify/ui only: { commDefinitionId, referenceId } — routes "Send test" to CCS's send/transaction endpoint.
|
|
213
|
-
ccsSendTransaction,
|
|
214
211
|
// Email-specific props
|
|
215
212
|
beeInstance,
|
|
216
213
|
currentTab = 1,
|
|
@@ -3628,52 +3625,7 @@ const CommonTestAndPreview = (props) => {
|
|
|
3628
3625
|
/**
|
|
3629
3626
|
* Handle send test message
|
|
3630
3627
|
*/
|
|
3631
|
-
// notify/ui: send the test through CCS's own send/transaction endpoint against the alert's
|
|
3632
|
-
// real CommDefinition, instead of the legacy createMessageMeta/sendTestMessage flow below.
|
|
3633
|
-
// Dispatched via the same action/saga pattern as every other API call in this component,
|
|
3634
|
-
// rather than calling Api.sendTransactionalComm directly.
|
|
3635
|
-
const handleCcsSendTestMessage = () => {
|
|
3636
|
-
const allUserIds = [];
|
|
3637
|
-
selectedTestEntities.forEach((entityId) => {
|
|
3638
|
-
const group = testGroups.find((testGroup) => testEntityIdsEqual(testGroup.groupId, entityId));
|
|
3639
|
-
if (group) {
|
|
3640
|
-
allUserIds.push(...group.userIds);
|
|
3641
|
-
} else {
|
|
3642
|
-
allUserIds.push(entityId);
|
|
3643
|
-
}
|
|
3644
|
-
});
|
|
3645
|
-
const uniqueUserIds = [...new Set(allUserIds)];
|
|
3646
|
-
const { commDefinitionId, referenceId } = ccsSendTransaction;
|
|
3647
|
-
|
|
3648
|
-
actions.sendCcsTestMessageRequested(
|
|
3649
|
-
{
|
|
3650
|
-
...(commDefinitionId ? { commDefinitionId } : { referenceId }),
|
|
3651
|
-
uniqueKey: `test_${Date.now()}`,
|
|
3652
|
-
isTest: true,
|
|
3653
|
-
recipient: {
|
|
3654
|
-
identifiers: uniqueUserIds.map((userId) => ({ type: 'USER_ID', value: String(userId) })),
|
|
3655
|
-
tagValues: customValues,
|
|
3656
|
-
},
|
|
3657
|
-
},
|
|
3658
|
-
(success) => {
|
|
3659
|
-
if (success) {
|
|
3660
|
-
CapNotification.success({
|
|
3661
|
-
message: formatMessage(messages.testMessageSent),
|
|
3662
|
-
});
|
|
3663
|
-
} else {
|
|
3664
|
-
CapNotification.error({
|
|
3665
|
-
message: formatMessage(messages.testMessageFailed),
|
|
3666
|
-
});
|
|
3667
|
-
}
|
|
3668
|
-
},
|
|
3669
|
-
);
|
|
3670
|
-
};
|
|
3671
|
-
|
|
3672
3628
|
const handleSendTestMessage = () => {
|
|
3673
|
-
if (ccsSendTransaction) {
|
|
3674
|
-
handleCcsSendTestMessage();
|
|
3675
|
-
return;
|
|
3676
|
-
}
|
|
3677
3629
|
const allUserIds = [];
|
|
3678
3630
|
selectedTestEntities.forEach((entityId) => {
|
|
3679
3631
|
const group = testGroups.find((testGroup) => testEntityIdsEqual(testGroup.groupId, entityId));
|
|
@@ -3811,7 +3763,7 @@ const CommonTestAndPreview = (props) => {
|
|
|
3811
3763
|
formData={formDataForSendTest}
|
|
3812
3764
|
content={getCurrentContent}
|
|
3813
3765
|
channel={channel}
|
|
3814
|
-
isSendingTestMessage={isSendingTestMessage
|
|
3766
|
+
isSendingTestMessage={isSendingTestMessage}
|
|
3815
3767
|
renderAddTestCustomerButton={renderAddTestCustomerButton}
|
|
3816
3768
|
formatMessage={formatMessage}
|
|
3817
3769
|
deliverySettings={testPreviewDeliverySettings[channel]}
|
|
@@ -3864,7 +3816,7 @@ const CommonTestAndPreview = (props) => {
|
|
|
3864
3816
|
header={slideboxHeader}
|
|
3865
3817
|
handleClose={handleClose}
|
|
3866
3818
|
show={show}
|
|
3867
|
-
size="size-
|
|
3819
|
+
size="size-xl"
|
|
3868
3820
|
content={(
|
|
3869
3821
|
<CapSpin
|
|
3870
3822
|
spinning={isCustomerDataLoading}
|
|
@@ -3961,16 +3913,11 @@ CommonTestAndPreview.propTypes = {
|
|
|
3961
3913
|
message: PropTypes.string,
|
|
3962
3914
|
})),
|
|
3963
3915
|
isSendingTestMessage: PropTypes.bool.isRequired,
|
|
3964
|
-
isSendingCcsTestMessage: PropTypes.bool,
|
|
3965
3916
|
intl: PropTypes.object.isRequired,
|
|
3966
3917
|
senderDetailsByChannel: PropTypes.object,
|
|
3967
3918
|
wecrmAccounts: PropTypes.array,
|
|
3968
3919
|
isLoadingSenderDetails: PropTypes.bool,
|
|
3969
3920
|
orgUnitId: PropTypes.number,
|
|
3970
|
-
ccsSendTransaction: PropTypes.shape({
|
|
3971
|
-
commDefinitionId: PropTypes.string,
|
|
3972
|
-
referenceId: PropTypes.string,
|
|
3973
|
-
}),
|
|
3974
3921
|
|
|
3975
3922
|
// Email-specific props
|
|
3976
3923
|
beeInstance: PropTypes.object,
|
|
@@ -4010,8 +3957,6 @@ CommonTestAndPreview.defaultProps = {
|
|
|
4010
3957
|
wecrmAccounts: [],
|
|
4011
3958
|
isLoadingSenderDetails: false,
|
|
4012
3959
|
orgUnitId: -1,
|
|
4013
|
-
ccsSendTransaction: null,
|
|
4014
|
-
isSendingCcsTestMessage: false,
|
|
4015
3960
|
};
|
|
4016
3961
|
|
|
4017
3962
|
// ============================================
|
|
@@ -15,9 +15,6 @@ import {
|
|
|
15
15
|
SEND_TEST_MESSAGE_REQUESTED,
|
|
16
16
|
SEND_TEST_MESSAGE_SUCCESS,
|
|
17
17
|
SEND_TEST_MESSAGE_FAILURE,
|
|
18
|
-
SEND_CCS_TEST_MESSAGE_REQUESTED,
|
|
19
|
-
SEND_CCS_TEST_MESSAGE_SUCCESS,
|
|
20
|
-
SEND_CCS_TEST_MESSAGE_FAILURE,
|
|
21
18
|
CLEAR_CUSTOMER_SEARCH_STATE,
|
|
22
19
|
CLEAR_SEARCH_RESULTS,
|
|
23
20
|
GET_TEST_CUSTOMERS_REQUESTED,
|
|
@@ -72,10 +69,6 @@ const initialState = fromJS({
|
|
|
72
69
|
sendTestMessageError: null,
|
|
73
70
|
testMessageResponse: null,
|
|
74
71
|
|
|
75
|
-
// CCS test message state (notify/ui)
|
|
76
|
-
isSendingCcsTestMessage: false,
|
|
77
|
-
sendCcsTestMessageError: null,
|
|
78
|
-
|
|
79
72
|
tags: {
|
|
80
73
|
loading: false,
|
|
81
74
|
error: null,
|
|
@@ -201,19 +194,6 @@ const previewAndTestReducer = (state = initialState, action) => {
|
|
|
201
194
|
.set('isSendingTestMessage', false)
|
|
202
195
|
.set('sendTestMessageError', action.payload.error);
|
|
203
196
|
|
|
204
|
-
// Send CCS Test Message (notify/ui)
|
|
205
|
-
case SEND_CCS_TEST_MESSAGE_REQUESTED:
|
|
206
|
-
return state.set('isSendingCcsTestMessage', true)
|
|
207
|
-
.set('sendCcsTestMessageError', null);
|
|
208
|
-
|
|
209
|
-
case SEND_CCS_TEST_MESSAGE_SUCCESS:
|
|
210
|
-
return state.set('isSendingCcsTestMessage', false)
|
|
211
|
-
.set('sendCcsTestMessageError', null);
|
|
212
|
-
|
|
213
|
-
case SEND_CCS_TEST_MESSAGE_FAILURE:
|
|
214
|
-
return state.set('isSendingCcsTestMessage', false)
|
|
215
|
-
.set('sendCcsTestMessageError', action.payload.error);
|
|
216
|
-
|
|
217
197
|
// Clear Actions
|
|
218
198
|
case CLEAR_SEARCH_RESULTS:
|
|
219
199
|
return state.set('customers', [])
|
|
@@ -21,9 +21,6 @@ import {
|
|
|
21
21
|
SEND_TEST_MESSAGE_REQUESTED,
|
|
22
22
|
SEND_TEST_MESSAGE_SUCCESS,
|
|
23
23
|
SEND_TEST_MESSAGE_FAILURE,
|
|
24
|
-
SEND_CCS_TEST_MESSAGE_REQUESTED,
|
|
25
|
-
SEND_CCS_TEST_MESSAGE_SUCCESS,
|
|
26
|
-
SEND_CCS_TEST_MESSAGE_FAILURE,
|
|
27
24
|
GET_TEST_CUSTOMERS_REQUESTED,
|
|
28
25
|
GET_TEST_GROUPS_REQUESTED,
|
|
29
26
|
GET_TEST_CUSTOMERS_SUCCESS,
|
|
@@ -147,26 +144,6 @@ export function* sendTestMessageSaga(action) {
|
|
|
147
144
|
}
|
|
148
145
|
}
|
|
149
146
|
|
|
150
|
-
// notify/ui: Send Test Message via CCS's send/transaction endpoint, against a real
|
|
151
|
-
// CommDefinition, instead of the legacy createMessageMeta/sendTestMessage flow above.
|
|
152
|
-
export function* sendCcsTestMessageSaga(action) {
|
|
153
|
-
try {
|
|
154
|
-
const { callback } = action;
|
|
155
|
-
const res = yield call(Api.sendTransactionalComm, action.payload);
|
|
156
|
-
if (res?.response?.success === false) {
|
|
157
|
-
const error = res?.response?.errors?.[0]?.message || ERROR_MESSAGES.FAILED_TO_SEND_CCS_TEST_MESSAGE;
|
|
158
|
-
yield put({ type: SEND_CCS_TEST_MESSAGE_FAILURE, payload: { error } });
|
|
159
|
-
callback(false);
|
|
160
|
-
} else {
|
|
161
|
-
yield put({ type: SEND_CCS_TEST_MESSAGE_SUCCESS });
|
|
162
|
-
callback(true);
|
|
163
|
-
}
|
|
164
|
-
} catch (error) {
|
|
165
|
-
yield put({ type: SEND_CCS_TEST_MESSAGE_FAILURE, payload: { error: error.message || ERROR_MESSAGES.NETWORK_ERROR } });
|
|
166
|
-
action.callback(false);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
147
|
export function* getBulkCustomerDetails({fetchedUserIds}) {
|
|
171
148
|
try {
|
|
172
149
|
const bulkCustomerDetails = yield call(Api.getBulkCustomerDetails, {
|
|
@@ -308,10 +285,6 @@ export function* watchSendTestMessage() {
|
|
|
308
285
|
yield takeLatest(SEND_TEST_MESSAGE_REQUESTED, sendTestMessageSaga);
|
|
309
286
|
}
|
|
310
287
|
|
|
311
|
-
export function* watchSendCcsTestMessage() {
|
|
312
|
-
yield takeLatest(SEND_CCS_TEST_MESSAGE_REQUESTED, sendCcsTestMessageSaga);
|
|
313
|
-
}
|
|
314
|
-
|
|
315
288
|
export function* watchFetchTestCustomers() {
|
|
316
289
|
yield takeLatest(GET_TEST_CUSTOMERS_REQUESTED, fetchTestCustomersSaga);
|
|
317
290
|
}
|
|
@@ -398,7 +371,6 @@ export function* commonTestAndPreviewSaga() {
|
|
|
398
371
|
watchExtractTags(),
|
|
399
372
|
watchUpdatePreview(),
|
|
400
373
|
watchSendTestMessage(),
|
|
401
|
-
watchSendCcsTestMessage(),
|
|
402
374
|
watchFetchTestCustomers(),
|
|
403
375
|
watchFetchTestGroups(),
|
|
404
376
|
watchCreateMessageMeta(),
|
|
@@ -124,11 +124,6 @@ const makeSelectIsSendingTestMessage = () => createSelector(
|
|
|
124
124
|
(substate) => substate.get('isSendingTestMessage'),
|
|
125
125
|
);
|
|
126
126
|
|
|
127
|
-
const makeSelectIsSendingCcsTestMessage = () => createSelector(
|
|
128
|
-
selectCommonTestAndPreviewDomain,
|
|
129
|
-
(substate) => substate.get('isSendingCcsTestMessage'),
|
|
130
|
-
);
|
|
131
|
-
|
|
132
127
|
const makeSelectUpdatePreviewError = () => createSelector(
|
|
133
128
|
selectCommonTestAndPreviewDomain,
|
|
134
129
|
(substate) => substate.get('updatePreviewError'),
|
|
@@ -217,7 +212,6 @@ export {
|
|
|
217
212
|
makeSelectPrefilledValues,
|
|
218
213
|
makeSelectTestMessageResponse,
|
|
219
214
|
makeSelectIsSendingTestMessage,
|
|
220
|
-
makeSelectIsSendingCcsTestMessage,
|
|
221
215
|
makeSelectUpdatePreviewError,
|
|
222
216
|
makeSelectUpdatePreviewErrors,
|
|
223
217
|
makeSelectFetchPrefilledValuesError,
|
|
@@ -479,112 +479,6 @@ describe('UnifiedPreview', () => {
|
|
|
479
479
|
});
|
|
480
480
|
});
|
|
481
481
|
|
|
482
|
-
describe('Channel Routing - LINE', () => {
|
|
483
|
-
it('should render SmsPreviewContent for LINE channel with string content', () => {
|
|
484
|
-
const props = {
|
|
485
|
-
...defaultProps,
|
|
486
|
-
channel: CHANNELS.LINE,
|
|
487
|
-
content: 'Hello world',
|
|
488
|
-
};
|
|
489
|
-
|
|
490
|
-
render(
|
|
491
|
-
<TestWrapper>
|
|
492
|
-
<ComponentToRender {...props} />
|
|
493
|
-
</TestWrapper>
|
|
494
|
-
);
|
|
495
|
-
|
|
496
|
-
expect(screen.getByTestId('sms-preview')).toBeTruthy();
|
|
497
|
-
expect(screen.getByTestId('sms-content')).toHaveTextContent('Hello world');
|
|
498
|
-
});
|
|
499
|
-
|
|
500
|
-
it('should handle object content with resolvedBody for LINE channel', () => {
|
|
501
|
-
const props = {
|
|
502
|
-
...defaultProps,
|
|
503
|
-
channel: CHANNELS.LINE,
|
|
504
|
-
content: {
|
|
505
|
-
resolvedBody: 'some text',
|
|
506
|
-
},
|
|
507
|
-
};
|
|
508
|
-
|
|
509
|
-
render(
|
|
510
|
-
<TestWrapper>
|
|
511
|
-
<ComponentToRender {...props} />
|
|
512
|
-
</TestWrapper>
|
|
513
|
-
);
|
|
514
|
-
|
|
515
|
-
expect(screen.getByTestId('sms-preview')).toBeTruthy();
|
|
516
|
-
expect(screen.getByTestId('sms-content')).toHaveTextContent('some text');
|
|
517
|
-
});
|
|
518
|
-
|
|
519
|
-
it('should not crash and render empty content for LINE channel when content is undefined', () => {
|
|
520
|
-
const props = {
|
|
521
|
-
...defaultProps,
|
|
522
|
-
channel: CHANNELS.LINE,
|
|
523
|
-
content: undefined,
|
|
524
|
-
};
|
|
525
|
-
|
|
526
|
-
render(
|
|
527
|
-
<TestWrapper>
|
|
528
|
-
<ComponentToRender {...props} />
|
|
529
|
-
</TestWrapper>
|
|
530
|
-
);
|
|
531
|
-
|
|
532
|
-
expect(screen.getByTestId('sms-preview')).toBeTruthy();
|
|
533
|
-
expect(screen.getByTestId('sms-content')).toHaveTextContent('');
|
|
534
|
-
});
|
|
535
|
-
|
|
536
|
-
it('should not crash and render empty content for LINE channel when content is null', () => {
|
|
537
|
-
const props = {
|
|
538
|
-
...defaultProps,
|
|
539
|
-
channel: CHANNELS.LINE,
|
|
540
|
-
content: null,
|
|
541
|
-
};
|
|
542
|
-
|
|
543
|
-
render(
|
|
544
|
-
<TestWrapper>
|
|
545
|
-
<ComponentToRender {...props} />
|
|
546
|
-
</TestWrapper>
|
|
547
|
-
);
|
|
548
|
-
|
|
549
|
-
expect(screen.getByTestId('sms-preview')).toBeTruthy();
|
|
550
|
-
expect(screen.getByTestId('sms-content')).toHaveTextContent('');
|
|
551
|
-
});
|
|
552
|
-
|
|
553
|
-
it('should render empty content for LINE channel when content is not a string and has no resolvedBody', () => {
|
|
554
|
-
const props = {
|
|
555
|
-
...defaultProps,
|
|
556
|
-
channel: CHANNELS.LINE,
|
|
557
|
-
content: { someOtherField: 'value' },
|
|
558
|
-
};
|
|
559
|
-
|
|
560
|
-
render(
|
|
561
|
-
<TestWrapper>
|
|
562
|
-
<ComponentToRender {...props} />
|
|
563
|
-
</TestWrapper>
|
|
564
|
-
);
|
|
565
|
-
|
|
566
|
-
expect(screen.getByTestId('sms-preview')).toBeTruthy();
|
|
567
|
-
expect(screen.getByTestId('sms-content')).toHaveTextContent('');
|
|
568
|
-
});
|
|
569
|
-
|
|
570
|
-
it('should not render the Unknown Channel fallback for LINE channel', () => {
|
|
571
|
-
const props = {
|
|
572
|
-
...defaultProps,
|
|
573
|
-
channel: CHANNELS.LINE,
|
|
574
|
-
content: 'Hello world',
|
|
575
|
-
};
|
|
576
|
-
|
|
577
|
-
render(
|
|
578
|
-
<TestWrapper>
|
|
579
|
-
<ComponentToRender {...props} />
|
|
580
|
-
</TestWrapper>
|
|
581
|
-
);
|
|
582
|
-
|
|
583
|
-
expect(screen.queryByText('Unknown Channel')).toBeNull();
|
|
584
|
-
expect(screen.getByTestId('sms-preview')).toBeTruthy();
|
|
585
|
-
});
|
|
586
|
-
});
|
|
587
|
-
|
|
588
482
|
describe('Channel Routing - WHATSAPP', () => {
|
|
589
483
|
it('should render WhatsAppPreviewContent for WHATSAPP channel', () => {
|
|
590
484
|
const props = {
|
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
extractTagsRequested,
|
|
10
10
|
updatePreviewRequested,
|
|
11
11
|
sendTestMessageRequested,
|
|
12
|
-
sendCcsTestMessageRequested,
|
|
13
12
|
clearCustomerSearchState,
|
|
14
13
|
clearSearchResults,
|
|
15
14
|
getTestCustomersRequested,
|
|
@@ -27,7 +26,6 @@ import {
|
|
|
27
26
|
EXTRACT_TAGS_REQUESTED,
|
|
28
27
|
UPDATE_PREVIEW_REQUESTED,
|
|
29
28
|
SEND_TEST_MESSAGE_REQUESTED,
|
|
30
|
-
SEND_CCS_TEST_MESSAGE_REQUESTED,
|
|
31
29
|
CLEAR_CUSTOMER_SEARCH_STATE,
|
|
32
30
|
CLEAR_SEARCH_RESULTS,
|
|
33
31
|
GET_TEST_CUSTOMERS_REQUESTED,
|
|
@@ -207,19 +205,6 @@ describe('CommonTestAndPreview Actions', () => {
|
|
|
207
205
|
});
|
|
208
206
|
});
|
|
209
207
|
|
|
210
|
-
describe('sendCcsTestMessageRequested', () => {
|
|
211
|
-
it('should create an action to send a CCS test message with payload and callback', () => {
|
|
212
|
-
const payload = { commDefinitionId: 'cd_123', recipient: { identifiers: [] } };
|
|
213
|
-
const callback = jest.fn();
|
|
214
|
-
const expectedAction = {
|
|
215
|
-
type: SEND_CCS_TEST_MESSAGE_REQUESTED,
|
|
216
|
-
payload,
|
|
217
|
-
callback,
|
|
218
|
-
};
|
|
219
|
-
expect(sendCcsTestMessageRequested(payload, callback)).toEqual(expectedAction);
|
|
220
|
-
});
|
|
221
|
-
});
|
|
222
|
-
|
|
223
208
|
describe('clearCustomerSearchState', () => {
|
|
224
209
|
it('should create an action to clear customer search state', () => {
|
|
225
210
|
const expectedAction = {
|