box-ui-elements 23.3.1-beta.1 → 23.4.0-beta.2
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/dist/explorer.js +1 -1
- package/dist/preview.js +1 -1
- package/dist/sharing.js +1 -1
- package/dist/sharing.js.LICENSE.txt +10 -0
- package/dist/sidebar.js +1 -1
- package/es/common/types/metadata.js.flow +1 -0
- package/es/common/types/metadata.js.map +1 -1
- package/es/components/notification/Notification.js +17 -8
- package/es/components/notification/Notification.js.flow +15 -8
- package/es/components/notification/Notification.js.map +1 -1
- package/es/features/metadata-instance-editor/CascadePolicy.js +6 -2
- package/es/features/metadata-instance-editor/CascadePolicy.js.flow +19 -12
- package/es/features/metadata-instance-editor/CascadePolicy.js.map +1 -1
- package/es/features/metadata-instance-editor/Instance.js +31 -9
- package/es/features/metadata-instance-editor/Instance.js.flow +41 -9
- package/es/features/metadata-instance-editor/Instance.js.map +1 -1
- package/es/features/metadata-instance-editor/Instances.js +2 -0
- package/es/features/metadata-instance-editor/Instances.js.flow +3 -0
- package/es/features/metadata-instance-editor/Instances.js.map +1 -1
- package/es/features/metadata-instance-editor/MetadataInstanceEditor.js +2 -0
- package/es/features/metadata-instance-editor/MetadataInstanceEditor.js.flow +3 -0
- package/es/features/metadata-instance-editor/MetadataInstanceEditor.js.map +1 -1
- package/es/features/metadata-instance-editor/TemplateDropdown.js +1 -1
- package/es/features/metadata-instance-editor/TemplateDropdown.js.flow +1 -1
- package/es/features/metadata-instance-editor/TemplateDropdown.js.map +1 -1
- package/es/features/metadata-instance-editor/TemplatedInstance.js +2 -0
- package/es/features/metadata-instance-editor/TemplatedInstance.js.flow +11 -1
- package/es/features/metadata-instance-editor/TemplatedInstance.js.map +1 -1
- package/es/features/metadata-instance-editor/constants.js +2 -1
- package/es/features/metadata-instance-editor/constants.js.flow +3 -1
- package/es/features/metadata-instance-editor/constants.js.map +1 -1
- package/es/features/metadata-instance-fields/DateMetadataField.js +30 -25
- package/es/features/metadata-instance-fields/DateMetadataField.js.flow +31 -27
- package/es/features/metadata-instance-fields/DateMetadataField.js.map +1 -1
- package/es/features/metadata-instance-fields/EnumMetadataField.js +8 -5
- package/es/features/metadata-instance-fields/EnumMetadataField.js.flow +8 -6
- package/es/features/metadata-instance-fields/EnumMetadataField.js.map +1 -1
- package/es/features/metadata-instance-fields/FloatMetadataField.js +2 -0
- package/es/features/metadata-instance-fields/FloatMetadataField.js.flow +3 -0
- package/es/features/metadata-instance-fields/FloatMetadataField.js.map +1 -1
- package/es/features/metadata-instance-fields/IntegerMetadataField.js +2 -0
- package/es/features/metadata-instance-fields/IntegerMetadataField.js.flow +3 -0
- package/es/features/metadata-instance-fields/IntegerMetadataField.js.map +1 -1
- package/es/features/metadata-instance-fields/MetadataField.js +7 -0
- package/es/features/metadata-instance-fields/MetadataField.js.flow +8 -0
- package/es/features/metadata-instance-fields/MetadataField.js.map +1 -1
- package/es/features/metadata-instance-fields/MultiSelectMetadataField.js +2 -0
- package/es/features/metadata-instance-fields/MultiSelectMetadataField.js.flow +3 -0
- package/es/features/metadata-instance-fields/MultiSelectMetadataField.js.map +1 -1
- package/es/features/metadata-instance-fields/TextMetadataField.js +8 -5
- package/es/features/metadata-instance-fields/TextMetadataField.js.flow +8 -6
- package/es/features/metadata-instance-fields/TextMetadataField.js.map +1 -1
- package/package.json +1 -1
- package/src/common/types/metadata.js +1 -0
- package/src/components/notification/Notification.js +15 -8
- package/src/components/notification/__tests__/Notification.test.js +21 -1
- package/src/features/metadata-instance-editor/CascadePolicy.js +19 -12
- package/src/features/metadata-instance-editor/Instance.js +41 -9
- package/src/features/metadata-instance-editor/Instances.js +3 -0
- package/src/features/metadata-instance-editor/MetadataInstanceEditor.js +3 -0
- package/src/features/metadata-instance-editor/TemplateDropdown.js +1 -1
- package/src/features/metadata-instance-editor/TemplatedInstance.js +11 -1
- package/src/features/metadata-instance-editor/__tests__/CascadePolicy.test.js +92 -1
- package/src/features/metadata-instance-editor/__tests__/Instance.test.js +207 -2
- package/src/features/metadata-instance-editor/__tests__/Instances.test.js +92 -3
- package/src/features/metadata-instance-editor/__tests__/MetadataInstanceEditor.test.js +105 -0
- package/src/features/metadata-instance-editor/__tests__/TemplatedInstance.test.js +83 -1
- package/src/features/metadata-instance-editor/__tests__/__snapshots__/CascadePolicy.test.js.snap +1 -0
- package/src/features/metadata-instance-editor/__tests__/__snapshots__/Instance.test.js.snap +16 -5
- package/src/features/metadata-instance-editor/__tests__/__snapshots__/Instances.test.js.snap +4 -2
- package/src/features/metadata-instance-editor/__tests__/__snapshots__/MetadataInstanceEditor.test.js.snap +1 -0
- package/src/features/metadata-instance-editor/__tests__/__snapshots__/TemplatedInstance.test.js.snap +2 -2
- package/src/features/metadata-instance-editor/constants.js +3 -1
- package/src/features/metadata-instance-fields/DateMetadataField.js +31 -27
- package/src/features/metadata-instance-fields/EnumMetadataField.js +8 -6
- package/src/features/metadata-instance-fields/FloatMetadataField.js +3 -0
- package/src/features/metadata-instance-fields/IntegerMetadataField.js +3 -0
- package/src/features/metadata-instance-fields/MetadataField.js +8 -0
- package/src/features/metadata-instance-fields/MultiSelectMetadataField.js +3 -0
- package/src/features/metadata-instance-fields/TextMetadataField.js +8 -6
- package/src/features/metadata-instance-fields/__tests__/DateMetadataField.test.js +59 -8
- package/src/features/metadata-instance-fields/__tests__/EnumMetadataField.test.js +63 -18
- package/src/features/metadata-instance-fields/__tests__/FloatMetadataField.test.js +68 -4
- package/src/features/metadata-instance-fields/__tests__/IntegerMetadataField.test.js +90 -4
- package/src/features/metadata-instance-fields/__tests__/MultiSelectMetadataField.test.js +95 -7
- package/src/features/metadata-instance-fields/__tests__/TextMetadataField.test.js +107 -14
- package/src/features/metadata-instance-fields/__tests__/__snapshots__/DateMetadataField.test.js.snap +0 -18
- package/src/features/metadata-instance-fields/__tests__/__snapshots__/EnumMetadataField.test.js.snap +0 -84
- package/src/features/metadata-instance-fields/__tests__/__snapshots__/FloatMetadataField.test.js.snap +0 -8
- package/src/features/metadata-instance-fields/__tests__/__snapshots__/IntegerMetadataField.test.js.snap +0 -8
- package/src/features/metadata-instance-fields/__tests__/__snapshots__/MultiSelectMetadataField.test.js.snap +0 -58
- package/src/features/metadata-instance-fields/__tests__/__snapshots__/TextMetadataField.test.js.snap +0 -31
|
@@ -13,12 +13,21 @@ type Props = {
|
|
|
13
13
|
canEdit: boolean,
|
|
14
14
|
data: MetadataFields,
|
|
15
15
|
errors: { [string]: React.Node },
|
|
16
|
+
isDisabled?: boolean,
|
|
16
17
|
onFieldChange?: (key: string, value: MetadataFieldValue, type: string) => void,
|
|
17
18
|
onFieldRemove?: (key: string) => void,
|
|
18
19
|
template: MetadataTemplate,
|
|
19
20
|
};
|
|
20
21
|
|
|
21
|
-
const TemplatedInstance = ({
|
|
22
|
+
const TemplatedInstance = ({
|
|
23
|
+
canEdit,
|
|
24
|
+
data = {},
|
|
25
|
+
errors,
|
|
26
|
+
isDisabled,
|
|
27
|
+
onFieldChange,
|
|
28
|
+
onFieldRemove,
|
|
29
|
+
template,
|
|
30
|
+
}: Props) => {
|
|
22
31
|
const { fields = [] } = template;
|
|
23
32
|
const hasFields = fields.length > 0;
|
|
24
33
|
const hasVisibleFields = hasFields && fields.some(field => !isHidden(field));
|
|
@@ -39,6 +48,7 @@ const TemplatedInstance = ({ canEdit, data = {}, errors, onFieldChange, onFieldR
|
|
|
39
48
|
description={field.description}
|
|
40
49
|
displayName={field.displayName}
|
|
41
50
|
error={errors[field.key]}
|
|
51
|
+
isDisabled={isDisabled}
|
|
42
52
|
isHidden={isHidden(field)} // Checking both isHidden and hidden attributes due to differences in V2 and V3 APIs
|
|
43
53
|
onChange={(key: string, value: MetadataFieldValue) => {
|
|
44
54
|
if (canEdit && onFieldChange) {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
|
|
3
|
+
import userEvent from '@testing-library/user-event';
|
|
4
|
+
|
|
3
5
|
import { screen, render, within } from '../../../test-utils/testing-library';
|
|
4
6
|
|
|
5
7
|
import CascadePolicy from '../CascadePolicy';
|
|
@@ -95,8 +97,97 @@ describe('features/metadata-instance-editor/CascadePolicy', () => {
|
|
|
95
97
|
|
|
96
98
|
describe('AI Agent Selector', () => {
|
|
97
99
|
test('should render AI agent selector with default to basic when AI features are enabled', () => {
|
|
98
|
-
render(
|
|
100
|
+
render(
|
|
101
|
+
<CascadePolicy
|
|
102
|
+
canEdit
|
|
103
|
+
canUseAIFolderExtraction
|
|
104
|
+
canUseAIFolderExtractionAgentSelector
|
|
105
|
+
shouldShowCascadeOptions
|
|
106
|
+
/>,
|
|
107
|
+
);
|
|
99
108
|
expect(screen.getByRole('button', { name: 'Agent Basic' })).toBeInTheDocument();
|
|
100
109
|
});
|
|
110
|
+
|
|
111
|
+
test('should not render AI agent selector when canUseAIFolderExtractionAgentSelector is false', () => {
|
|
112
|
+
render(<CascadePolicy canEdit canUseAIFolderExtraction shouldShowCascadeOptions />);
|
|
113
|
+
expect(screen.queryByRole('button', { name: 'Agent Basic' })).not.toBeInTheDocument();
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
describe('AI Autofill Toggle', () => {
|
|
118
|
+
test('should disable toggle when isExistingAIExtractionCascadePolicy is true', () => {
|
|
119
|
+
render(
|
|
120
|
+
<CascadePolicy
|
|
121
|
+
canEdit
|
|
122
|
+
canUseAIFolderExtraction
|
|
123
|
+
shouldShowCascadeOptions
|
|
124
|
+
isExistingAIExtractionCascadePolicy
|
|
125
|
+
/>,
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
const aiSection = screen.getByTestId('ai-folder-extraction');
|
|
129
|
+
const toggle = within(aiSection).getByRole('switch');
|
|
130
|
+
|
|
131
|
+
expect(toggle).toBeDisabled();
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
test('should enable toggle when isExistingAIExtractionCascadePolicy is false', () => {
|
|
135
|
+
render(
|
|
136
|
+
<CascadePolicy
|
|
137
|
+
canEdit
|
|
138
|
+
canUseAIFolderExtraction
|
|
139
|
+
shouldShowCascadeOptions
|
|
140
|
+
isExistingAIExtractionCascadePolicy={false}
|
|
141
|
+
/>,
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
const aiSection = screen.getByTestId('ai-folder-extraction');
|
|
145
|
+
const toggle = within(aiSection).getByRole('switch');
|
|
146
|
+
|
|
147
|
+
expect(toggle).not.toBeDisabled();
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
test('should call onAIFolderExtractionToggle when toggle is clicked and enabled', async () => {
|
|
151
|
+
const onAIFolderExtractionToggle = jest.fn();
|
|
152
|
+
|
|
153
|
+
render(
|
|
154
|
+
<CascadePolicy
|
|
155
|
+
canEdit
|
|
156
|
+
canUseAIFolderExtraction
|
|
157
|
+
shouldShowCascadeOptions
|
|
158
|
+
isExistingAIExtractionCascadePolicy={false}
|
|
159
|
+
onAIFolderExtractionToggle={onAIFolderExtractionToggle}
|
|
160
|
+
/>,
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
const aiSection = screen.getByTestId('ai-folder-extraction');
|
|
164
|
+
const toggle = within(aiSection).getByRole('switch');
|
|
165
|
+
|
|
166
|
+
await userEvent.click(toggle);
|
|
167
|
+
|
|
168
|
+
expect(onAIFolderExtractionToggle).toHaveBeenCalledTimes(1);
|
|
169
|
+
expect(onAIFolderExtractionToggle).toHaveBeenCalledWith(true);
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
test('should not call onAIFolderExtractionToggle when toggle is clicked but disabled', async () => {
|
|
173
|
+
const onAIFolderExtractionToggle = jest.fn();
|
|
174
|
+
|
|
175
|
+
render(
|
|
176
|
+
<CascadePolicy
|
|
177
|
+
canEdit
|
|
178
|
+
canUseAIFolderExtraction
|
|
179
|
+
shouldShowCascadeOptions
|
|
180
|
+
isExistingAIExtractionCascadePolicy={true}
|
|
181
|
+
onAIFolderExtractionToggle={onAIFolderExtractionToggle}
|
|
182
|
+
/>,
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
const aiSection = screen.getByTestId('ai-folder-extraction');
|
|
186
|
+
const toggle = within(aiSection).getByRole('switch');
|
|
187
|
+
|
|
188
|
+
await userEvent.click(toggle);
|
|
189
|
+
|
|
190
|
+
expect(onAIFolderExtractionToggle).not.toHaveBeenCalled();
|
|
191
|
+
});
|
|
101
192
|
});
|
|
102
193
|
});
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
|
|
3
|
-
import
|
|
2
|
+
import userEvent from '@testing-library/user-event';
|
|
3
|
+
import { createIntl } from 'react-intl';
|
|
4
|
+
import { render, screen, within } from '../../../test-utils/testing-library';
|
|
5
|
+
import { CASCADE_POLICY_TYPE_AI_EXTRACT, TEMPLATE_CUSTOM_PROPERTIES } from '../constants';
|
|
4
6
|
import { InstanceBase as Instance } from '../Instance';
|
|
5
7
|
import { isValidValue } from '../../metadata-instance-fields/validateMetadataField';
|
|
6
8
|
|
|
9
|
+
// Add RTL imports
|
|
10
|
+
|
|
7
11
|
jest.mock('../../metadata-instance-fields/validateMetadataField');
|
|
8
12
|
|
|
9
13
|
const data = {
|
|
@@ -718,3 +722,204 @@ describe('features/metadata-instance-editor/fields/Instance', () => {
|
|
|
718
722
|
});
|
|
719
723
|
});
|
|
720
724
|
});
|
|
725
|
+
|
|
726
|
+
// New RTL tests
|
|
727
|
+
const testFields = [
|
|
728
|
+
{
|
|
729
|
+
id: 'field1',
|
|
730
|
+
type: 'string',
|
|
731
|
+
key: 'stringfield',
|
|
732
|
+
displayName: 'String Field',
|
|
733
|
+
description: 'example of a string field',
|
|
734
|
+
},
|
|
735
|
+
{
|
|
736
|
+
id: 'field2',
|
|
737
|
+
type: 'float',
|
|
738
|
+
key: 'floatfield',
|
|
739
|
+
displayName: 'Float Field',
|
|
740
|
+
description: 'example of a float field',
|
|
741
|
+
},
|
|
742
|
+
];
|
|
743
|
+
|
|
744
|
+
const testData = {
|
|
745
|
+
stringfield: 'some string',
|
|
746
|
+
floatfield: 1.0,
|
|
747
|
+
};
|
|
748
|
+
|
|
749
|
+
const getBaseProps = (props = {}) => ({
|
|
750
|
+
id: 'test-instance',
|
|
751
|
+
canEdit: true,
|
|
752
|
+
data: { ...testData },
|
|
753
|
+
template: {
|
|
754
|
+
id: 'template-1',
|
|
755
|
+
displayName: 'Test Template',
|
|
756
|
+
fields: [...testFields],
|
|
757
|
+
templateKey: 'testTemplateKey',
|
|
758
|
+
},
|
|
759
|
+
intl: createIntl({ locale: 'en' }),
|
|
760
|
+
onSave: jest.fn(),
|
|
761
|
+
onModification: jest.fn(),
|
|
762
|
+
onRemove: jest.fn(),
|
|
763
|
+
isDirty: false,
|
|
764
|
+
hasError: false,
|
|
765
|
+
isCascadingPolicyApplicable: true,
|
|
766
|
+
cascadePolicy: {
|
|
767
|
+
id: 'policy-1',
|
|
768
|
+
canEdit: true,
|
|
769
|
+
isEnabled: true,
|
|
770
|
+
scope: 'enterprise_123',
|
|
771
|
+
cascadePolicyType: 'regular', // default to non-AI
|
|
772
|
+
},
|
|
773
|
+
canUseAIFolderExtraction: true, // Assume feature flag is on
|
|
774
|
+
canUseAIFolderExtractionAgentSelector: false,
|
|
775
|
+
...props,
|
|
776
|
+
});
|
|
777
|
+
|
|
778
|
+
describe('Instance Component - React Testing Library', () => {
|
|
779
|
+
beforeEach(() => {
|
|
780
|
+
jest.clearAllMocks();
|
|
781
|
+
isValidValue.mockReturnValue(true); // Default mock for isValidValue
|
|
782
|
+
});
|
|
783
|
+
|
|
784
|
+
describe('Initialization based on cascadePolicy.cascadePolicyType', () => {
|
|
785
|
+
test('should initialize with AI folder extraction enabled and fields disabled if cascadePolicyType is "ai_extract"', async () => {
|
|
786
|
+
render(
|
|
787
|
+
<Instance
|
|
788
|
+
{...getBaseProps({
|
|
789
|
+
cascadePolicy: {
|
|
790
|
+
id: 'policy-ai',
|
|
791
|
+
canEdit: true,
|
|
792
|
+
isEnabled: true,
|
|
793
|
+
scope: 'enterprise_123',
|
|
794
|
+
cascadePolicyType: CASCADE_POLICY_TYPE_AI_EXTRACT,
|
|
795
|
+
},
|
|
796
|
+
})}
|
|
797
|
+
/>,
|
|
798
|
+
);
|
|
799
|
+
|
|
800
|
+
// Click Edit button to enable editing
|
|
801
|
+
const editButton = screen.getByRole('button', { name: 'Edit Metadata' }); // Assuming 'Edit Metadata' is the rendered name
|
|
802
|
+
await userEvent.click(editButton);
|
|
803
|
+
|
|
804
|
+
// Fields should be disabled because AI extraction is on by default from policy
|
|
805
|
+
// Input fields are part of TemplatedInstance, which is only rendered if Collapsible is open.
|
|
806
|
+
// Default state has isOpen true if not specified or based on single field length.
|
|
807
|
+
// Let's assume it's open.
|
|
808
|
+
expect(screen.getByRole('textbox', { name: 'String Field example of a string field' })).toBeDisabled();
|
|
809
|
+
expect(screen.getByRole('textbox', { name: 'Float Field example of a float field' })).toBeDisabled();
|
|
810
|
+
});
|
|
811
|
+
|
|
812
|
+
test('should initialize with AI folder extraction disabled and fields enabled if cascadePolicyType is not "ai_extract"', async () => {
|
|
813
|
+
render(<Instance {...getBaseProps()} />); // default policy is not 'ai_extract'
|
|
814
|
+
|
|
815
|
+
// Click Edit button to enable editing
|
|
816
|
+
const editButton = screen.getByRole('button', { name: 'Edit Metadata' }); // Assuming 'Edit Metadata' is the rendered name
|
|
817
|
+
await userEvent.click(editButton);
|
|
818
|
+
|
|
819
|
+
expect(screen.getByRole('textbox', { name: 'String Field example of a string field' })).not.toBeDisabled();
|
|
820
|
+
expect(screen.getByRole('textbox', { name: 'Float Field example of a float field' })).not.toBeDisabled();
|
|
821
|
+
});
|
|
822
|
+
|
|
823
|
+
test('should initialize with AI folder extraction disabled if cascadePolicy is undefined', async () => {
|
|
824
|
+
render(<Instance {...getBaseProps({ cascadePolicy: undefined, isCascadingPolicyApplicable: false })} />);
|
|
825
|
+
|
|
826
|
+
// Click Edit button to enable editing
|
|
827
|
+
const editButton = screen.getByRole('button', { name: 'Edit Metadata' }); // Assuming 'Edit Metadata' is the rendered name
|
|
828
|
+
await userEvent.click(editButton);
|
|
829
|
+
|
|
830
|
+
expect(screen.getByRole('textbox', { name: 'String Field example of a string field' })).not.toBeDisabled();
|
|
831
|
+
expect(screen.getByRole('textbox', { name: 'Float Field example of a float field' })).not.toBeDisabled();
|
|
832
|
+
});
|
|
833
|
+
});
|
|
834
|
+
|
|
835
|
+
describe('AI Folder Extraction Toggle Interaction', () => {
|
|
836
|
+
test('should toggle AI folder extraction, disable/enable fields', async () => {
|
|
837
|
+
render(<Instance {...getBaseProps()} />);
|
|
838
|
+
|
|
839
|
+
// Click Edit button to enable editing
|
|
840
|
+
const editButton = screen.getByRole('button', { name: 'Edit Metadata' }); // Assuming 'Edit Metadata' is the rendered name
|
|
841
|
+
await userEvent.click(editButton);
|
|
842
|
+
|
|
843
|
+
// Initially, fields are enabled as default policy is not 'ai_extract'
|
|
844
|
+
expect(screen.getByRole('textbox', { name: 'String Field example of a string field' })).not.toBeDisabled();
|
|
845
|
+
|
|
846
|
+
const aiSection = screen.getByTestId('ai-folder-extraction');
|
|
847
|
+
const aiToggle = within(aiSection).getByRole('switch');
|
|
848
|
+
|
|
849
|
+
// Turn AI toggle ON
|
|
850
|
+
await userEvent.click(aiToggle);
|
|
851
|
+
expect(screen.getByRole('textbox', { name: 'String Field example of a string field' })).toBeDisabled();
|
|
852
|
+
|
|
853
|
+
// Turn AI toggle OFF
|
|
854
|
+
await userEvent.click(aiToggle);
|
|
855
|
+
expect(screen.getByRole('textbox', { name: 'String Field example of a string field' })).not.toBeDisabled();
|
|
856
|
+
});
|
|
857
|
+
});
|
|
858
|
+
|
|
859
|
+
describe('Props passed to CascadePolicy', () => {
|
|
860
|
+
test('should pass canUseAIFolderExtractionAgentSelector to CascadePolicy', async () => {
|
|
861
|
+
render(<Instance {...getBaseProps({ canUseAIFolderExtractionAgentSelector: true })} />);
|
|
862
|
+
|
|
863
|
+
const editButton = screen.queryByRole('button', { name: 'Edit Metadata' });
|
|
864
|
+
if (editButton) await userEvent.click(editButton); // Enter edit mode to ensure CascadePolicy options are visible
|
|
865
|
+
|
|
866
|
+
expect(screen.getByRole('button', { name: 'Agent Basic' })).toBeInTheDocument();
|
|
867
|
+
});
|
|
868
|
+
|
|
869
|
+
test('should pass isExistingAIExtractionCascadePolicy=true to CascadePolicy if policy is ai_extract', async () => {
|
|
870
|
+
render(
|
|
871
|
+
<Instance
|
|
872
|
+
{...getBaseProps({
|
|
873
|
+
cascadePolicy: {
|
|
874
|
+
id: 'policy-ai',
|
|
875
|
+
canEdit: true,
|
|
876
|
+
isEnabled: true,
|
|
877
|
+
scope: 'enterprise_123',
|
|
878
|
+
cascadePolicyType: CASCADE_POLICY_TYPE_AI_EXTRACT,
|
|
879
|
+
},
|
|
880
|
+
})}
|
|
881
|
+
/>,
|
|
882
|
+
);
|
|
883
|
+
const editButton = screen.queryByRole('button', { name: 'Edit Metadata' });
|
|
884
|
+
if (editButton) await userEvent.click(editButton);
|
|
885
|
+
|
|
886
|
+
const aiSection = screen.getByTestId('ai-folder-extraction');
|
|
887
|
+
const aiToggle = within(aiSection).getByRole('switch');
|
|
888
|
+
expect(aiToggle).toBeDisabled();
|
|
889
|
+
});
|
|
890
|
+
|
|
891
|
+
test('should pass isExistingAIExtractionCascadePolicy=false to CascadePolicy if policy is not ai_extract', async () => {
|
|
892
|
+
render(<Instance {...getBaseProps()} />);
|
|
893
|
+
const editButton = screen.queryByRole('button', { name: 'Edit Metadata' });
|
|
894
|
+
if (editButton) await userEvent.click(editButton);
|
|
895
|
+
|
|
896
|
+
const aiSection = screen.getByTestId('ai-folder-extraction');
|
|
897
|
+
const aiToggle = within(aiSection).getByRole('switch');
|
|
898
|
+
expect(aiToggle).not.toBeDisabled();
|
|
899
|
+
});
|
|
900
|
+
});
|
|
901
|
+
|
|
902
|
+
describe('Props passed to TemplatedInstance', () => {
|
|
903
|
+
test('should pass isDisabled=true to TemplatedInstance when AI folder extraction is enabled', async () => {
|
|
904
|
+
render(<Instance {...getBaseProps()} />);
|
|
905
|
+
const editButton = screen.getByRole('button', { name: 'Edit Metadata' });
|
|
906
|
+
await userEvent.click(editButton);
|
|
907
|
+
|
|
908
|
+
const aiSection = screen.getByTestId('ai-folder-extraction');
|
|
909
|
+
const aiToggle = within(aiSection).getByRole('switch');
|
|
910
|
+
|
|
911
|
+
await userEvent.click(aiToggle); // Turn AI ON
|
|
912
|
+
expect(screen.getByRole('textbox', { name: 'String Field example of a string field' })).toBeDisabled();
|
|
913
|
+
});
|
|
914
|
+
|
|
915
|
+
test('should pass isDisabled=false to TemplatedInstance when AI folder extraction is disabled', async () => {
|
|
916
|
+
render(<Instance {...getBaseProps()} />);
|
|
917
|
+
const editButton = screen.queryByRole('button', { name: 'Edit Metadata' });
|
|
918
|
+
// If instance starts in non-edit mode, fields might not be interactive until edit is clicked
|
|
919
|
+
if (editButton) await userEvent.click(editButton);
|
|
920
|
+
|
|
921
|
+
// AI is off by default
|
|
922
|
+
expect(screen.getByRole('textbox', { name: 'String Field example of a string field' })).not.toBeDisabled();
|
|
923
|
+
});
|
|
924
|
+
});
|
|
925
|
+
});
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
+
import userEvent from '@testing-library/user-event';
|
|
3
|
+
import { render, screen } from '../../../test-utils/testing-library';
|
|
2
4
|
|
|
3
5
|
import Instances from '../Instances';
|
|
4
6
|
|
|
@@ -182,6 +184,50 @@ const editor2 = {
|
|
|
182
184
|
// State of editors from server
|
|
183
185
|
const editorsOnServer = [editor1, editor2];
|
|
184
186
|
|
|
187
|
+
const testInstanceFields = [
|
|
188
|
+
{
|
|
189
|
+
id: 'field1',
|
|
190
|
+
type: 'string',
|
|
191
|
+
key: 'stringfield',
|
|
192
|
+
displayName: 'String Field',
|
|
193
|
+
description: 'example of a string field',
|
|
194
|
+
},
|
|
195
|
+
];
|
|
196
|
+
|
|
197
|
+
const getInstancesBaseProps = (props = {}) => ({
|
|
198
|
+
editors: [
|
|
199
|
+
{
|
|
200
|
+
instance: {
|
|
201
|
+
id: 'test-instance-1',
|
|
202
|
+
canEdit: true,
|
|
203
|
+
data: { stringfield: 'value1' },
|
|
204
|
+
isDirty: false,
|
|
205
|
+
hasError: false,
|
|
206
|
+
isCascadingPolicyApplicable: true,
|
|
207
|
+
cascadePolicy: {
|
|
208
|
+
id: 'policy-1',
|
|
209
|
+
canEdit: true,
|
|
210
|
+
isEnabled: true,
|
|
211
|
+
scope: 'enterprise_123',
|
|
212
|
+
cascadePolicyType: 'regular',
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
template: {
|
|
216
|
+
id: 'template-1',
|
|
217
|
+
displayName: 'Test Template Editor',
|
|
218
|
+
fields: testInstanceFields,
|
|
219
|
+
templateKey: 'editorTemplateKey',
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
],
|
|
223
|
+
onSave: jest.fn(),
|
|
224
|
+
onModification: jest.fn(),
|
|
225
|
+
onRemove: jest.fn(),
|
|
226
|
+
canUseAIFolderExtraction: true,
|
|
227
|
+
isCascadingPolicyApplicable: true,
|
|
228
|
+
...props,
|
|
229
|
+
});
|
|
230
|
+
|
|
185
231
|
describe('features/metadata-editor-editor/Instances', () => {
|
|
186
232
|
test('should correctly render editors', () => {
|
|
187
233
|
const wrapper = shallow(<Instances editors={editorsOnServer} />);
|
|
@@ -190,18 +236,61 @@ describe('features/metadata-editor-editor/Instances', () => {
|
|
|
190
236
|
|
|
191
237
|
test('should correctly render instances with editors and a selected template', () => {
|
|
192
238
|
const wrapper = shallow(<Instances editors={editorsOnServer} selectedTemplateKey="template1" />);
|
|
193
|
-
const selectedTemplate = wrapper.find('Instance').at(0);
|
|
239
|
+
const selectedTemplate = wrapper.find('injectIntl(Instance)').at(0);
|
|
194
240
|
expect(selectedTemplate.prop('isOpen')).toBe(true);
|
|
195
241
|
expect(selectedTemplate.prop('id')).toBe('editor1');
|
|
196
242
|
});
|
|
197
243
|
|
|
198
244
|
test('should correctly render instances with a selected template and multiple editors', () => {
|
|
199
245
|
const wrapper = shallow(<Instances editors={editorsOnServer} selectedTemplateKey="template2" />);
|
|
200
|
-
const selectedTemplate = wrapper.find('Instance').at(1);
|
|
246
|
+
const selectedTemplate = wrapper.find('injectIntl(Instance)').at(1);
|
|
201
247
|
expect(selectedTemplate.prop('isOpen')).toBe(true);
|
|
202
248
|
expect(selectedTemplate.prop('id')).toBe('editor2');
|
|
203
|
-
const unselectedTemplate = wrapper.find('Instance').at(0);
|
|
249
|
+
const unselectedTemplate = wrapper.find('injectIntl(Instance)').at(0);
|
|
204
250
|
expect(unselectedTemplate.prop('isOpen')).toBe(false);
|
|
205
251
|
expect(unselectedTemplate.prop('id')).toBe('editor1');
|
|
206
252
|
});
|
|
207
253
|
});
|
|
254
|
+
|
|
255
|
+
describe('Instances component - canUseAIFolderExtractionAgentSelector prop', () => {
|
|
256
|
+
test('should pass canUseAIFolderExtractionAgentSelector to child Instance components, showing agent selector', async () => {
|
|
257
|
+
render(
|
|
258
|
+
<Instances
|
|
259
|
+
{...getInstancesBaseProps({
|
|
260
|
+
canUseAIFolderExtractionAgentSelector: true,
|
|
261
|
+
})}
|
|
262
|
+
/>,
|
|
263
|
+
);
|
|
264
|
+
|
|
265
|
+
const editButton = screen.getByRole('button', { name: 'Edit Metadata' });
|
|
266
|
+
await userEvent.click(editButton);
|
|
267
|
+
|
|
268
|
+
expect(screen.getByRole('button', { name: 'Agent Basic' })).toBeInTheDocument();
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
test('should not show agent selector in child Instance if canUseAIFolderExtractionAgentSelector is false', async () => {
|
|
272
|
+
render(
|
|
273
|
+
<Instances
|
|
274
|
+
{...getInstancesBaseProps({
|
|
275
|
+
canUseAIFolderExtractionAgentSelector: false,
|
|
276
|
+
})}
|
|
277
|
+
/>,
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
const editButton = screen.getByRole('button', { name: 'Edit Metadata' });
|
|
281
|
+
await userEvent.click(editButton);
|
|
282
|
+
|
|
283
|
+
expect(screen.queryByRole('button', { name: 'Agent Basic' })).not.toBeInTheDocument();
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
test('should not show agent selector in child Instance if canUseAIFolderExtractionAgentSelector is undefined', async () => {
|
|
287
|
+
const props = getInstancesBaseProps();
|
|
288
|
+
delete props.canUseAIFolderExtractionAgentSelector;
|
|
289
|
+
render(<Instances {...props} />);
|
|
290
|
+
|
|
291
|
+
const editButton = screen.getByRole('button', { name: 'Edit Metadata' });
|
|
292
|
+
await userEvent.click(editButton);
|
|
293
|
+
|
|
294
|
+
expect(screen.queryByRole('button', { name: 'Agent Basic' })).not.toBeInTheDocument();
|
|
295
|
+
});
|
|
296
|
+
});
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
+
import userEvent from '@testing-library/user-event';
|
|
3
|
+
import { render, screen } from '../../../test-utils/testing-library';
|
|
2
4
|
|
|
3
5
|
import MetadataInstanceEditor from '../MetadataInstanceEditor';
|
|
4
6
|
import Instances from '../Instances';
|
|
@@ -443,6 +445,66 @@ const templatesOnServer = [template1, template2, template3, template4, template5
|
|
|
443
445
|
// State of editors from server
|
|
444
446
|
const editorsOnServer = [editor1, editor2, editor3, editor4, editor5];
|
|
445
447
|
|
|
448
|
+
const testGrandchildInstanceFields = [
|
|
449
|
+
{
|
|
450
|
+
id: 'field1',
|
|
451
|
+
type: 'string',
|
|
452
|
+
key: 'stringfield',
|
|
453
|
+
displayName: 'String Field',
|
|
454
|
+
description: 'example of a string field',
|
|
455
|
+
},
|
|
456
|
+
];
|
|
457
|
+
|
|
458
|
+
const getMetadataEditorBaseProps = (props = {}) => ({
|
|
459
|
+
editors: [
|
|
460
|
+
{
|
|
461
|
+
instance: {
|
|
462
|
+
id: 'test-instance-editor-child-1',
|
|
463
|
+
canEdit: true,
|
|
464
|
+
data: { stringfield: 'valueForEditor' },
|
|
465
|
+
isDirty: false,
|
|
466
|
+
hasError: false,
|
|
467
|
+
isCascadingPolicyApplicable: true,
|
|
468
|
+
cascadePolicy: {
|
|
469
|
+
id: 'policy-for-editor-1',
|
|
470
|
+
canEdit: true,
|
|
471
|
+
isEnabled: true,
|
|
472
|
+
scope: 'enterprise_123',
|
|
473
|
+
cascadePolicyType: 'regular',
|
|
474
|
+
},
|
|
475
|
+
},
|
|
476
|
+
template: {
|
|
477
|
+
id: 'template-for-editor-1',
|
|
478
|
+
displayName: 'Test Template In Editor',
|
|
479
|
+
fields: testGrandchildInstanceFields,
|
|
480
|
+
templateKey: 'editorChildTemplateKey',
|
|
481
|
+
},
|
|
482
|
+
},
|
|
483
|
+
],
|
|
484
|
+
templates: [
|
|
485
|
+
{
|
|
486
|
+
id: 'template-for-editor-1',
|
|
487
|
+
templateKey: 'editorChildTemplateKey',
|
|
488
|
+
displayName: 'Test Template In Editor',
|
|
489
|
+
fields: testGrandchildInstanceFields,
|
|
490
|
+
},
|
|
491
|
+
{
|
|
492
|
+
id: 'template-for-editor-2',
|
|
493
|
+
templateKey: 'anotherEditorTemplateKey',
|
|
494
|
+
displayName: 'Another Test Template',
|
|
495
|
+
fields: [],
|
|
496
|
+
},
|
|
497
|
+
],
|
|
498
|
+
onSave: jest.fn(),
|
|
499
|
+
onModification: jest.fn(),
|
|
500
|
+
onRemove: jest.fn(),
|
|
501
|
+
onAdd: jest.fn(),
|
|
502
|
+
canAdd: true,
|
|
503
|
+
canUseAIFolderExtraction: true,
|
|
504
|
+
isCascadingPolicyApplicable: true,
|
|
505
|
+
...props,
|
|
506
|
+
});
|
|
507
|
+
|
|
446
508
|
describe('features/metadata-editor-editor/MetadataInstanceEditor', () => {
|
|
447
509
|
test('should correctly render editors', () => {
|
|
448
510
|
const wrapper = shallow(<MetadataInstanceEditor editors={editorsOnServer} templates={templatesOnServer} />);
|
|
@@ -471,3 +533,46 @@ describe('features/metadata-editor-editor/MetadataInstanceEditor', () => {
|
|
|
471
533
|
expect(instances.prop('selectedTemplateKey')).toBe(selectedTemplateKey);
|
|
472
534
|
});
|
|
473
535
|
});
|
|
536
|
+
|
|
537
|
+
describe('MetadataInstanceEditor - canUseAIFolderExtractionAgentSelector prop', () => {
|
|
538
|
+
test('should propagate canUseAIFolderExtractionAgentSelector, showing agent selector', async () => {
|
|
539
|
+
render(
|
|
540
|
+
<MetadataInstanceEditor
|
|
541
|
+
{...getMetadataEditorBaseProps({
|
|
542
|
+
canUseAIFolderExtractionAgentSelector: true,
|
|
543
|
+
})}
|
|
544
|
+
/>,
|
|
545
|
+
);
|
|
546
|
+
|
|
547
|
+
const editButton = await screen.findByRole('button', { name: 'Edit Metadata' }, { timeout: 3000 });
|
|
548
|
+
await userEvent.click(editButton);
|
|
549
|
+
|
|
550
|
+
expect(screen.getByRole('button', { name: 'Agent Basic' })).toBeInTheDocument();
|
|
551
|
+
});
|
|
552
|
+
|
|
553
|
+
test('should not show agent selector if canUseAIFolderExtractionAgentSelector is false', async () => {
|
|
554
|
+
render(
|
|
555
|
+
<MetadataInstanceEditor
|
|
556
|
+
{...getMetadataEditorBaseProps({
|
|
557
|
+
canUseAIFolderExtractionAgentSelector: false,
|
|
558
|
+
})}
|
|
559
|
+
/>,
|
|
560
|
+
);
|
|
561
|
+
|
|
562
|
+
const editButton = await screen.findByRole('button', { name: 'Edit Metadata' });
|
|
563
|
+
await userEvent.click(editButton);
|
|
564
|
+
|
|
565
|
+
expect(screen.queryByRole('button', { name: 'Agent Basic' })).not.toBeInTheDocument();
|
|
566
|
+
});
|
|
567
|
+
|
|
568
|
+
test('should not show agent selector if canUseAIFolderExtractionAgentSelector is undefined', async () => {
|
|
569
|
+
const props = getMetadataEditorBaseProps();
|
|
570
|
+
delete props.canUseAIFolderExtractionAgentSelector;
|
|
571
|
+
render(<MetadataInstanceEditor {...props} />);
|
|
572
|
+
|
|
573
|
+
const editButton = await screen.findByRole('button', { name: 'Edit Metadata' });
|
|
574
|
+
await userEvent.click(editButton);
|
|
575
|
+
|
|
576
|
+
expect(screen.queryByRole('button', { name: 'Agent Basic' })).not.toBeInTheDocument();
|
|
577
|
+
});
|
|
578
|
+
});
|