@capillarytech/creatives-library 9.0.15-alpha.0 → 9.0.15-alpha.3
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 +29 -0
- package/global-styles.js +1 -1
- package/package.json +1 -1
- package/services/tests/api.test.js +35 -20
- package/utils/commonUtils.js +19 -1
- package/utils/rcsPayloadUtils.js +92 -0
- package/utils/templateVarUtils.js +201 -0
- package/utils/tests/rcsPayloadUtils.test.js +226 -0
- package/utils/tests/templateVarUtils.test.js +204 -0
- package/v2Components/CapActionButton/constants.js +8 -1
- package/v2Components/CapActionButton/index.js +202 -144
- package/v2Components/CapActionButton/index.scss +232 -14
- package/v2Components/CapActionButton/messages.js +19 -3
- package/v2Components/CapActionButton/tests/index.test.js +42 -18
- package/v2Components/CapImageUpload/index.js +2 -2
- package/v2Components/CapTagList/index.js +10 -0
- package/v2Components/CommonTestAndPreview/CustomValuesEditor.js +70 -48
- package/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +8 -2
- package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +214 -21
- package/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +16 -0
- package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +83 -9
- package/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +30 -0
- package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +60 -11
- package/v2Components/CommonTestAndPreview/SendTestMessage.js +10 -5
- package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js +202 -22
- package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +381 -80
- package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +155 -8
- package/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +11 -0
- package/v2Components/CommonTestAndPreview/constants.js +38 -2
- package/v2Components/CommonTestAndPreview/index.js +761 -222
- package/v2Components/CommonTestAndPreview/messages.js +45 -3
- package/v2Components/CommonTestAndPreview/previewApiUtils.js +59 -0
- package/v2Components/CommonTestAndPreview/sagas.js +25 -6
- package/v2Components/CommonTestAndPreview/tests/CommonTestAndPreview.addTestCustomer.test.js +1 -0
- package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +284 -267
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +231 -65
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/index.test.js +118 -5
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +341 -0
- package/v2Components/CommonTestAndPreview/tests/PreviewSection.test.js +8 -1
- package/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +34 -13
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/RcsPreviewContent.test.js +281 -283
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +199 -1
- package/v2Components/CommonTestAndPreview/tests/index.test.js +133 -4
- package/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +67 -0
- package/v2Components/CommonTestAndPreview/tests/sagas.test.js +31 -24
- package/v2Components/CommonTestAndPreview/utils.js +84 -0
- package/v2Components/SmsFallback/SmsFallbackLocalSelector.js +91 -0
- package/v2Components/SmsFallback/constants.js +94 -0
- package/v2Components/SmsFallback/index.js +958 -0
- package/v2Components/SmsFallback/index.scss +266 -0
- package/v2Components/SmsFallback/messages.js +78 -0
- package/v2Components/SmsFallback/smsFallbackUtils.js +120 -0
- package/v2Components/SmsFallback/tests/SmsFallbackLocalSelector.test.js +50 -0
- package/v2Components/SmsFallback/tests/rcsSmsFallback.acceptance.test.js +147 -0
- package/v2Components/SmsFallback/tests/smsFallbackHandlers.test.js +304 -0
- package/v2Components/SmsFallback/tests/smsFallbackUi.test.js +208 -0
- package/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +309 -0
- package/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +422 -0
- package/v2Components/SmsFallback/useLocalTemplateList.js +92 -0
- package/v2Components/TemplatePreview/_templatePreview.scss +45 -25
- package/v2Components/TemplatePreview/constants.js +2 -0
- package/v2Components/TemplatePreview/index.js +147 -32
- package/v2Components/TemplatePreview/tests/index.test.js +142 -0
- package/v2Components/TestAndPreviewSlidebox/CustomValuesEditor.js +6 -6
- package/v2Components/TestAndPreviewSlidebox/index.js +13 -1
- package/v2Components/TestAndPreviewSlidebox/sagas.js +11 -4
- package/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +3 -1
- package/v2Components/VarSegmentMessageEditor/constants.js +2 -0
- package/v2Components/VarSegmentMessageEditor/index.js +125 -0
- package/v2Components/VarSegmentMessageEditor/index.scss +46 -0
- package/v2Containers/CommunicationFlow/Tests/CommunicationFlow.test.js +4 -1
- package/v2Containers/CommunicationFlow/index.js +3 -3
- package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/DeliverySettingsSection.test.js +4 -0
- package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/SenderDetails.test.js +20 -20
- package/v2Containers/CreativesContainer/CreativesSlideBoxWrapper.js +17 -0
- package/v2Containers/CreativesContainer/SlideBoxContent.js +37 -4
- package/v2Containers/CreativesContainer/SlideBoxFooter.js +14 -5
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +36 -5
- package/v2Containers/CreativesContainer/constants.js +11 -0
- package/v2Containers/CreativesContainer/embeddedSlideboxUtils.js +79 -0
- package/v2Containers/CreativesContainer/index.js +323 -104
- package/v2Containers/CreativesContainer/index.scss +83 -1
- package/v2Containers/CreativesContainer/tests/SlideBoxContent.localTemplates.test.js +90 -0
- package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +79 -34
- package/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +79 -16
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +8 -0
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +333 -90
- package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +20 -15
- package/v2Containers/CreativesContainer/tests/embeddedSlideboxUtils.test.js +258 -0
- package/v2Containers/CreativesContainer/tests/index.test.js +71 -9
- package/v2Containers/CreativesContainer/tests/useLocalTemplatesProp.test.js +125 -0
- package/v2Containers/MobilePush/Create/test/saga.test.js +2 -2
- package/v2Containers/Rcs/constants.js +131 -11
- package/v2Containers/Rcs/index.js +2685 -832
- package/v2Containers/Rcs/index.scss +443 -8
- package/v2Containers/Rcs/messages.js +45 -6
- package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +227 -0
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +74176 -39409
- package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +10 -74
- package/v2Containers/Rcs/tests/index.test.js +151 -40
- package/v2Containers/Rcs/tests/mockData.js +38 -0
- package/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +318 -0
- package/v2Containers/Rcs/tests/utils.test.js +643 -30
- package/v2Containers/Rcs/utils.js +466 -12
- package/v2Containers/Sms/Create/index.js +115 -48
- package/v2Containers/Sms/smsFormDataHelpers.js +67 -0
- package/v2Containers/Sms/tests/smsFormDataHelpers.test.js +253 -0
- package/v2Containers/SmsTrai/Create/index.js +9 -4
- package/v2Containers/SmsTrai/Edit/constants.js +2 -0
- package/v2Containers/SmsTrai/Edit/index.js +678 -169
- package/v2Containers/SmsTrai/Edit/index.scss +126 -0
- package/v2Containers/SmsTrai/Edit/messages.js +14 -4
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +5615 -3014
- package/v2Containers/SmsWrapper/index.js +37 -8
- package/v2Containers/TagList/index.js +6 -0
- package/v2Containers/Templates/TemplatesActionBar.js +101 -0
- package/v2Containers/Templates/_templates.scss +196 -12
- package/v2Containers/Templates/actions.js +11 -0
- package/v2Containers/Templates/constants.js +2 -0
- package/v2Containers/Templates/index.js +131 -59
- package/v2Containers/Templates/sagas.js +57 -13
- package/v2Containers/Templates/tests/TemplatesActionBar.test.js +120 -0
- package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1060 -1015
- package/v2Containers/Templates/tests/sagas.test.js +199 -16
- package/v2Containers/Templates/tests/smsTemplatesListApi.test.js +180 -0
- package/v2Containers/Templates/utils/smsTemplatesListApi.js +79 -0
- package/v2Containers/TemplatesV2/TemplatesV2.style.js +72 -1
- package/v2Containers/TemplatesV2/index.js +86 -23
- package/v2Containers/TemplatesV2/tests/TemplatesV2.localTemplates.test.js +131 -0
- package/v2Containers/WeChat/MapTemplates/test/saga.test.js +9 -9
- package/v2Containers/Whatsapp/index.js +3 -20
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +578 -34
|
@@ -1,83 +1,108 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Tests for CustomValuesEditor component.
|
|
3
|
-
* Covers: loading state, values-missing warning, JSON view, tag table, discard/update buttons.
|
|
4
2
|
* @jest-environment jsdom
|
|
5
3
|
*/
|
|
6
|
-
|
|
7
4
|
import React from 'react';
|
|
8
5
|
import { render, screen, fireEvent } from '@testing-library/react';
|
|
6
|
+
import '@testing-library/jest-dom';
|
|
9
7
|
import { IntlProvider } from 'react-intl';
|
|
10
8
|
import PropTypes from 'prop-types';
|
|
9
|
+
import CustomValuesEditor from '../CustomValuesEditor';
|
|
11
10
|
|
|
12
|
-
jest.mock('@capillarytech/cap-ui-library/CapRow', () =>
|
|
13
|
-
|
|
14
|
-
)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
)
|
|
18
|
-
jest.mock('@capillarytech/cap-ui-library/
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
data-testid
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
11
|
+
jest.mock('@capillarytech/cap-ui-library/CapRow', () => {
|
|
12
|
+
const React = require('react');
|
|
13
|
+
return function CapRow(props) {
|
|
14
|
+
return React.createElement('div', { className: props?.className, 'data-testid': 'cap-row' }, props?.children);
|
|
15
|
+
};
|
|
16
|
+
});
|
|
17
|
+
jest.mock('@capillarytech/cap-ui-library/CapSpin', () => {
|
|
18
|
+
const React = require('react');
|
|
19
|
+
return function CapSpin() {
|
|
20
|
+
return React.createElement('div', { 'data-testid': 'cap-spin' }, 'spin');
|
|
21
|
+
};
|
|
22
|
+
});
|
|
23
|
+
jest.mock('@capillarytech/cap-ui-library/CapSwitch', () => {
|
|
24
|
+
const React = require('react');
|
|
25
|
+
return function CapSwitch(props) {
|
|
26
|
+
return React.createElement('input', {
|
|
27
|
+
type: 'checkbox',
|
|
28
|
+
'data-testid': 'json-switch',
|
|
29
|
+
checked: props?.checked,
|
|
30
|
+
onChange: (e) => props?.onChange?.(e.target.checked),
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
});
|
|
34
|
+
jest.mock('@capillarytech/cap-ui-library/CapButton', () => {
|
|
35
|
+
const React = require('react');
|
|
36
|
+
return function CapButton(props) {
|
|
37
|
+
return React.createElement('button', {
|
|
38
|
+
type: 'button',
|
|
39
|
+
'data-testid': 'cap-button',
|
|
40
|
+
onClick: props?.onClick,
|
|
41
|
+
disabled: props?.disabled,
|
|
42
|
+
'data-loading': props?.loading,
|
|
43
|
+
}, props?.children);
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
jest.mock('@capillarytech/cap-ui-library/CapInput', () => {
|
|
47
|
+
const React = require('react');
|
|
48
|
+
return function CapInput(props) {
|
|
49
|
+
return React.createElement('input', {
|
|
50
|
+
'data-testid': 'tag-input',
|
|
51
|
+
value: props?.value,
|
|
52
|
+
placeholder: props?.placeholder,
|
|
53
|
+
onChange: props?.onChange,
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
});
|
|
57
|
+
jest.mock('@capillarytech/cap-ui-library/CapLabel', () => {
|
|
58
|
+
const React = require('react');
|
|
59
|
+
return function CapLabel(props) {
|
|
60
|
+
return React.createElement('div', { className: props?.className, 'data-testid': 'cap-label' }, props?.children);
|
|
61
|
+
};
|
|
62
|
+
});
|
|
53
63
|
|
|
54
|
-
|
|
64
|
+
const formatMessage = (msg) => (typeof msg === 'object' && msg?.id ? msg.id : String(msg));
|
|
55
65
|
|
|
56
|
-
const
|
|
66
|
+
const baseProps = {
|
|
57
67
|
isExtractingTags: false,
|
|
58
68
|
isUpdatePreviewDisabled: false,
|
|
59
69
|
showJSON: false,
|
|
60
70
|
setShowJSON: jest.fn(),
|
|
61
|
-
customValues: { '
|
|
71
|
+
customValues: { 'tag.a': 'v1' },
|
|
62
72
|
handleJSONTextChange: jest.fn(),
|
|
63
|
-
|
|
64
|
-
{
|
|
65
|
-
|
|
73
|
+
sections: [
|
|
74
|
+
{
|
|
75
|
+
key: 'sec1',
|
|
76
|
+
title: 'Section A',
|
|
77
|
+
requiredTags: [{ fullPath: 'tag.a', name: 'a' }],
|
|
78
|
+
optionalTags: [{ fullPath: 'tag.b', name: 'b' }],
|
|
79
|
+
},
|
|
66
80
|
],
|
|
67
|
-
requiredTags: [{ fullPath: '{{customer.name}}' }],
|
|
68
|
-
optionalTags: [{ fullPath: '{{customer.email}}' }],
|
|
69
81
|
handleCustomValueChange: jest.fn(),
|
|
70
82
|
handleDiscardCustomValues: jest.fn(),
|
|
71
83
|
handleUpdatePreview: jest.fn(),
|
|
72
84
|
isUpdatingPreview: false,
|
|
73
|
-
formatMessage
|
|
85
|
+
formatMessage,
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const defaultProps = {
|
|
89
|
+
...baseProps,
|
|
90
|
+
customValues: {},
|
|
91
|
+
sections: [
|
|
92
|
+
{
|
|
93
|
+
key: 'default-sec',
|
|
94
|
+
title: 'Section',
|
|
95
|
+
requiredTags: [{ fullPath: '{{customer.name}}', name: 'customer.name' }],
|
|
96
|
+
optionalTags: [{ fullPath: '{{customer.email}}', name: 'customer.email' }],
|
|
97
|
+
},
|
|
98
|
+
],
|
|
74
99
|
};
|
|
75
100
|
|
|
76
101
|
// IntlProvider wrapper for incoming tests
|
|
77
102
|
const scope = 'app.v2Components.TestAndPreviewSlidebox';
|
|
78
103
|
const mockMessages = {
|
|
79
104
|
[`${scope}.extractingTags`]: 'Extracting tags...',
|
|
80
|
-
[`${scope}.valuesMissing`]: '
|
|
105
|
+
[`${scope}.valuesMissing`]: 'Some values are missing',
|
|
81
106
|
[`${scope}.showJSON`]: 'Show JSON',
|
|
82
107
|
[`${scope}.personalizationTags`]: 'Personalization Tags',
|
|
83
108
|
[`${scope}.customValues`]: 'Custom Values',
|
|
@@ -97,118 +122,128 @@ TestWrapper.propTypes = {
|
|
|
97
122
|
};
|
|
98
123
|
|
|
99
124
|
describe('CustomValuesEditor', () => {
|
|
100
|
-
beforeEach(() =>
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
it('renders a spinner and extracting-tags message when isExtractingTags is true', () => {
|
|
104
|
-
render(
|
|
105
|
-
<TestWrapper>
|
|
106
|
-
<CustomValuesEditor {...defaultProps} isExtractingTags />
|
|
107
|
-
</TestWrapper>
|
|
108
|
-
);
|
|
109
|
-
expect(screen.getByTestId('cap-spin')).toBeTruthy();
|
|
110
|
-
expect(screen.getByText('Extracting tags...')).toBeTruthy();
|
|
111
|
-
});
|
|
125
|
+
beforeEach(() => {
|
|
126
|
+
jest.clearAllMocks();
|
|
127
|
+
});
|
|
112
128
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
});
|
|
129
|
+
it('shows loading state when isExtractingTags', () => {
|
|
130
|
+
render(
|
|
131
|
+
<IntlProvider locale="en" messages={{}}>
|
|
132
|
+
<CustomValuesEditor {...baseProps} isExtractingTags />
|
|
133
|
+
</IntlProvider>,
|
|
134
|
+
);
|
|
135
|
+
expect(screen.getByTestId('cap-spin')).toBeInTheDocument();
|
|
136
|
+
});
|
|
122
137
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
expect(screen.getByTestId('cap-switch')).toBeTruthy();
|
|
131
|
-
});
|
|
138
|
+
it('shows values missing label when isUpdatePreviewDisabled', () => {
|
|
139
|
+
render(
|
|
140
|
+
<IntlProvider locale="en" messages={{}}>
|
|
141
|
+
<CustomValuesEditor {...baseProps} isUpdatePreviewDisabled />
|
|
142
|
+
</IntlProvider>,
|
|
143
|
+
);
|
|
144
|
+
expect(document.querySelector('.values-missing-message')).toBeTruthy();
|
|
132
145
|
});
|
|
133
146
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
147
|
+
it('toggles JSON mode and calls setShowJSON', () => {
|
|
148
|
+
const setShowJSON = jest.fn();
|
|
149
|
+
render(
|
|
150
|
+
<IntlProvider locale="en" messages={{}}>
|
|
151
|
+
<CustomValuesEditor {...baseProps} setShowJSON={setShowJSON} />
|
|
152
|
+
</IntlProvider>,
|
|
153
|
+
);
|
|
154
|
+
fireEvent.click(screen.getByTestId('json-switch'));
|
|
155
|
+
expect(setShowJSON).toHaveBeenCalled();
|
|
156
|
+
});
|
|
143
157
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
});
|
|
158
|
+
it('renders JSON textarea and fires handleJSONTextChange', () => {
|
|
159
|
+
render(
|
|
160
|
+
<IntlProvider locale="en" messages={{}}>
|
|
161
|
+
<CustomValuesEditor {...baseProps} showJSON />
|
|
162
|
+
</IntlProvider>,
|
|
163
|
+
);
|
|
164
|
+
const ta = document.querySelector('.json-textarea');
|
|
165
|
+
expect(ta).toBeTruthy();
|
|
166
|
+
fireEvent.change(ta, { target: { value: '{}' } });
|
|
167
|
+
expect(baseProps.handleJSONTextChange).toHaveBeenCalledWith('{}');
|
|
154
168
|
});
|
|
155
169
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
});
|
|
170
|
+
it('renders required and optional tag inputs when not JSON', () => {
|
|
171
|
+
render(
|
|
172
|
+
<IntlProvider locale="en" messages={{}}>
|
|
173
|
+
<CustomValuesEditor {...baseProps} />
|
|
174
|
+
</IntlProvider>,
|
|
175
|
+
);
|
|
176
|
+
const inputs = screen.getAllByTestId('tag-input');
|
|
177
|
+
expect(inputs.length).toBeGreaterThan(0);
|
|
178
|
+
fireEvent.change(inputs[0], { target: { value: 'new' } });
|
|
179
|
+
expect(baseProps.handleCustomValueChange).toHaveBeenCalledWith('tag.a', 'new');
|
|
180
|
+
});
|
|
168
181
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
<
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
182
|
+
it('calls discard and update handlers', () => {
|
|
183
|
+
render(
|
|
184
|
+
<IntlProvider locale="en" messages={{}}>
|
|
185
|
+
<CustomValuesEditor {...baseProps} />
|
|
186
|
+
</IntlProvider>,
|
|
187
|
+
);
|
|
188
|
+
const buttons = screen.getAllByTestId('cap-button');
|
|
189
|
+
fireEvent.click(buttons[0]);
|
|
190
|
+
fireEvent.click(buttons[buttons.length - 1]);
|
|
191
|
+
expect(baseProps.handleDiscardCustomValues).toHaveBeenCalled();
|
|
192
|
+
expect(baseProps.handleUpdatePreview).toHaveBeenCalled();
|
|
193
|
+
});
|
|
180
194
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
195
|
+
it('skips sections with no tags', () => {
|
|
196
|
+
render(
|
|
197
|
+
<IntlProvider locale="en" messages={{}}>
|
|
198
|
+
<CustomValuesEditor
|
|
199
|
+
{...baseProps}
|
|
200
|
+
sections={[
|
|
201
|
+
{ key: 'empty', requiredTags: [], optionalTags: [] },
|
|
202
|
+
baseProps.sections[0],
|
|
203
|
+
]}
|
|
204
|
+
/>
|
|
205
|
+
</IntlProvider>,
|
|
206
|
+
);
|
|
207
|
+
expect(screen.getAllByTestId('tag-input').length).toBeGreaterThan(0);
|
|
208
|
+
});
|
|
191
209
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
210
|
+
it('renders section title as FormattedMessage when title is an intl message object (not a string)', () => {
|
|
211
|
+
render(
|
|
212
|
+
<IntlProvider locale="en" messages={{ 'section.title.id': 'Intl Section Title' }}>
|
|
213
|
+
<CustomValuesEditor
|
|
214
|
+
{...baseProps}
|
|
215
|
+
sections={[
|
|
216
|
+
{
|
|
217
|
+
key: 'intl-sec',
|
|
218
|
+
title: { id: 'section.title.id', defaultMessage: 'Intl Section Title' },
|
|
219
|
+
requiredTags: [{ fullPath: 'tag.a', name: 'a' }],
|
|
220
|
+
optionalTags: [],
|
|
221
|
+
},
|
|
222
|
+
]}
|
|
223
|
+
/>
|
|
224
|
+
</IntlProvider>,
|
|
225
|
+
);
|
|
226
|
+
expect(screen.getByText('Intl Section Title')).toBeInTheDocument();
|
|
200
227
|
});
|
|
201
228
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
<
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
229
|
+
it('renders section title as plain text when title is a string', () => {
|
|
230
|
+
render(
|
|
231
|
+
<IntlProvider locale="en" messages={{}}>
|
|
232
|
+
<CustomValuesEditor
|
|
233
|
+
{...baseProps}
|
|
234
|
+
sections={[
|
|
235
|
+
{
|
|
236
|
+
key: 'str-sec',
|
|
237
|
+
title: 'Plain String Title',
|
|
238
|
+
requiredTags: [{ fullPath: 'tag.a', name: 'a' }],
|
|
239
|
+
optionalTags: [],
|
|
240
|
+
},
|
|
241
|
+
]}
|
|
242
|
+
/>
|
|
243
|
+
</IntlProvider>,
|
|
244
|
+
);
|
|
245
|
+
expect(screen.getByText('Plain String Title')).toBeInTheDocument();
|
|
246
|
+
});
|
|
212
247
|
|
|
213
248
|
it('renders required tags with a required indicator (*)', () => {
|
|
214
249
|
render(
|
|
@@ -239,124 +274,106 @@ describe('CustomValuesEditor', () => {
|
|
|
239
274
|
expect(screen.getByText('{{customer.email}}')).toBeTruthy();
|
|
240
275
|
});
|
|
241
276
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
<CustomValuesEditor {...defaultProps} showJSON={false} />
|
|
261
|
-
</TestWrapper>
|
|
262
|
-
);
|
|
263
|
-
const inputs = screen.getAllByTestId('cap-input');
|
|
264
|
-
fireEvent.change(inputs[0], { target: { value: 'Bob' } });
|
|
265
|
-
expect(defaultProps.handleCustomValueChange).toHaveBeenCalledWith('{{customer.name}}', 'Bob');
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
it('calls handleCustomValueChange with the tag path and new value for optional tags', () => {
|
|
269
|
-
render(
|
|
270
|
-
<TestWrapper>
|
|
271
|
-
<CustomValuesEditor {...defaultProps} showJSON={false} />
|
|
272
|
-
</TestWrapper>
|
|
273
|
-
);
|
|
274
|
-
const inputs = screen.getAllByTestId('cap-input');
|
|
275
|
-
fireEvent.change(inputs[1], { target: { value: 'bob@example.com' } });
|
|
276
|
-
expect(defaultProps.handleCustomValueChange).toHaveBeenCalledWith(
|
|
277
|
-
'{{customer.email}}',
|
|
278
|
-
'bob@example.com'
|
|
279
|
-
);
|
|
280
|
-
});
|
|
277
|
+
it('uses empty string as column label when both fullPath and name are absent', () => {
|
|
278
|
+
render(
|
|
279
|
+
<IntlProvider locale="en" messages={{}}>
|
|
280
|
+
<CustomValuesEditor
|
|
281
|
+
{...baseProps}
|
|
282
|
+
sections={[
|
|
283
|
+
{
|
|
284
|
+
key: 'no-label',
|
|
285
|
+
title: 'Section',
|
|
286
|
+
requiredTags: [{}],
|
|
287
|
+
optionalTags: [],
|
|
288
|
+
},
|
|
289
|
+
]}
|
|
290
|
+
/>
|
|
291
|
+
</IntlProvider>,
|
|
292
|
+
);
|
|
293
|
+
const inputs = screen.getAllByTestId('tag-input');
|
|
294
|
+
expect(inputs.length).toBeGreaterThan(0);
|
|
281
295
|
});
|
|
282
296
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
<
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
});
|
|
297
|
+
it('renders optional-only section (no requiredTags) correctly', () => {
|
|
298
|
+
render(
|
|
299
|
+
<IntlProvider locale="en" messages={{}}>
|
|
300
|
+
<CustomValuesEditor
|
|
301
|
+
{...baseProps}
|
|
302
|
+
sections={[
|
|
303
|
+
{
|
|
304
|
+
key: 'optional-only',
|
|
305
|
+
title: 'Optional Section',
|
|
306
|
+
requiredTags: [],
|
|
307
|
+
optionalTags: [{ fullPath: 'tag.opt', name: 'opt' }],
|
|
308
|
+
},
|
|
309
|
+
]}
|
|
310
|
+
/>
|
|
311
|
+
</IntlProvider>,
|
|
312
|
+
);
|
|
313
|
+
expect(screen.getByText('Optional Section')).toBeInTheDocument();
|
|
314
|
+
const inputs = screen.getAllByTestId('tag-input');
|
|
315
|
+
expect(inputs.length).toBeGreaterThan(0);
|
|
303
316
|
});
|
|
304
317
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
<
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
expect(defaultProps.handleUpdatePreview).toHaveBeenCalled();
|
|
326
|
-
});
|
|
327
|
-
|
|
328
|
-
it('disables the update-preview button when isUpdatePreviewDisabled is true', () => {
|
|
329
|
-
render(
|
|
330
|
-
<TestWrapper>
|
|
331
|
-
<CustomValuesEditor {...defaultProps} isUpdatePreviewDisabled />
|
|
332
|
-
</TestWrapper>
|
|
333
|
-
);
|
|
334
|
-
const buttons = screen.getAllByTestId('cap-button');
|
|
335
|
-
expect(buttons[1].disabled).toBe(true);
|
|
336
|
-
});
|
|
318
|
+
it('renders required-only section (no optionalTags) correctly', () => {
|
|
319
|
+
render(
|
|
320
|
+
<IntlProvider locale="en" messages={{}}>
|
|
321
|
+
<CustomValuesEditor
|
|
322
|
+
{...baseProps}
|
|
323
|
+
sections={[
|
|
324
|
+
{
|
|
325
|
+
key: 'required-only',
|
|
326
|
+
title: 'Required Section',
|
|
327
|
+
requiredTags: [{ fullPath: 'tag.req', name: 'req' }],
|
|
328
|
+
optionalTags: [],
|
|
329
|
+
},
|
|
330
|
+
]}
|
|
331
|
+
/>
|
|
332
|
+
</IntlProvider>,
|
|
333
|
+
);
|
|
334
|
+
expect(screen.getByText('Required Section')).toBeInTheDocument();
|
|
335
|
+
const inputs = screen.getAllByTestId('tag-input');
|
|
336
|
+
expect(inputs.length).toBeGreaterThan(0);
|
|
337
|
+
});
|
|
337
338
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
339
|
+
it('renders line numbers in JSON mode matching JSON line count', () => {
|
|
340
|
+
const multiValueCustomValues = { a: 'val1', b: 'val2', c: 'val3' };
|
|
341
|
+
render(
|
|
342
|
+
<IntlProvider locale="en" messages={{}}>
|
|
343
|
+
<CustomValuesEditor
|
|
344
|
+
{...baseProps}
|
|
345
|
+
showJSON
|
|
346
|
+
customValues={multiValueCustomValues}
|
|
347
|
+
/>
|
|
348
|
+
</IntlProvider>,
|
|
349
|
+
);
|
|
350
|
+
const lineNumbers = document.querySelectorAll('.line-number');
|
|
351
|
+
const expectedLineCount = JSON.stringify(multiValueCustomValues, null, 2).split('\n').length;
|
|
352
|
+
expect(lineNumbers.length).toBe(expectedLineCount);
|
|
353
|
+
});
|
|
347
354
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
355
|
+
it('passes fullPath as key for required tag row when fullPath is present', () => {
|
|
356
|
+
const handleChange = jest.fn();
|
|
357
|
+
render(
|
|
358
|
+
<IntlProvider locale="en" messages={{}}>
|
|
359
|
+
<CustomValuesEditor
|
|
360
|
+
{...baseProps}
|
|
361
|
+
sections={[
|
|
362
|
+
{
|
|
363
|
+
key: 'sec',
|
|
364
|
+
title: 'S',
|
|
365
|
+
requiredTags: [{ fullPath: 'my.full.path', name: 'name' }],
|
|
366
|
+
optionalTags: [],
|
|
367
|
+
},
|
|
368
|
+
]}
|
|
369
|
+
handleCustomValueChange={handleChange}
|
|
370
|
+
customValues={{ 'my.full.path': 'existing' }}
|
|
371
|
+
/>
|
|
372
|
+
</IntlProvider>,
|
|
373
|
+
);
|
|
374
|
+
const input = screen.getByTestId('tag-input');
|
|
375
|
+
expect(input.value).toBe('existing');
|
|
376
|
+
fireEvent.change(input, { target: { value: 'updated' } });
|
|
377
|
+
expect(handleChange).toHaveBeenCalledWith('my.full.path', 'updated');
|
|
361
378
|
});
|
|
362
379
|
});
|