@capillarytech/creatives-library 8.0.345-alpha.10 → 8.0.345-alpha.12

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.
Files changed (127) hide show
  1. package/constants/unified.js +29 -0
  2. package/package.json +1 -1
  3. package/services/tests/api.test.js +13 -0
  4. package/utils/commonUtils.js +19 -1
  5. package/utils/rcsPayloadUtils.js +92 -0
  6. package/utils/templateVarUtils.js +201 -0
  7. package/utils/tests/templateVarUtils.test.js +204 -0
  8. package/v2Components/CapActionButton/constants.js +7 -0
  9. package/v2Components/CapActionButton/index.js +167 -109
  10. package/v2Components/CapActionButton/index.scss +157 -6
  11. package/v2Components/CapActionButton/messages.js +19 -3
  12. package/v2Components/CapActionButton/tests/index.test.js +41 -17
  13. package/v2Components/CapTagList/index.js +10 -0
  14. package/v2Components/CommonTestAndPreview/CustomValuesEditor.js +70 -49
  15. package/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +8 -2
  16. package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +207 -21
  17. package/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +16 -0
  18. package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +85 -10
  19. package/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +30 -0
  20. package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +79 -11
  21. package/v2Components/CommonTestAndPreview/SendTestMessage.js +10 -5
  22. package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js +160 -15
  23. package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js.rej +18 -0
  24. package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +341 -76
  25. package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +133 -4
  26. package/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +11 -0
  27. package/v2Components/CommonTestAndPreview/constants.js +38 -2
  28. package/v2Components/CommonTestAndPreview/index.js +676 -186
  29. package/v2Components/CommonTestAndPreview/messages.js +49 -3
  30. package/v2Components/CommonTestAndPreview/previewApiUtils.js +59 -0
  31. package/v2Components/CommonTestAndPreview/sagas.js +15 -6
  32. package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +308 -284
  33. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +231 -65
  34. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/index.test.js +118 -5
  35. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +341 -0
  36. package/v2Components/CommonTestAndPreview/tests/PreviewSection.test.js +8 -1
  37. package/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +34 -13
  38. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/RcsPreviewContent.test.js +281 -283
  39. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +199 -1
  40. package/v2Components/CommonTestAndPreview/tests/index.test.js +132 -4
  41. package/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +67 -0
  42. package/v2Components/CommonTestAndPreview/tests/sagas.test.js +2 -2
  43. package/v2Components/FormBuilder/index.js +8 -10
  44. package/v2Components/SmsFallback/SmsFallbackLocalSelector.js +87 -0
  45. package/v2Components/SmsFallback/constants.js +73 -0
  46. package/v2Components/SmsFallback/index.js +955 -0
  47. package/v2Components/SmsFallback/index.scss +265 -0
  48. package/v2Components/SmsFallback/messages.js +78 -0
  49. package/v2Components/SmsFallback/smsFallbackUtils.js +118 -0
  50. package/v2Components/SmsFallback/tests/SmsFallbackLocalSelector.test.js +50 -0
  51. package/v2Components/SmsFallback/tests/rcsSmsFallback.acceptance.test.js +147 -0
  52. package/v2Components/SmsFallback/tests/smsFallbackHandlers.test.js +304 -0
  53. package/v2Components/SmsFallback/tests/smsFallbackUi.test.js +197 -0
  54. package/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +277 -0
  55. package/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +422 -0
  56. package/v2Components/SmsFallback/useLocalTemplateList.js +92 -0
  57. package/v2Components/TemplatePreview/_templatePreview.scss +33 -23
  58. package/v2Components/TemplatePreview/constants.js +2 -0
  59. package/v2Components/TemplatePreview/index.js +143 -28
  60. package/v2Components/TemplatePreview/tests/index.test.js +142 -0
  61. package/v2Components/TestAndPreviewSlidebox/index.js +13 -1
  62. package/v2Components/TestAndPreviewSlidebox/sagas.js +11 -4
  63. package/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +3 -1
  64. package/v2Components/VarSegmentMessageEditor/constants.js +2 -0
  65. package/v2Components/VarSegmentMessageEditor/index.js +125 -0
  66. package/v2Components/VarSegmentMessageEditor/index.scss +46 -0
  67. package/v2Containers/CreativesContainer/CreativesSlideBoxWrapper.js +43 -0
  68. package/v2Containers/CreativesContainer/SlideBoxContent.js +37 -24
  69. package/v2Containers/CreativesContainer/SlideBoxFooter.js +10 -1
  70. package/v2Containers/CreativesContainer/SlideBoxHeader.js +29 -4
  71. package/v2Containers/CreativesContainer/constants.js +9 -0
  72. package/v2Containers/CreativesContainer/embeddedSlideboxUtils.js +67 -0
  73. package/v2Containers/CreativesContainer/index.js +301 -107
  74. package/v2Containers/CreativesContainer/index.scss +51 -1
  75. package/v2Containers/CreativesContainer/tests/SlideBoxContent.localTemplates.test.js +90 -0
  76. package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +78 -34
  77. package/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +79 -16
  78. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +8 -0
  79. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +357 -98
  80. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +20 -15
  81. package/v2Containers/CreativesContainer/tests/embeddedSlideboxUtils.test.js +258 -0
  82. package/v2Containers/CreativesContainer/tests/index.test.js +71 -9
  83. package/v2Containers/CreativesContainer/tests/useLocalTemplatesProp.test.js +125 -0
  84. package/v2Containers/Email/index.js +0 -23
  85. package/v2Containers/Rcs/constants.js +119 -8
  86. package/v2Containers/Rcs/index.js +2370 -807
  87. package/v2Containers/Rcs/index.js.rej +1336 -0
  88. package/v2Containers/Rcs/index.scss +276 -6
  89. package/v2Containers/Rcs/index.scss.rej +74 -0
  90. package/v2Containers/Rcs/messages.js +38 -3
  91. package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +225 -0
  92. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +98302 -70345
  93. package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +0 -5
  94. package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap.rej +128 -0
  95. package/v2Containers/Rcs/tests/index.test.js +152 -121
  96. package/v2Containers/Rcs/tests/mockData.js +38 -0
  97. package/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +318 -0
  98. package/v2Containers/Rcs/tests/utils.test.js +646 -30
  99. package/v2Containers/Rcs/utils.js +478 -11
  100. package/v2Containers/Sms/Create/index.js +100 -40
  101. package/v2Containers/Sms/smsFormDataHelpers.js +67 -0
  102. package/v2Containers/Sms/tests/smsFormDataHelpers.test.js +253 -0
  103. package/v2Containers/SmsTrai/Create/index.js +9 -4
  104. package/v2Containers/SmsTrai/Edit/constants.js +2 -0
  105. package/v2Containers/SmsTrai/Edit/index.js +636 -130
  106. package/v2Containers/SmsTrai/Edit/index.scss +121 -0
  107. package/v2Containers/SmsTrai/Edit/messages.js +14 -4
  108. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +4328 -2375
  109. package/v2Containers/SmsWrapper/index.js +37 -8
  110. package/v2Containers/TagList/index.js +6 -0
  111. package/v2Containers/Templates/TemplatesActionBar.js +101 -0
  112. package/v2Containers/Templates/_templates.scss +163 -2
  113. package/v2Containers/Templates/actions.js +11 -0
  114. package/v2Containers/Templates/constants.js +2 -0
  115. package/v2Containers/Templates/index.js +119 -54
  116. package/v2Containers/Templates/sagas.js +57 -12
  117. package/v2Containers/Templates/tests/TemplatesActionBar.test.js +120 -0
  118. package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1043 -1079
  119. package/v2Containers/Templates/tests/sagas.test.js +193 -123
  120. package/v2Containers/Templates/tests/smsTemplatesListApi.test.js +180 -0
  121. package/v2Containers/Templates/utils/smsTemplatesListApi.js +79 -0
  122. package/v2Containers/TemplatesV2/TemplatesV2.style.js +72 -1
  123. package/v2Containers/TemplatesV2/index.js +86 -23
  124. package/v2Containers/TemplatesV2/tests/TemplatesV2.localTemplates.test.js +131 -0
  125. package/v2Containers/Whatsapp/index.js +3 -20
  126. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +578 -34
  127. package/.npmrx +0 -2
@@ -0,0 +1,258 @@
1
+ import {
2
+ CAP_SPACE_32,
3
+ CAP_SPACE_56,
4
+ CAP_SPACE_64,
5
+ } from '@capillarytech/cap-ui-library/styled/variables';
6
+ import {
7
+ isDeepEmpty,
8
+ getSlideBoxWrapperMarginFromLiquidErrors,
9
+ computeLiquidFooterUpdateFromFormBuilder,
10
+ } from '../embeddedSlideboxUtils';
11
+ import { ANDROID, IOS, MOBILE_PUSH, LIQUID_ERROR_MSG, STANDARD_ERROR_MSG } from '../constants';
12
+
13
+ // ---------------------------------------------------------------------------
14
+ // isDeepEmpty
15
+ // ---------------------------------------------------------------------------
16
+
17
+ describe('isDeepEmpty', () => {
18
+ it('returns true for null', () => {
19
+ expect(isDeepEmpty(null)).toBe(true);
20
+ });
21
+
22
+ it('returns true for undefined', () => {
23
+ expect(isDeepEmpty(undefined)).toBe(true);
24
+ });
25
+
26
+ it('returns true for empty string', () => {
27
+ expect(isDeepEmpty('')).toBe(true);
28
+ });
29
+
30
+ it('returns false for non-empty string', () => {
31
+ expect(isDeepEmpty('hello')).toBe(false);
32
+ });
33
+
34
+ it('returns true for empty array', () => {
35
+ expect(isDeepEmpty([])).toBe(true);
36
+ });
37
+
38
+ it('returns false for non-empty array', () => {
39
+ expect(isDeepEmpty(['item'])).toBe(false);
40
+ });
41
+
42
+ it('returns true for empty object', () => {
43
+ expect(isDeepEmpty({})).toBe(true);
44
+ });
45
+
46
+ it('returns true for object where all values are deep-empty', () => {
47
+ expect(isDeepEmpty({ a: null, b: '', c: [] })).toBe(true);
48
+ });
49
+
50
+ it('returns false for object with at least one non-empty value', () => {
51
+ expect(isDeepEmpty({ a: null, b: 'something' })).toBe(false);
52
+ });
53
+
54
+ it('returns true for nested all-empty object', () => {
55
+ expect(isDeepEmpty({ a: { b: null, c: [] } })).toBe(true);
56
+ });
57
+
58
+ it('returns false for nested object with a non-empty leaf', () => {
59
+ expect(isDeepEmpty({ a: { b: 'value' } })).toBe(false);
60
+ });
61
+
62
+ it('returns false for a number (non-null, non-string, non-array, non-object)', () => {
63
+ expect(isDeepEmpty(0)).toBe(false);
64
+ expect(isDeepEmpty(42)).toBe(false);
65
+ });
66
+
67
+ it('returns false for a boolean false', () => {
68
+ expect(isDeepEmpty(false)).toBe(false);
69
+ });
70
+ });
71
+
72
+ // ---------------------------------------------------------------------------
73
+ // getSlideBoxWrapperMarginFromLiquidErrors
74
+ // ---------------------------------------------------------------------------
75
+
76
+ describe('getSlideBoxWrapperMarginFromLiquidErrors', () => {
77
+ it('returns 0 when liquidErrorMessage is null', () => {
78
+ expect(getSlideBoxWrapperMarginFromLiquidErrors(null)).toBe(0);
79
+ });
80
+
81
+ it('returns 0 when liquidErrorMessage is undefined', () => {
82
+ expect(getSlideBoxWrapperMarginFromLiquidErrors(undefined)).toBe(0);
83
+ });
84
+
85
+ it('returns 0 when both error arrays are empty', () => {
86
+ expect(getSlideBoxWrapperMarginFromLiquidErrors({
87
+ STANDARD_ERROR_MSG: [],
88
+ LIQUID_ERROR_MSG: [],
89
+ })).toBe(0);
90
+ });
91
+
92
+ it('returns 0 when neither error array is present', () => {
93
+ expect(getSlideBoxWrapperMarginFromLiquidErrors({})).toBe(0);
94
+ });
95
+
96
+ it('returns CAP_SPACE_64 when both STANDARD and LIQUID errors are present', () => {
97
+ expect(getSlideBoxWrapperMarginFromLiquidErrors({
98
+ STANDARD_ERROR_MSG: ['std error'],
99
+ LIQUID_ERROR_MSG: ['liquid error'],
100
+ })).toBe(CAP_SPACE_64);
101
+ });
102
+
103
+ it('returns CAP_SPACE_56 when only LIQUID errors are present', () => {
104
+ expect(getSlideBoxWrapperMarginFromLiquidErrors({
105
+ STANDARD_ERROR_MSG: [],
106
+ LIQUID_ERROR_MSG: ['liquid error'],
107
+ })).toBe(CAP_SPACE_56);
108
+ });
109
+
110
+ it('returns CAP_SPACE_32 when only STANDARD errors are present', () => {
111
+ expect(getSlideBoxWrapperMarginFromLiquidErrors({
112
+ STANDARD_ERROR_MSG: ['std error'],
113
+ LIQUID_ERROR_MSG: [],
114
+ })).toBe(CAP_SPACE_32);
115
+ });
116
+
117
+ it('returns CAP_SPACE_56 when LIQUID has multiple errors and STANDARD is absent', () => {
118
+ expect(getSlideBoxWrapperMarginFromLiquidErrors({
119
+ LIQUID_ERROR_MSG: ['err1', 'err2'],
120
+ })).toBe(CAP_SPACE_56);
121
+ });
122
+
123
+ it('returns CAP_SPACE_32 when STANDARD has multiple errors and LIQUID is absent', () => {
124
+ expect(getSlideBoxWrapperMarginFromLiquidErrors({
125
+ STANDARD_ERROR_MSG: ['err1', 'err2'],
126
+ })).toBe(CAP_SPACE_32);
127
+ });
128
+ });
129
+
130
+ // ---------------------------------------------------------------------------
131
+ // computeLiquidFooterUpdateFromFormBuilder
132
+ // ---------------------------------------------------------------------------
133
+
134
+ describe('computeLiquidFooterUpdateFromFormBuilder', () => {
135
+ const noErrors = { [LIQUID_ERROR_MSG]: [], [STANDARD_ERROR_MSG]: [] };
136
+ const liquidOnly = { [LIQUID_ERROR_MSG]: ['liquid err'], [STANDARD_ERROR_MSG]: [] };
137
+ const standardOnly = { [LIQUID_ERROR_MSG]: [], [STANDARD_ERROR_MSG]: ['std err'] };
138
+ const bothErrors = { [LIQUID_ERROR_MSG]: ['l'], [STANDARD_ERROR_MSG]: ['s'] };
139
+
140
+ describe('normal (non-null) returns', () => {
141
+ it('returns isLiquidValidationError=false when no errors', () => {
142
+ const result = computeLiquidFooterUpdateFromFormBuilder(noErrors, 1, {
143
+ previousIsLiquidValidationError: false,
144
+ currentChannelUpper: 'SMS',
145
+ });
146
+ expect(result).not.toBeNull();
147
+ expect(result.isLiquidValidationError).toBe(false);
148
+ expect(result.liquidErrorMessage).toEqual(noErrors);
149
+ });
150
+
151
+ it('sets isLiquidValidationError=true when liquid errors present', () => {
152
+ const result = computeLiquidFooterUpdateFromFormBuilder(liquidOnly, 1, {
153
+ previousIsLiquidValidationError: false,
154
+ currentChannelUpper: 'SMS',
155
+ });
156
+ expect(result.isLiquidValidationError).toBe(true);
157
+ });
158
+
159
+ it('sets isLiquidValidationError=true when standard errors present', () => {
160
+ const result = computeLiquidFooterUpdateFromFormBuilder(standardOnly, 1, {
161
+ previousIsLiquidValidationError: false,
162
+ currentChannelUpper: 'SMS',
163
+ });
164
+ expect(result.isLiquidValidationError).toBe(true);
165
+ });
166
+
167
+ it('sets isLiquidValidationError=true when both errors present', () => {
168
+ const result = computeLiquidFooterUpdateFromFormBuilder(bothErrors, 1, {
169
+ previousIsLiquidValidationError: false,
170
+ currentChannelUpper: 'SMS',
171
+ });
172
+ expect(result.isLiquidValidationError).toBe(true);
173
+ });
174
+
175
+ it('maps tab 1 to ANDROID', () => {
176
+ const result = computeLiquidFooterUpdateFromFormBuilder(noErrors, 1, {
177
+ previousIsLiquidValidationError: false,
178
+ currentChannelUpper: 'SMS',
179
+ });
180
+ expect(result.activeFormBuilderTab).toBe(ANDROID);
181
+ });
182
+
183
+ it('maps tab 2 to IOS', () => {
184
+ const result = computeLiquidFooterUpdateFromFormBuilder(noErrors, 2, {
185
+ previousIsLiquidValidationError: false,
186
+ currentChannelUpper: 'SMS',
187
+ });
188
+ expect(result.activeFormBuilderTab).toBe(IOS);
189
+ });
190
+
191
+ it('maps tab 3 (or any other tab) to null', () => {
192
+ const result = computeLiquidFooterUpdateFromFormBuilder(noErrors, 3, {
193
+ previousIsLiquidValidationError: false,
194
+ currentChannelUpper: 'SMS',
195
+ });
196
+ expect(result.activeFormBuilderTab).toBeNull();
197
+ });
198
+
199
+ it('maps undefined tab to null for activeFormBuilderTab', () => {
200
+ const result = computeLiquidFooterUpdateFromFormBuilder(noErrors, undefined, {
201
+ previousIsLiquidValidationError: false,
202
+ currentChannelUpper: 'SMS',
203
+ });
204
+ expect(result.activeFormBuilderTab).toBeNull();
205
+ });
206
+
207
+ it('does NOT return null for Mobile Push when errors ARE present', () => {
208
+ const result = computeLiquidFooterUpdateFromFormBuilder(liquidOnly, 1, {
209
+ previousIsLiquidValidationError: true,
210
+ currentChannelUpper: MOBILE_PUSH,
211
+ });
212
+ expect(result).not.toBeNull();
213
+ expect(result.isLiquidValidationError).toBe(true);
214
+ });
215
+
216
+ it('does NOT return null for non-Mobile Push channel even with previousIsLiquidValidationError', () => {
217
+ const result = computeLiquidFooterUpdateFromFormBuilder(noErrors, 1, {
218
+ previousIsLiquidValidationError: true,
219
+ currentChannelUpper: 'SMS',
220
+ });
221
+ expect(result).not.toBeNull();
222
+ expect(result.isLiquidValidationError).toBe(false);
223
+ });
224
+
225
+ it('works without options argument (uses defaults)', () => {
226
+ const result = computeLiquidFooterUpdateFromFormBuilder(noErrors, 1);
227
+ expect(result).not.toBeNull();
228
+ expect(result.isLiquidValidationError).toBe(false);
229
+ });
230
+ });
231
+
232
+ describe('Mobile Push OLD clear (returns null)', () => {
233
+ it('returns null when no errors and previousIsLiquidValidationError is true for MOBILEPUSH', () => {
234
+ const result = computeLiquidFooterUpdateFromFormBuilder(noErrors, 1, {
235
+ previousIsLiquidValidationError: true,
236
+ currentChannelUpper: MOBILE_PUSH,
237
+ });
238
+ expect(result).toBeNull();
239
+ });
240
+
241
+ it('does NOT return null when previousIsLiquidValidationError is false for MOBILEPUSH', () => {
242
+ const result = computeLiquidFooterUpdateFromFormBuilder(noErrors, 1, {
243
+ previousIsLiquidValidationError: false,
244
+ currentChannelUpper: MOBILE_PUSH,
245
+ });
246
+ expect(result).not.toBeNull();
247
+ });
248
+
249
+ it('does NOT return null when only standard errors cleared but liquid error remains for MOBILEPUSH', () => {
250
+ const result = computeLiquidFooterUpdateFromFormBuilder(liquidOnly, 1, {
251
+ previousIsLiquidValidationError: true,
252
+ currentChannelUpper: MOBILE_PUSH,
253
+ });
254
+ // hasLiquid = true → condition !hasLiquid is false → does not return null
255
+ expect(result).not.toBeNull();
256
+ });
257
+ });
258
+ });
@@ -173,19 +173,35 @@ describe('Test SlideBoxContent container', () => {
173
173
  expect(getCreativesData).toHaveBeenCalledWith({ channel: 'RCS' });
174
174
  });
175
175
 
176
- it('RCS getFormData does not attach smsFallBackContent to templateData', async () => {
177
- renderFunction('RCS', 'editTemplate', rcsTemplates, rcsEditTemplateData);
176
+ it('RCS getFormData mirrors smsFallBackContent onto templateData for library round-trip', async () => {
177
+ renderedComponent = shallowWithIntl(
178
+ <Creatives
179
+ loyaltyMetaData={loyaltyMetaData}
180
+ Templates={rcsTemplates}
181
+ channel="RCS"
182
+ slidBoxContent="editTemplate"
183
+ templateData={rcsEditTemplateData}
184
+ handleCloseCreatives={handleCloseCreatives}
185
+ getCreativesData={getCreativesData}
186
+ isFullMode={false}
187
+ templateActions={{
188
+ getCdnTransformationConfig,
189
+ }}
190
+ />,
191
+ );
178
192
  renderedComponent.instance().onEditTemplate();
179
193
 
180
194
  const mockValue = {
195
+ validity: true,
181
196
  value: {
182
197
  name: 'rcs_creative_name',
198
+ type: 'RCS',
183
199
  versions: {
184
200
  base: {
185
201
  content: {
186
202
  RCS: {
187
203
  rcsContent: { contentType: 'RICHCARD', cardType: 'STANDALONE', cardSettings: {}, cardContent: [{}] },
188
- smsFallBackContent: { message: 'should-not-be-copied' },
204
+ smsFallBackContent: { message: 'fallback-body' },
189
205
  },
190
206
  },
191
207
  },
@@ -193,16 +209,62 @@ describe('Test SlideBoxContent container', () => {
193
209
  },
194
210
  };
195
211
 
196
- renderedComponent
197
- .find('CapSlideBox')
198
- .props()
199
- .content.props.getFormData(mockValue);
212
+ // Call getFormData on the container instance — shallow CapSlideBox `content` shape can differ across wrappers
213
+ renderedComponent.instance().getFormData(mockValue);
200
214
  await tick();
201
215
 
202
216
  const instance = renderedComponent.instance();
203
217
  expect(instance.state.templateData).toBeDefined();
204
- // sms fallback content should not be set on templateData per current logic
205
- expect(instance.state.templateData.smsFallBackContent).toBeUndefined();
218
+ expect(instance.state.templateData.smsFallBackContent).toEqual({ message: 'fallback-body' });
219
+ });
220
+
221
+ it('RCS getFormData mirrors rcsCardVarMapped onto templateData for campaign reopen', async () => {
222
+ renderedComponent = shallowWithIntl(
223
+ <Creatives
224
+ loyaltyMetaData={loyaltyMetaData}
225
+ Templates={rcsTemplates}
226
+ channel="RCS"
227
+ slidBoxContent="editTemplate"
228
+ templateData={rcsEditTemplateData}
229
+ handleCloseCreatives={handleCloseCreatives}
230
+ getCreativesData={getCreativesData}
231
+ isFullMode={false}
232
+ templateActions={{
233
+ getCdnTransformationConfig,
234
+ }}
235
+ />,
236
+ );
237
+ renderedComponent.instance().onEditTemplate();
238
+
239
+ const cardVarMapped = { 1: '[Name]', user_name: '[Name]' };
240
+ const mockValue = {
241
+ validity: true,
242
+ value: {
243
+ name: 'rcs_creative_name',
244
+ type: 'RCS',
245
+ versions: {
246
+ base: {
247
+ content: {
248
+ RCS: {
249
+ rcsContent: {
250
+ contentType: 'RICHCARD',
251
+ cardType: 'STANDALONE',
252
+ cardSettings: {},
253
+ cardContent: [{ title: 'Hi {{user_name}}', cardVarMapped }],
254
+ },
255
+ smsFallBackContent: {},
256
+ },
257
+ },
258
+ },
259
+ },
260
+ },
261
+ };
262
+
263
+ renderedComponent.instance().getFormData(mockValue);
264
+ await tick();
265
+
266
+ const instance = renderedComponent.instance();
267
+ expect(instance.state.templateData.rcsCardVarMapped).toEqual(cardVarMapped);
206
268
  });
207
269
 
208
270
  it('Text getCreatives data for rcs, data from creatives done to campaigns', async () => {
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Covers local-templates flag resolution: nested `localTemplatesConfig.useLocalTemplates`
3
+ * vs top-level `useLocalTemplates` (embedded consumers / SlideBoxContent).
4
+ */
5
+ import React from 'react';
6
+ import { shallowWithIntl } from '../../../helpers/intl-enzym-test-helpers';
7
+ import { Creatives } from '../index';
8
+ import mockdata from '../../mockdata';
9
+
10
+ const { smsTemplates, loyaltyMetaData } = mockdata;
11
+
12
+ jest.mock('../../../v2Components/FormBuilder', () => ({
13
+ __esModule: true,
14
+ default: (props) => (
15
+ <div className="FormBuilder-mock" {...props}>
16
+ FormBuilder
17
+ </div>
18
+ ),
19
+ }));
20
+
21
+ const baseProps = {
22
+ loyaltyMetaData,
23
+ Templates: smsTemplates,
24
+ channel: 'SMS',
25
+ creativesMode: 'create',
26
+ templateData: null,
27
+ isFullMode: true,
28
+ handleCloseCreatives: jest.fn(),
29
+ getCreativesData: jest.fn(),
30
+ templateActions: {
31
+ getCdnTransformationConfig: jest.fn(),
32
+ resetTemplateStoreData: jest.fn(),
33
+ },
34
+ globalActions: {
35
+ clearMetaEntities: jest.fn(),
36
+ },
37
+ };
38
+
39
+ describe('CreativesContainer useLocalTemplates prop resolution', () => {
40
+ beforeEach(() => {
41
+ jest.clearAllMocks();
42
+ });
43
+
44
+ it('initial slidebox is templates when only top-level useLocalTemplates is true', () => {
45
+ const wrapper = shallowWithIntl(
46
+ <Creatives
47
+ {...baseProps}
48
+ useLocalTemplates
49
+ />,
50
+ );
51
+ expect(wrapper.instance().state.slidBoxContent).toBe('templates');
52
+ });
53
+
54
+ it('initial slidebox is templates when localTemplatesConfig.useLocalTemplates is true', () => {
55
+ const wrapper = shallowWithIntl(
56
+ <Creatives
57
+ {...baseProps}
58
+ localTemplatesConfig={{ useLocalTemplates: true }}
59
+ />,
60
+ );
61
+ expect(wrapper.instance().state.slidBoxContent).toBe('templates');
62
+ });
63
+
64
+ it('does not reset template store on unmount when embedded and top-level useLocalTemplates is true', () => {
65
+ const wrapper = shallowWithIntl(
66
+ <Creatives
67
+ {...baseProps}
68
+ location={{ query: { type: 'embedded' } }}
69
+ useLocalTemplates
70
+ />,
71
+ );
72
+ wrapper.unmount();
73
+ expect(baseProps.templateActions.resetTemplateStoreData).not.toHaveBeenCalled();
74
+ expect(baseProps.globalActions.clearMetaEntities).toHaveBeenCalled();
75
+ });
76
+
77
+ it('resets template store on unmount when embedded and local templates are not used', () => {
78
+ const wrapper = shallowWithIntl(
79
+ <Creatives
80
+ {...baseProps}
81
+ location={{ query: { type: 'embedded' } }}
82
+ useLocalTemplates={false}
83
+ />,
84
+ );
85
+ wrapper.unmount();
86
+ expect(baseProps.templateActions.resetTemplateStoreData).toHaveBeenCalled();
87
+ expect(baseProps.globalActions.clearMetaEntities).toHaveBeenCalled();
88
+ });
89
+
90
+ it('prefers nested localTemplatesConfig.useLocalTemplates=false over top-level true (not local list mode)', () => {
91
+ const wrapper = shallowWithIntl(
92
+ <Creatives
93
+ {...baseProps}
94
+ localTemplatesConfig={{ useLocalTemplates: false }}
95
+ useLocalTemplates
96
+ />,
97
+ );
98
+ expect(wrapper.instance().state.slidBoxContent).toBe('createTemplate');
99
+ });
100
+
101
+ it('uses top-level useLocalTemplates when localTemplatesConfig omits the flag', () => {
102
+ const wrapper = shallowWithIntl(
103
+ <Creatives
104
+ {...baseProps}
105
+ localTemplatesConfig={{}}
106
+ useLocalTemplates
107
+ />,
108
+ );
109
+ expect(wrapper.instance().state.slidBoxContent).toBe('templates');
110
+ });
111
+
112
+ it('resets template store when nested useLocalTemplates is false even if top-level is true', () => {
113
+ const wrapper = shallowWithIntl(
114
+ <Creatives
115
+ {...baseProps}
116
+ location={{ query: { type: 'embedded' } }}
117
+ localTemplatesConfig={{ useLocalTemplates: false }}
118
+ useLocalTemplates
119
+ />,
120
+ );
121
+ wrapper.unmount();
122
+ expect(baseProps.templateActions.resetTemplateStoreData).toHaveBeenCalled();
123
+ expect(baseProps.globalActions.clearMetaEntities).toHaveBeenCalled();
124
+ });
125
+ });
@@ -224,7 +224,6 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
224
224
  || _.get(this.props.Templates.BEETemplate, 'versions.base.drag_drop_id')
225
225
  || _.get(this.props.Templates.BEETemplate, 'versions.base.id')
226
226
  || this.props.Templates.BEETemplate?._id;
227
- console.log('[Rafeeq manzoor] comes here 1');
228
227
  this.props.actions.getCmsSetting(BEE_PLUGIN, dragDropId, 'open', undefined, isBEESupport, isBEEAppEnable);
229
228
  } else if (this.props.location.query.module !== "library" || (this.props.location.query.module === "library" && !this.props.templateData)) {
230
229
  // Extract drag_drop_id - check multiple possible paths
@@ -235,7 +234,6 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
235
234
  || _.get(this.props.Templates.BEETemplate, 'versions.base.drag_drop_id')
236
235
  || _.get(this.props.Templates.BEETemplate, 'versions.base.id')
237
236
  || this.props.Templates.BEETemplate?._id;
238
- console.log('[Rafeeq manzoor] comes here 2');
239
237
  this.props.actions.getCmsSetting(BEE_PLUGIN, dragDropId, 'create', undefined, isBEESupport, isBEEAppEnable);
240
238
  }
241
239
  }
@@ -288,10 +286,8 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
288
286
 
289
287
  if (this.props.params.id) {
290
288
  const activeTabForLang = beeTemplate.versions?.base?.activeTab || 'en';
291
- console.log('[Rafeeq manzoor] comes here 3');
292
289
  this.props.actions.getCmsSetting(BEE_PLUGIN, dragDropId, 'open', activeTabForLang, isBEESupport, isBEEAppEnable);
293
290
  } else {
294
- console.log('[Rafeeq manzoor] comes here 4');
295
291
  this.props.actions.getCmsSetting(BEE_PLUGIN, dragDropId, 'create', undefined, isBEESupport, isBEEAppEnable);
296
292
  }
297
293
  }
@@ -335,7 +331,6 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
335
331
  this.getFormData();
336
332
  }
337
333
  }
338
- console.log('[Rafeeq manzoor] nextProps', nextProps, _.isEmpty(this.state.formData));
339
334
  if (this.state.languageDataSet && nextProps.Templates.selectedEmailLayout && nextProps.Templates.selectedEmailLayout !== '' && !_.isEqual(this.props.Templates.selectedEmailLayout, nextProps.Templates.selectedEmailLayout )) {
340
335
  this.setNewLanguageContent(nextProps.Templates.selectedEmailLayout);
341
336
  }
@@ -364,7 +359,6 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
364
359
  }, 0);
365
360
  }
366
361
  if (nextProps.currentOrgDetails && nextProps.currentOrgDetails.basic_details && !_.isEmpty(nextProps.currentOrgDetails.basic_details) && _.isEmpty(this.state.formData)) {
367
- console.log('[Rafeeq manzoor] if condition');
368
362
  const formData = this.initFormData(nextProps);
369
363
  formData['template-version-options'] = [
370
364
  {
@@ -458,10 +452,8 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
458
452
  // Extract langId from active tab
459
453
  const activeTabForLang = beeTemplate.versions?.base?.activeTab || 'en';
460
454
  if (hasParamsId) {
461
- console.log('[Rafeeq manzoor] comes here 5');
462
455
  this.props.actions.getCmsSetting(BEE_PLUGIN, dragDropId, 'open', activeTabForLang, isBEESupport, isBEEAppEnable);
463
456
  } else if (nextProps.location.query.module !== "library" || (nextProps.location.query.module === "library" && !nextProps.templateData)) {
464
- console.log('[Rafeeq manzoor] comes here 6');
465
457
  this.props.actions.getCmsSetting(BEE_PLUGIN, dragDropId, 'create', undefined, isBEESupport, isBEEAppEnable);
466
458
  }
467
459
  }
@@ -478,10 +470,6 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
478
470
  }
479
471
  });
480
472
  }
481
- console.log('[Rafeeq manzoor] here we have data 1', this.state.isEdit, nextProps.location.query.module);
482
- console.log('[Rafeeq manzoor] here we have data 2', nextProps.templateData, !_.isEmpty(nextProps.templateData), this.props.params.id, nextProps.isGetFormData);
483
- console.log('[Rafeeq manzoor] here we have data 3', _.isEmpty(_.get(this, `state.formData['template-subject']`)));
484
-
485
473
  if (this.state.isEdit && nextProps.location.query.module === "library" && !_.isEmpty(nextProps.templateData) && !this.props.params.id && !nextProps.isGetFormData && _.isEmpty(_.get(this, `state.formData['template-subject']`))) {
486
474
  this.startTemplateCreation(nextProps.templateData);
487
475
  }
@@ -1250,7 +1238,6 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
1250
1238
  // formData.base.activeTab = language;
1251
1239
  // }
1252
1240
  if (language && editData.versions.base[language].is_drag_drop && isBEEAppEnable) {
1253
- console.log('[Rafeeq manzoor] comes here 7');
1254
1241
  this.props.actions.getCmsSetting(BEE_PLUGIN, editData._id, 'open', language, isBEESupport, isBEEAppEnable);
1255
1242
  }
1256
1243
  });
@@ -1474,7 +1461,6 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
1474
1461
  const currentTab = this.state.currentTab - 1;
1475
1462
  const baseLanguage = this.props.currentOrgDetails.basic_details.base_language ? this.props.currentOrgDetails.basic_details.base_language : 'en';
1476
1463
  if (formData[currentTab][baseLanguage].is_drag_drop && isBEEAppEnable) {
1477
- console.log('[Rafeeq manzoor] comes here 8');
1478
1464
  this.props.actions.getCmsSetting(BEE_PLUGIN, formData[currentTab][baseLanguage].drag_drop_id, 'duplicate', baseLanguage, isEdmSupport, isBEEAppEnable);
1479
1465
  }
1480
1466
  });
@@ -1653,9 +1639,6 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
1653
1639
  if (content.id) {
1654
1640
  tmpData.id = content.id;
1655
1641
  }
1656
- if (content.drag_drop_id) {
1657
- tmpData.drag_drop_id = content.drag_drop_id;
1658
- }
1659
1642
  }
1660
1643
  newFormData.base = _.cloneDeep(tmpData);
1661
1644
  newFormData.secondary_templates.push({template_data: tmpData});
@@ -2532,7 +2515,6 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
2532
2515
  const isBEEAppEnable = this.checkBeeEditorAllowedForLibrary();
2533
2516
  if (templates.drag_drop_id && isBEEAppEnable) {
2534
2517
  tempData.drag_drop_id = templates.drag_drop_id;
2535
- console.log('[Rafeeq manzoor] comes here 9');
2536
2518
  this.props.actions.getCmsSetting(BEE_PLUGIN, tempData._id, 'open', tempData.iso_code, isEdmSupport, isBEEAppEnable);
2537
2519
  }
2538
2520
  // formData.usingTabContainer = true;
@@ -2553,17 +2535,13 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
2553
2535
  });
2554
2536
  this.addLanguage(false, formData, false, additionalLanguages);
2555
2537
  }
2556
- console.log("[Rafeeq manzoor] comes here lib 1", formData[0])
2557
2538
  formData.base = _.cloneDeep(formData[0]);
2558
2539
  if (formData?.['template-subject'] !== '') {
2559
- console.log("[Rafeeq manzoor] comes here lib 1 if", formData)
2560
2540
  this.setState({formData, loading: false, injectedTags: data.tags, tabKey, isDragDrop: (data.base.is_drag_drop !== 0 )}, () => {
2561
2541
  // this.setState({tabKey: ''});
2562
2542
  const isBEEEnable = this.checkBeeEditorAllowedForLibrary();
2563
- console.log("[Rafeeq manzoor] comes here lib 1 isBEEEnable", isBEEEnable)
2564
2543
  _.forEach(formData[0].selectedLanguages, (language) => {
2565
2544
  if (formData[0][language].is_drag_drop && isBEEEnable) {
2566
- console.log('[Rafeeq manzoor] comes here 10');
2567
2545
  this.props.actions.getCmsSetting(BEE_PLUGIN, formData[0][language].drag_drop_id, 'open', language, isEdmSupport, isBEEEnable);
2568
2546
  }
2569
2547
  });
@@ -2906,7 +2884,6 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
2906
2884
  // let getQuery = '';
2907
2885
  const isEdmSupport = (this.props.location.query.isEdmSupport !== "false") || false;
2908
2886
  const isBEEAppEnable = this.checkBeeEditorAllowedForLibrary();
2909
- console.log('[Rafeeq manzoor] comes here 11');
2910
2887
  this.props.actions.getCmsSetting(BEE_PLUGIN, data._id, 'create', this.state.formData[this.state.currentTab - 1].activeTab, isEdmSupport, isBEEAppEnable);
2911
2888
  // this.props.templatesActions.setEdmTemplate(data);
2912
2889
  this.toggleEdmEmailTemplateSelection();