@capillarytech/creatives-library 8.0.307-alpha.0 → 8.0.307-alpha.5

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 (70) hide show
  1. package/constants/unified.js +1 -3
  2. package/initialState.js +2 -0
  3. package/package.json +1 -1
  4. package/utils/common.js +8 -5
  5. package/utils/commonUtils.js +95 -36
  6. package/utils/tagValidations.js +231 -83
  7. package/utils/tests/commonUtil.test.js +124 -147
  8. package/utils/tests/tagValidations.test.js +388 -437
  9. package/v2Components/CapTagListWithInput/index.js +4 -0
  10. package/v2Components/CapWhatsappCTA/index.js +2 -0
  11. package/v2Components/ErrorInfoNote/index.js +5 -2
  12. package/v2Components/FormBuilder/index.js +218 -137
  13. package/v2Components/FormBuilder/messages.js +8 -0
  14. package/v2Components/HtmlEditor/HTMLEditor.js +10 -0
  15. package/v2Components/HtmlEditor/__tests__/HTMLEditor.apiErrors.test.js +1 -0
  16. package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +15 -0
  17. package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +5 -1
  18. package/v2Containers/BeeEditor/index.js +3 -0
  19. package/v2Containers/Cap/mockData.js +14 -0
  20. package/v2Containers/Cap/reducer.js +55 -3
  21. package/v2Containers/Cap/tests/reducer.test.js +102 -0
  22. package/v2Containers/CreativesContainer/SlideBoxContent.js +26 -5
  23. package/v2Containers/CreativesContainer/SlideBoxFooter.js +5 -13
  24. package/v2Containers/CreativesContainer/constants.js +0 -6
  25. package/v2Containers/CreativesContainer/index.js +10 -47
  26. package/v2Containers/Email/index.js +6 -1
  27. package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +79 -23
  28. package/v2Containers/EmailWrapper/components/EmailWrapperView.js +3 -0
  29. package/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +121 -20
  30. package/v2Containers/EmailWrapper/components/__tests__/EmailWrapperView.test.js +1 -0
  31. package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +3 -0
  32. package/v2Containers/EmailWrapper/index.js +4 -0
  33. package/v2Containers/EmailWrapper/tests/useEmailWrapper.edgeCases.test.js +1 -0
  34. package/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +1 -0
  35. package/v2Containers/FTP/index.js +51 -2
  36. package/v2Containers/FTP/messages.js +4 -0
  37. package/v2Containers/InApp/index.js +110 -35
  38. package/v2Containers/InApp/tests/index.test.js +6 -17
  39. package/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +1 -0
  40. package/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +3 -0
  41. package/v2Containers/InAppWrapper/index.js +3 -0
  42. package/v2Containers/InappAdvance/index.js +115 -4
  43. package/v2Containers/InappAdvance/tests/index.test.js +0 -2
  44. package/v2Containers/Line/Container/Text/index.js +1 -0
  45. package/v2Containers/MobilePush/Create/index.js +21 -59
  46. package/v2Containers/MobilePush/Edit/index.js +22 -48
  47. package/v2Containers/MobilePushNew/index.js +33 -12
  48. package/v2Containers/MobilepushWrapper/index.js +3 -3
  49. package/v2Containers/Rcs/index.js +39 -12
  50. package/v2Containers/Sms/Create/index.js +5 -39
  51. package/v2Containers/Sms/Create/messages.js +0 -4
  52. package/v2Containers/Sms/Edit/index.js +5 -35
  53. package/v2Containers/Sms/commonMethods.js +6 -3
  54. package/v2Containers/SmsTrai/Edit/index.js +51 -11
  55. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +6 -6
  56. package/v2Containers/SmsWrapper/index.js +2 -2
  57. package/v2Containers/TagList/index.js +41 -2
  58. package/v2Containers/TagList/messages.js +4 -0
  59. package/v2Containers/TagList/tests/TagList.test.js +13 -1
  60. package/v2Containers/TagList/tests/mockdata.js +17 -0
  61. package/v2Containers/TemplatesV2/index.js +13 -28
  62. package/v2Containers/Viber/index.js +6 -0
  63. package/v2Containers/WebPush/Create/hooks/useTagManagement.js +5 -1
  64. package/v2Containers/WebPush/Create/hooks/useTagManagement.test.js +10 -0
  65. package/v2Containers/WebPush/Create/index.js +11 -3
  66. package/v2Containers/WebPush/Create/utils/validation.js +8 -17
  67. package/v2Containers/WebPush/Create/utils/validation.test.js +26 -44
  68. package/v2Containers/Whatsapp/index.js +23 -9
  69. package/v2Containers/Zalo/index.js +14 -3
  70. package/v2Containers/Sms/tests/commonMethods.test.js +0 -122
@@ -26,6 +26,10 @@ export default defineMessages({
26
26
  id: 'creatives.components.FormBuilder.missingTagsValidationError',
27
27
  defaultMessage: 'Missing tags: {missingTags}. Please add them to this message.',
28
28
  },
29
+ unsupportedTagsValidationError: {
30
+ id: 'creatives.components.FormBuilder.unsupportedTagsValidationError',
31
+ defaultMessage: 'Unsupported tags: {unsupportedTags}. Please remove them from this message.',
32
+ },
29
33
  genericTagsValidationError: {
30
34
  id: 'creatives.components.FormBuilder.genericTagsValidationError',
31
35
  defaultMessage: 'Please check the message content for unsupported/missing tags',
@@ -38,6 +42,10 @@ export default defineMessages({
38
42
  id: 'creatives.componentsV2.FormBuilder.missingTags',
39
43
  defaultMessage: 'Missing tags are:',
40
44
  },
45
+ unsupportedTags: {
46
+ id: 'creatives.componentsV2.FormBuilder.unsupportedTags',
47
+ defaultMessage: 'Unsupported tags are:',
48
+ },
41
49
  upload: {
42
50
  id: 'creatives.componentsV2.FormBuilder.upload',
43
51
  defaultMessage: 'Upload',
@@ -94,6 +94,7 @@ const HTMLEditor = forwardRef(({
94
94
  injectedTags = {},
95
95
  location,
96
96
  eventContextTags = [],
97
+ waitEventContextTags = {},
97
98
  selectedOfferDetails = [],
98
99
  channel,
99
100
  userLocale = 'en',
@@ -102,6 +103,7 @@ const HTMLEditor = forwardRef(({
102
103
  onTagSelect = null,
103
104
  onContextChange = null,
104
105
  globalActions = null,
106
+ isLiquidEnabled = false, // Controls Liquid tab visibility in ValidationTabs
105
107
  isFullMode = true, // Full mode vs library mode - controls layout and visibility
106
108
  onErrorAcknowledged = null, // Callback when user clicks redirection icon to acknowledge errors
107
109
  onValidationChange = null, // Callback when validation state changes (for parent to track errors)
@@ -573,6 +575,7 @@ const HTMLEditor = forwardRef(({
573
575
  content,
574
576
  layout,
575
577
  validation,
578
+ isLiquidEnabled,
576
579
  editorRef: getActiveEditorRef(),
577
580
  handleLabelInsert,
578
581
  handleSave,
@@ -592,6 +595,7 @@ const HTMLEditor = forwardRef(({
592
595
  content,
593
596
  layout,
594
597
  validation,
598
+ isLiquidEnabled,
595
599
  getActiveEditorRef,
596
600
  handleLabelInsert,
597
601
  handleSave,
@@ -663,6 +667,7 @@ const HTMLEditor = forwardRef(({
663
667
  injectedTags={injectedTags}
664
668
  location={location}
665
669
  eventContextTags={eventContextTags}
670
+ waitEventContextTags={waitEventContextTags}
666
671
  selectedOfferDetails={selectedOfferDetails}
667
672
  channel={channel}
668
673
  userLocale={userLocale}
@@ -734,6 +739,7 @@ const HTMLEditor = forwardRef(({
734
739
  injectedTags={injectedTags}
735
740
  location={location}
736
741
  eventContextTags={eventContextTags}
742
+ waitEventContextTags={waitEventContextTags}
737
743
  selectedOfferDetails={selectedOfferDetails}
738
744
  channel={channel}
739
745
  userLocale={userLocale}
@@ -772,6 +778,7 @@ HTMLEditor.propTypes = {
772
778
  injectedTags: PropTypes.object,
773
779
  location: PropTypes.object,
774
780
  eventContextTags: PropTypes.array,
781
+ waitEventContextTags: PropTypes.object,
775
782
  selectedOfferDetails: PropTypes.array,
776
783
  channel: PropTypes.string,
777
784
  userLocale: PropTypes.string,
@@ -780,6 +787,7 @@ HTMLEditor.propTypes = {
780
787
  onTagSelect: PropTypes.func,
781
788
  onContextChange: PropTypes.func, // Deprecated: use globalActions instead
782
789
  globalActions: PropTypes.object,
790
+ isLiquidEnabled: PropTypes.bool, // Controls Liquid tab visibility in validation
783
791
  isFullMode: PropTypes.bool, // Full mode vs library mode
784
792
  onErrorAcknowledged: PropTypes.func, // Callback when user clicks redirection icon to acknowledge errors
785
793
  onValidationChange: PropTypes.func, // Callback when validation state changes
@@ -805,6 +813,7 @@ HTMLEditor.defaultProps = {
805
813
  injectedTags: {},
806
814
  location: null,
807
815
  eventContextTags: [],
816
+ waitEventContextTags: {},
808
817
  selectedOfferDetails: [],
809
818
  channel: null,
810
819
  userLocale: 'en',
@@ -813,6 +822,7 @@ HTMLEditor.defaultProps = {
813
822
  onTagSelect: null,
814
823
  onContextChange: null,
815
824
  globalActions: null, // Redux actions for API calls
825
+ isLiquidEnabled: false,
816
826
  isFullMode: true, // Default to full mode
817
827
  onErrorAcknowledged: null, // Callback when user clicks redirection icon to acknowledge errors
818
828
  onValidationChange: null, // Callback when validation state changes
@@ -229,6 +229,7 @@ const defaultProps = {
229
229
  channel: 'EMAIL',
230
230
  userLocale: 'en',
231
231
  moduleFilterEnabled: true,
232
+ isLiquidEnabled: false,
232
233
  isFullMode: true,
233
234
  onErrorAcknowledged: jest.fn(),
234
235
  onValidationChange: jest.fn(),
@@ -3202,6 +3202,7 @@ describe('HTMLEditor', () => {
3202
3202
  onTagSelect={onTagSelect}
3203
3203
  onContextChange={onContextChange}
3204
3204
  globalActions={globalActions}
3205
+ isLiquidEnabled={true}
3205
3206
  isFullMode={false}
3206
3207
  onErrorAcknowledged={onErrorAcknowledged}
3207
3208
  onValidationChange={onValidationChange}
@@ -3261,6 +3262,20 @@ describe('HTMLEditor', () => {
3261
3262
  expect(screen.getByTestId('device-toggle')).toBeInTheDocument();
3262
3263
  });
3263
3264
 
3265
+ it('should handle isLiquidEnabled prop', () => {
3266
+ render(
3267
+ <TestWrapper>
3268
+ <HTMLEditor isLiquidEnabled={true} />
3269
+ </TestWrapper>
3270
+ );
3271
+
3272
+ act(() => {
3273
+ jest.runAllTimers();
3274
+ });
3275
+
3276
+ expect(screen.getByTestId('editor-toolbar')).toBeInTheDocument();
3277
+ });
3278
+
3264
3279
  it('should handle isFullMode prop', () => {
3265
3280
  render(
3266
3281
  <TestWrapper>
@@ -59,6 +59,7 @@ const CodeEditorPaneComponent = ({
59
59
  injectedTags = {},
60
60
  location,
61
61
  eventContextTags = [],
62
+ waitEventContextTags = {},
62
63
  selectedOfferDetails = [],
63
64
  channel,
64
65
  userLocale = 'en',
@@ -69,7 +70,7 @@ const CodeEditorPaneComponent = ({
69
70
  }) => {
70
71
  const context = useEditorContext();
71
72
  const {
72
- content, validation, variant,
73
+ content, validation, variant, isLiquidEnabled,
73
74
  } = context || {};
74
75
  const { content: contentValue, updateContent } = content || {};
75
76
  const editorRef = useRef(null);
@@ -289,6 +290,7 @@ const CodeEditorPaneComponent = ({
289
290
  location={location}
290
291
  selectedOfferDetails={selectedOfferDetails}
291
292
  eventContextTags={eventContextTags}
293
+ waitEventContextTags={waitEventContextTags}
292
294
  popoverPlacement="rightTop"
293
295
  />
294
296
  </CapRow>
@@ -298,6 +300,7 @@ const CodeEditorPaneComponent = ({
298
300
  <ValidationErrorDisplay
299
301
  validation={validation}
300
302
  onErrorClick={onErrorClick}
303
+ isLiquidEnabled={isLiquidEnabled}
301
304
  className="code-editor-pane__validation"
302
305
  />
303
306
  </div>
@@ -327,6 +330,7 @@ CodeEditorPane.propTypes = {
327
330
  injectedTags: PropTypes.object,
328
331
  location: PropTypes.object,
329
332
  eventContextTags: PropTypes.array,
333
+ waitEventContextTags: PropTypes.object,
330
334
  selectedOfferDetails: PropTypes.array,
331
335
  channel: PropTypes.string,
332
336
  userLocale: PropTypes.string,
@@ -53,6 +53,7 @@ function BeeEditor(props) {
53
53
  BEESelect,
54
54
  currentOrgDetails,
55
55
  eventContextTags,
56
+ waitEventContextTags,
56
57
  } = props;
57
58
  const { saveRowRequest } = BEESelect;
58
59
  const {formatMessage} = intl;
@@ -368,6 +369,7 @@ function BeeEditor(props) {
368
369
  }}
369
370
  onContextChange={onContextChange}
370
371
  eventContextTags={eventContextTags}
372
+ waitEventContextTags={waitEventContextTags}
371
373
  />
372
374
  <CapModal
373
375
  className="custom-row-modal"
@@ -414,6 +416,7 @@ BeeEditor.propTypes = {
414
416
  onContextChange: PropTypes.func,
415
417
  userLocale: PropTypes.string,
416
418
  eventContextTags: PropTypes.array,
419
+ waitEventContextTags: PropTypes.object,
417
420
  };
418
421
 
419
422
  const mapStateToProps = () => createStructuredSelector({
@@ -2,9 +2,11 @@ export const expectedStateGetLiquidTagsRequest = {
2
2
  fetchingLiquidTags: true,
3
3
  fetchingSchema: true,
4
4
  fetchingSchemaError: "",
5
+ liquidTags: [],
5
6
  messages: [],
6
7
  metaEntities: {
7
8
  layouts: [],
9
+ tagLookupMap: {},
8
10
  tags: [],
9
11
  },
10
12
  orgID: "",
@@ -15,9 +17,11 @@ export const expectedStateGetLiquidTagsFailure = {
15
17
  fetchingLiquidTags: false,
16
18
  fetchingSchema: true,
17
19
  fetchingSchemaError: "",
20
+ liquidTags: [],
18
21
  messages: [],
19
22
  metaEntities: {
20
23
  layouts: [],
24
+ tagLookupMap: {},
21
25
  tags: [],
22
26
  },
23
27
  orgID: "",
@@ -28,9 +32,11 @@ export const expectedStateGetLiquidTagsSuccess = {
28
32
  fetchingLiquidTags: false,
29
33
  fetchingSchema: true,
30
34
  fetchingSchemaError: "",
35
+ liquidTags: [],
31
36
  messages: [],
32
37
  metaEntities: {
33
38
  layouts: [],
39
+ tagLookupMap: {},
34
40
  tags: [],
35
41
  },
36
42
  orgID: "",
@@ -41,9 +47,11 @@ export const expectedStateGetSchemaForEntitySuccessTAG = {
41
47
  fetchingLiquidTags: false,
42
48
  fetchingSchema: false,
43
49
  fetchingSchemaError: false,
50
+ liquidTags: [],
44
51
  messages: [],
45
52
  metaEntities: {
46
53
  layouts: undefined,
54
+ tagLookupMap: { undefined: { definition: {} } },
47
55
  tags: { standard: { random: "32" } },
48
56
  },
49
57
  orgID: "",
@@ -54,9 +62,11 @@ export const expectedStateGetSchemaForEntitySuccess = {
54
62
  fetchingLiquidTags: false,
55
63
  fetchingSchema: false,
56
64
  fetchingSchemaError: false,
65
+ liquidTags: [],
57
66
  messages: [],
58
67
  metaEntities: {
59
68
  layouts: undefined,
69
+ tagLookupMap: undefined,
60
70
  tags: undefined,
61
71
  },
62
72
  orgID: "",
@@ -68,9 +78,13 @@ export const expectedForwardedTags = {
68
78
  fetchingSchema: false,
69
79
  fetchingSchemaError: '',
70
80
  injectedTags: undefined,
81
+ liquidTags: [],
71
82
  messages: [],
72
83
  metaEntities: {
73
84
  layouts: [],
85
+ tagLookupMap: {
86
+
87
+ },
74
88
  tags: [],
75
89
  },
76
90
  orgID: "",
@@ -1,11 +1,13 @@
1
1
  /**
2
2
  * Created by vivek on 22/5/17.
3
3
  */
4
- import { fromJS } from 'immutable';
4
+ import { fromJS, Map as ImmutableMap } from 'immutable';
5
5
  import _ from 'lodash';
6
6
  import * as types from './constants';
7
7
  import initialState from '../../initialState';
8
8
  import { FAILURE } from '../App/constants';
9
+ import { TAG } from '../Whatsapp/constants';
10
+ import { getTagMapValue, getForwardedMapValues, getLoyaltyTagsMapValue } from '../../utils/tagValidations';
9
11
 
10
12
  function capReducer(state = fromJS(initialState.cap), action) {
11
13
  switch (action.type) {
@@ -96,6 +98,39 @@ function capReducer(state = fromJS(initialState.cap), action) {
96
98
  return state
97
99
  .set('fetchingLiquidTags', false);
98
100
  case types.GET_SCHEMA_FOR_ENTITY_SUCCESS: {
101
+ //Process standard tags
102
+ const standardTagMapInitial = _.keyBy(
103
+ action?.data?.metaEntities?.standard,
104
+ item => item?.definition?.value
105
+ );
106
+ // Mapping only the `definition` object instead of the entire item, to reduce space used
107
+ const standardTagMap = _.mapValues(standardTagMapInitial, item => ({
108
+ definition: item?.definition ?? {},
109
+ }));
110
+
111
+ // Process custom tags
112
+ const customSubtags = getTagMapValue(action?.data?.metaEntities?.custom)
113
+ // Process extended tags
114
+ const extendedSubtags = getTagMapValue(action?.data?.metaEntities?.extended);
115
+
116
+ const loyaltySubTagsData = getLoyaltyTagsMapValue(action?.data?.metaEntities?.loyaltyTags);
117
+
118
+ const getExistingTagLookupMap = (state) => {
119
+ if (!state || !state.get) return {};
120
+ const tagLookupMap = state.getIn(['metaEntities', 'tagLookupMap']);
121
+ return state.get('metaEntities') && ImmutableMap.isMap(tagLookupMap)
122
+ ? tagLookupMap.toJS()
123
+ : {};
124
+ };
125
+
126
+ // Combine all maps
127
+ const combinedTagMap = {
128
+ ...standardTagMap,
129
+ ...customSubtags,
130
+ ...extendedSubtags,
131
+ ...loyaltySubTagsData,
132
+ ...getExistingTagLookupMap(state),
133
+ };
99
134
  const stateMeta = state.get("metaEntities");
100
135
  return state
101
136
  .set('fetchingSchema', false)
@@ -103,6 +138,7 @@ function capReducer(state = fromJS(initialState.cap), action) {
103
138
  .set('metaEntities', {
104
139
  layouts: action.data && action.entityType === 'LAYOUT' ? action.data.metaEntities : stateMeta?.layouts,
105
140
  tags: action.data && action.entityType === 'TAG' ? action.data.metaEntities : stateMeta?.tags,
141
+ tagLookupMap: action?.data && action?.entityType === TAG ? combinedTagMap : stateMeta?.tagLookupMap,
106
142
  })
107
143
  .set('fetchingSchemaError', false);
108
144
  }
@@ -110,6 +146,7 @@ function capReducer(state = fromJS(initialState.cap), action) {
110
146
  return state.set('metaEntities', {
111
147
  layouts: [],
112
148
  tags: [],
149
+ tagLookupMap: {},
113
150
  });
114
151
  // eslint-disable-next-line no-case-declarations
115
152
  case types.HIDE_TAGS:
@@ -117,8 +154,23 @@ function capReducer(state = fromJS(initialState.cap), action) {
117
154
  metaEntities.tags.standard = _.filter(state.get('metaEntities').tags.standard, (tag) => action.tagList.indexOf(tag.definition.value) === -1);
118
155
  metaEntities.tags.custom = _.filter(state.get('metaEntities').tags.custom, (tag) => action.tagList.indexOf(tag.name) === -1);
119
156
  return state.setIn(['metaEntities'], metaEntities);
120
- case types.SET_INJECTED_TAGS:
121
- return state.set("injectedTags", action.injectedTags);
157
+ case types.SET_INJECTED_TAGS:
158
+
159
+ // Deep clone the tagLookupMap to avoid direct mutations
160
+ let updatedMetaEntitiesTagLookUp = _.cloneDeep(state.getIn(['metaEntities', 'tagLookupMap']));
161
+ const formattedInjectedTags = getForwardedMapValues(action?.injectedTags);
162
+ // Merge the injectedTags with the existing tagLookupMap
163
+ updatedMetaEntitiesTagLookUp = {
164
+ ...formattedInjectedTags || {},
165
+ ...updatedMetaEntitiesTagLookUp || {},
166
+ };
167
+ return state.set("injectedTags", action.injectedTags).setIn(
168
+ ["metaEntities"],
169
+ fromJS({
170
+ ...state.get("metaEntities"),
171
+ tagLookupMap: updatedMetaEntitiesTagLookUp
172
+ })
173
+ );
122
174
  case types.GET_TOPBAR_MENU_DATA_REQUEST:
123
175
  return state.set('topbarMenuData', fromJS({ status: 'request' }));
124
176
  case types.GET_TOPBAR_MENU_DATA_SUCCESS:
@@ -21,6 +21,7 @@ import {
21
21
  expectedStateGetSchemaForEntitySuccessTAG,
22
22
  expectedStateGetSchemaForEntitySuccess,
23
23
  } from '../mockData';
24
+ import { TAG } from '../../Whatsapp/constants';
24
25
  import { loadItem } from '../../../services/localStorageApi';
25
26
 
26
27
 
@@ -117,3 +118,104 @@ describe('should handle GET_SUPPORT_VIDEOS_CONFIG', () => {
117
118
  expect(reducer(mockedInitialState, action).toJS())?.fetchingSchema?.toEqual(true);
118
119
  });
119
120
  });
121
+
122
+ describe('GET_SCHEMA_FOR_ENTITY_SUCCESS handler', () => {
123
+ it.concurrent('should handle existing tagLookupMap correctly when metaEntities and tagLookupMap exist', () => {
124
+ const initialStateTest = fromJS({
125
+ token: loadItem('token') || '',
126
+ orgID: loadItem('orgID') || '',
127
+ messages: [],
128
+ metaEntities: {
129
+ tags: [{ id: 1, name: 'tag1' }],
130
+ layouts: ['layout1', 'layout2'],
131
+ tagLookupMap: {
132
+ existingTag: { definition: { value: 'existing' } },
133
+ anotherTag: { definition: { value: 'another' } },
134
+ },
135
+ standard: [],
136
+ },
137
+ liquidTags: [],
138
+ fetchingLiquidTags: false,
139
+ fetchingSchema: false,
140
+ fetchingSchemaError: '',
141
+ });
142
+
143
+ let action = {
144
+ type: GET_SCHEMA_FOR_ENTITY_SUCCESS,
145
+ entityType: TAG,
146
+ data: {
147
+ metaEntities: {
148
+ standard: [],
149
+ custom: [],
150
+ extended: [],
151
+ },
152
+ },
153
+ };
154
+
155
+ let newState = reducer(initialStateTest, action);
156
+ let metaEntities = newState.get('metaEntities');
157
+
158
+ expect(metaEntities).toEqual(expect.objectContaining({
159
+ tagLookupMap: expect.objectContaining({
160
+ existingTag: expect.objectContaining({
161
+ definition: expect.objectContaining({
162
+ value: 'existing',
163
+ }),
164
+ }),
165
+ }),
166
+ }));
167
+
168
+ action = {
169
+ type: GET_SCHEMA_FOR_ENTITY_SUCCESS,
170
+ entityType: 'LAYOUT',
171
+ data: {
172
+ metaEntities: {
173
+ layouts: ['layout1', 'layout2'],
174
+ standard: [],
175
+ },
176
+ },
177
+ };
178
+ newState = reducer(initialStateTest, action);
179
+ metaEntities = newState.get('metaEntities');
180
+ expect(metaEntities).toEqual(expect.objectContaining({
181
+ layouts: expect.objectContaining({
182
+ layouts: expect.arrayContaining(['layout1', 'layout2']),
183
+ }),
184
+ }));
185
+ });
186
+
187
+ it.concurrent('should handle non-existent tagLookupMap by returning empty object', () => {
188
+ const initialStateTest = fromJS({
189
+ token: loadItem('token') || '',
190
+ orgID: loadItem('orgID') || '',
191
+ messages: [],
192
+ metaEntities: {
193
+ tagLookupMap: {},
194
+ },
195
+ liquidTags: [],
196
+ fetchingLiquidTags: false,
197
+ fetchingSchema: false,
198
+ fetchingSchemaError: '',
199
+ });
200
+
201
+ const action = {
202
+ type: GET_SCHEMA_FOR_ENTITY_SUCCESS,
203
+ entityType: TAG,
204
+ data: {
205
+ metaEntities: {
206
+ standard: [],
207
+ custom: [],
208
+ extended: [],
209
+ },
210
+ },
211
+ };
212
+
213
+ const newState = reducer(initialStateTest, action);
214
+ const metaEntities = newState.get('metaEntities');
215
+
216
+ // Updated assertions to handle plain object
217
+ expect(metaEntities).toBeDefined();
218
+ expect(metaEntities.tagLookupMap).toBeDefined();
219
+ expect(metaEntities.tagLookupMap).toEqual({});
220
+ });
221
+ });