Skip to content

Commit fd164ec

Browse files
fix(metadata-sidebar): Fix metadata sidebar ai capabilities (#3681)
* fix(metadata-sidebar): Check if AI Suggestion are enabled feature * fix(metadata-sidebar): Fix storybook test * fix(metadata-sidebar): Spread mockFeatures instead of duplication Co-authored-by: greg-in-a-box <103291617+greg-in-a-box@users.noreply.github.com> * feat(metadata-sidebar): Select only one button as only one is used * feat(metadata-sidebar): Add FeatureProvider to test-utils --------- Co-authored-by: greg-in-a-box <103291617+greg-in-a-box@users.noreply.github.com>
1 parent 305d3af commit fd164ec

File tree

4 files changed

+54
-24
lines changed

4 files changed

+54
-24
lines changed

src/elements/content-sidebar/MetadataSidebarRedesign.tsx

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { withErrorBoundary } from '../common/error-boundary';
2424
import { withLogger } from '../common/logger';
2525
import { ORIGIN_METADATA_SIDEBAR_REDESIGN, SIDEBAR_VIEW_METADATA } from '../../constants';
2626
import { EVENT_JS_READY } from '../common/logger/constants';
27+
import { useFeatureEnabled } from '../common/feature-checking';
2728
import { mark } from '../../utils/performance';
2829
import useSidebarMetadataFetcher, { STATUS } from './hooks/useSidebarMetadataFetcher';
2930

@@ -41,7 +42,6 @@ const MARK_NAME_JS_READY = `${ORIGIN_METADATA_SIDEBAR_REDESIGN}_${EVENT_JS_READY
4142
mark(MARK_NAME_JS_READY);
4243

4344
export interface ExternalProps {
44-
isBoxAiSuggestionsEnabled: boolean;
4545
isFeatureEnabled: boolean;
4646
}
4747

@@ -64,14 +64,7 @@ export interface MetadataSidebarRedesignProps extends PropsWithoutContext, Error
6464
api: API;
6565
}
6666

67-
function MetadataSidebarRedesign({
68-
api,
69-
elementId,
70-
fileId,
71-
isBoxAiSuggestionsEnabled,
72-
onError,
73-
isFeatureEnabled,
74-
}: MetadataSidebarRedesignProps) {
67+
function MetadataSidebarRedesign({ api, elementId, fileId, onError, isFeatureEnabled }: MetadataSidebarRedesignProps) {
7568
const {
7669
file,
7770
handleCreateMetadataInstance,
@@ -84,6 +77,7 @@ function MetadataSidebarRedesign({
8477
} = useSidebarMetadataFetcher(api, fileId, onError, isFeatureEnabled);
8578

8679
const { formatMessage } = useIntl();
80+
const isBoxAiSuggestionsEnabled: boolean = useFeatureEnabled('metadata.aiSuggestions.enabled');
8781

8882
const [editingTemplate, setEditingTemplate] = React.useState<MetadataTemplateInstance | null>(null);
8983
const [isUnsavedChangesModalOpen, setIsUnsavedChangesModalOpen] = React.useState<boolean>(false);

src/elements/content-sidebar/__tests__/MetadataSidebarRedesign.test.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,17 +54,16 @@ describe('elements/content-sidebar/Metadata/MetadataSidebarRedesign', () => {
5454
permissions: { [FIELD_PERMISSIONS_CAN_UPLOAD]: true },
5555
};
5656

57-
const renderComponent = (props = {}) => {
57+
const renderComponent = (props = {}, features = {}) => {
5858
const defaultProps = {
5959
api: {},
6060
fileId: 'test-file-id-1',
6161
elementId: 'element-1',
62-
isBoxAiSuggestionsEnabled: true,
6362
isFeatureEnabled: true,
6463
onError: jest.fn(),
6564
} satisfies MetadataSidebarRedesignProps;
6665

67-
render(<MetadataSidebarRedesign {...defaultProps} {...props} />);
66+
render(<MetadataSidebarRedesign {...defaultProps} {...props} />, { wrapperProps: { features } });
6867
};
6968

7069
beforeEach(() => {
@@ -154,7 +153,7 @@ describe('elements/content-sidebar/Metadata/MetadataSidebarRedesign', () => {
154153
});
155154

156155
test('should correctly render empty state when AI feature is enabled', () => {
157-
renderComponent();
156+
renderComponent({}, { 'metadata.aiSuggestions.enabled': true });
158157
expect(screen.getByRole('heading', { level: 2, name: 'Autofill Metadata with Box AI' })).toBeInTheDocument();
159158
expect(
160159
screen.getByText(

src/elements/content-sidebar/stories/tests/MetadataSidebarRedesign-visual.stories.tsx

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ const defaultMetadataArgs = {
1515
onError: fn,
1616
};
1717
const defaultMetadataSidebarProps: ComponentProps<typeof MetadataSidebarRedesign> = {
18-
isBoxAiSuggestionsEnabled: true,
1918
isFeatureEnabled: true,
2019
onError: fn,
2120
};
@@ -139,6 +138,10 @@ export const EmptyStateWithBoxAiEnabled: StoryObj<typeof MetadataSidebarRedesign
139138
metadataSidebarProps: {
140139
...defaultMetadataSidebarProps,
141140
},
141+
features: {
142+
...mockFeatures,
143+
'metadata.aiSuggestions.enabled': true,
144+
},
142145
},
143146
};
144147

@@ -188,7 +191,9 @@ export const MetadataInstanceEditorCancelChanges: StoryObj<typeof MetadataSideba
188191
play: async ({ canvasElement }) => {
189192
const canvas = within(canvasElement);
190193

191-
const editButtons = await canvas.findAllByRole('button', { name: 'Edit' }, { timeout: 5000 });
194+
// Edit buttons contains also template name
195+
const editButton = await canvas.findByRole('button', { name: 'Edit My Template' }, { timeout: 5000 });
196+
expect(editButton).toBeInTheDocument();
192197

193198
let headlines = await canvas.findAllByRole('heading', { level: 1 });
194199
expect(headlines).toHaveLength(3);
@@ -197,7 +202,7 @@ export const MetadataInstanceEditorCancelChanges: StoryObj<typeof MetadataSideba
197202
);
198203

199204
// go to edit mode - only edited template is visible
200-
await userEvent.click(editButtons[0]);
205+
await userEvent.click(editButton);
201206

202207
headlines = await canvas.findAllByRole('heading', { level: 1 });
203208
expect(headlines).toHaveLength(1);
@@ -286,7 +291,6 @@ export const SwitchEditingTemplateInstances: StoryObj<typeof MetadataSidebarRede
286291
},
287292
play: async ({ canvasElement }) => {
288293
const canvas = within(canvasElement);
289-
290294
// open and edit a new template
291295
const addTemplateButton = await canvas.findByRole('button', { name: 'Add template' }, { timeout: 5000 });
292296

@@ -335,3 +339,28 @@ export const SwitchEditingTemplateInstances: StoryObj<typeof MetadataSidebarRede
335339
expect(templateMetadataOptionBAfterSwitch).toHaveAttribute('aria-disabled');
336340
},
337341
};
342+
343+
export const MetadataInstanceEditorAIEnabled: StoryObj<typeof MetadataSidebarRedesign> = {
344+
args: {
345+
features: {
346+
...mockFeatures,
347+
'metadata.aiSuggestions.enabled': true,
348+
},
349+
},
350+
play: async ({ canvasElement }) => {
351+
const canvas = within(canvasElement);
352+
353+
const autofillWithBoxAI = await canvas.findAllByRole(
354+
'button',
355+
{ name: /Autofill .+ with Box AI/ },
356+
{ timeout: 5000 },
357+
);
358+
expect(autofillWithBoxAI).toHaveLength(2);
359+
360+
const editButton = await canvas.findByRole('button', { name: 'Edit My Template' });
361+
userEvent.click(editButton);
362+
363+
const autofillButton = await canvas.findByRole('button', { name: 'Autofill' });
364+
expect(autofillButton).toBeInTheDocument();
365+
},
366+
};

src/test-utils/testing-library.tsx

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,30 @@
11
import React from 'react';
2-
import { render } from '@testing-library/react';
2+
import { render, type RenderOptions } from '@testing-library/react';
33

44
// Data Providers
55
import { TooltipProvider } from '@box/blueprint-web';
66
import { IntlProvider } from 'react-intl';
77
import { AutofillContextProvider } from '@box/metadata-editor';
8+
import { FeatureProvider } from '../elements/common/feature-checking';
89

910
jest.unmock('react-intl');
1011

11-
const Wrapper = ({ children }) => (
12-
<AutofillContextProvider isAiSuggestionsFeatureEnabled={false} fetchSuggestions={() => Promise.resolve([])}>
13-
<TooltipProvider>
14-
<IntlProvider locale="en">{children}</IntlProvider>
15-
</TooltipProvider>
12+
const Wrapper = ({ children, features = {}, isAiSuggestionsFeatureEnabled = false, fetchSuggestions = () => Promise.resolve([]) }) => (
13+
<AutofillContextProvider isAiSuggestionsFeatureEnabled={isAiSuggestionsFeatureEnabled} fetchSuggestions={fetchSuggestions}>
14+
<FeatureProvider features={features}>
15+
<TooltipProvider>
16+
<IntlProvider locale="en">{children}</IntlProvider>
17+
</TooltipProvider>
18+
</FeatureProvider>
1619
</AutofillContextProvider>
1720
);
1821

19-
const renderConnected = (element, options = {}) => render(element, { wrapper: Wrapper, ...options });
22+
type RenderConnectedOptions = Omit<RenderOptions, 'wrapper'> & {
23+
wrapperProps?: Record<string, unknown>;
24+
};
25+
26+
const renderConnected = (element, options: RenderConnectedOptions = {}) =>
27+
render(element, { wrapper: props => <Wrapper {...props} {...options.wrapperProps} />, ...options });
2028

2129
export * from '@testing-library/react';
2230
export { renderConnected as render };

0 commit comments

Comments
 (0)