diff --git a/src/elements/content-sidebar/MetadataSidebarRedesign.tsx b/src/elements/content-sidebar/MetadataSidebarRedesign.tsx index 9addb817bd..445a9beabd 100644 --- a/src/elements/content-sidebar/MetadataSidebarRedesign.tsx +++ b/src/elements/content-sidebar/MetadataSidebarRedesign.tsx @@ -24,6 +24,7 @@ import { withErrorBoundary } from '../common/error-boundary'; import { withLogger } from '../common/logger'; import { ORIGIN_METADATA_SIDEBAR_REDESIGN, SIDEBAR_VIEW_METADATA } from '../../constants'; import { EVENT_JS_READY } from '../common/logger/constants'; +import { useFeatureEnabled } from '../common/feature-checking'; import { mark } from '../../utils/performance'; import useSidebarMetadataFetcher, { STATUS } from './hooks/useSidebarMetadataFetcher'; @@ -41,7 +42,6 @@ const MARK_NAME_JS_READY = `${ORIGIN_METADATA_SIDEBAR_REDESIGN}_${EVENT_JS_READY mark(MARK_NAME_JS_READY); export interface ExternalProps { - isBoxAiSuggestionsEnabled: boolean; isFeatureEnabled: boolean; } @@ -64,14 +64,7 @@ export interface MetadataSidebarRedesignProps extends PropsWithoutContext, Error api: API; } -function MetadataSidebarRedesign({ - api, - elementId, - fileId, - isBoxAiSuggestionsEnabled, - onError, - isFeatureEnabled, -}: MetadataSidebarRedesignProps) { +function MetadataSidebarRedesign({ api, elementId, fileId, onError, isFeatureEnabled }: MetadataSidebarRedesignProps) { const { file, handleCreateMetadataInstance, @@ -84,6 +77,7 @@ function MetadataSidebarRedesign({ } = useSidebarMetadataFetcher(api, fileId, onError, isFeatureEnabled); const { formatMessage } = useIntl(); + const isBoxAiSuggestionsEnabled: boolean = useFeatureEnabled('metadata.aiSuggestions.enabled'); const [editingTemplate, setEditingTemplate] = React.useState(null); const [isUnsavedChangesModalOpen, setIsUnsavedChangesModalOpen] = React.useState(false); diff --git a/src/elements/content-sidebar/__tests__/MetadataSidebarRedesign.test.tsx b/src/elements/content-sidebar/__tests__/MetadataSidebarRedesign.test.tsx index 362066f9f5..45e97b1aae 100644 --- a/src/elements/content-sidebar/__tests__/MetadataSidebarRedesign.test.tsx +++ b/src/elements/content-sidebar/__tests__/MetadataSidebarRedesign.test.tsx @@ -54,17 +54,16 @@ describe('elements/content-sidebar/Metadata/MetadataSidebarRedesign', () => { permissions: { [FIELD_PERMISSIONS_CAN_UPLOAD]: true }, }; - const renderComponent = (props = {}) => { + const renderComponent = (props = {}, features = {}) => { const defaultProps = { api: {}, fileId: 'test-file-id-1', elementId: 'element-1', - isBoxAiSuggestionsEnabled: true, isFeatureEnabled: true, onError: jest.fn(), } satisfies MetadataSidebarRedesignProps; - render(); + render(, { wrapperProps: { features } }); }; beforeEach(() => { @@ -154,7 +153,7 @@ describe('elements/content-sidebar/Metadata/MetadataSidebarRedesign', () => { }); test('should correctly render empty state when AI feature is enabled', () => { - renderComponent(); + renderComponent({}, { 'metadata.aiSuggestions.enabled': true }); expect(screen.getByRole('heading', { level: 2, name: 'Autofill Metadata with Box AI' })).toBeInTheDocument(); expect( screen.getByText( diff --git a/src/elements/content-sidebar/stories/tests/MetadataSidebarRedesign-visual.stories.tsx b/src/elements/content-sidebar/stories/tests/MetadataSidebarRedesign-visual.stories.tsx index 09d555ff7e..7dc5de5eb5 100644 --- a/src/elements/content-sidebar/stories/tests/MetadataSidebarRedesign-visual.stories.tsx +++ b/src/elements/content-sidebar/stories/tests/MetadataSidebarRedesign-visual.stories.tsx @@ -15,7 +15,6 @@ const defaultMetadataArgs = { onError: fn, }; const defaultMetadataSidebarProps: ComponentProps = { - isBoxAiSuggestionsEnabled: true, isFeatureEnabled: true, onError: fn, }; @@ -139,6 +138,10 @@ export const EmptyStateWithBoxAiEnabled: StoryObj { const canvas = within(canvasElement); - const editButtons = await canvas.findAllByRole('button', { name: 'Edit' }, { timeout: 5000 }); + // Edit buttons contains also template name + const editButton = await canvas.findByRole('button', { name: 'Edit My Template' }, { timeout: 5000 }); + expect(editButton).toBeInTheDocument(); let headlines = await canvas.findAllByRole('heading', { level: 1 }); expect(headlines).toHaveLength(3); @@ -197,7 +202,7 @@ export const MetadataInstanceEditorCancelChanges: StoryObj { const canvas = within(canvasElement); - // open and edit a new template const addTemplateButton = await canvas.findByRole('button', { name: 'Add template' }, { timeout: 5000 }); @@ -335,3 +339,28 @@ export const SwitchEditingTemplateInstances: StoryObj = { + args: { + features: { + ...mockFeatures, + 'metadata.aiSuggestions.enabled': true, + }, + }, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + + const autofillWithBoxAI = await canvas.findAllByRole( + 'button', + { name: /Autofill .+ with Box AI/ }, + { timeout: 5000 }, + ); + expect(autofillWithBoxAI).toHaveLength(2); + + const editButton = await canvas.findByRole('button', { name: 'Edit My Template' }); + userEvent.click(editButton); + + const autofillButton = await canvas.findByRole('button', { name: 'Autofill' }); + expect(autofillButton).toBeInTheDocument(); + }, +}; diff --git a/src/test-utils/testing-library.tsx b/src/test-utils/testing-library.tsx index c8014de528..cdf8fc54ca 100644 --- a/src/test-utils/testing-library.tsx +++ b/src/test-utils/testing-library.tsx @@ -1,22 +1,30 @@ import React from 'react'; -import { render } from '@testing-library/react'; +import { render, type RenderOptions } from '@testing-library/react'; // Data Providers import { TooltipProvider } from '@box/blueprint-web'; import { IntlProvider } from 'react-intl'; import { AutofillContextProvider } from '@box/metadata-editor'; +import { FeatureProvider } from '../elements/common/feature-checking'; jest.unmock('react-intl'); -const Wrapper = ({ children }) => ( - Promise.resolve([])}> - - {children} - +const Wrapper = ({ children, features = {}, isAiSuggestionsFeatureEnabled = false, fetchSuggestions = () => Promise.resolve([]) }) => ( + + + + {children} + + ); -const renderConnected = (element, options = {}) => render(element, { wrapper: Wrapper, ...options }); +type RenderConnectedOptions = Omit & { + wrapperProps?: Record; +}; + +const renderConnected = (element, options: RenderConnectedOptions = {}) => + render(element, { wrapper: props => , ...options }); export * from '@testing-library/react'; export { renderConnected as render };