forked from box/box-ui-elements
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(metadata-sidebar): Add metadata add template dropdown menu (box#…
…3606) * feat(metadata-sidebar): Add AddMetadataTemplateDropdown and improve basic styling * feat(metadata-sidebar): Fix failing tests Extend Jest configuration to not transforming metadata-editor code * feat(metadata-sidebar): add AddMetadataTemplateDropdown To MetadataSidebarRedesign * feat(content-sidebar): Bring back changes to mockServiceWorker.js No idea why they got there in the first place * feat(metadata-sidebar): update storybook * feat(metadata-sidebar): PR comments * feat(metadata-sidebar): simplify storybook * feat(metadata-sidebar): enum status * feat(metadata-sidebar): global variables and enum upper case change * feat(metadata-sidebar): useSidebarMetadataFetcher tests * feat(metadata-sidebar): useSidebarMetadataFetcher tests * feat(metadata-sidebar): PR comments * feat(metadata-sidebar): PR comments * feat(metadata-sidebar): loading status test * feat(metadata-sidebar): use SidebarContent + tests * feat(metadata-sidebar): template dropdown menu nit fixes --------- Co-authored-by: Karolina Rusek-Bieniek <[email protected]> Co-authored-by: Wiola <[email protected]>
- Loading branch information
1 parent
a938524
commit 8b206c3
Showing
10 changed files
with
526 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,10 @@ | ||
@import '../common/variables'; | ||
@import '~@box/blueprint-web-assets/tokens/tokens.scss'; | ||
|
||
.bcs-MetadataSidebarRedesign { | ||
padding-inline: 10px; | ||
border-left: 1px solid $gray-10; | ||
|
||
.bcs-MetadataSidebarRedesign-content { | ||
padding: $space-2; | ||
background-color: $gray-02; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
116 changes: 116 additions & 0 deletions
116
src/elements/content-sidebar/__tests__/MetadataSidebarRedesign.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
import React from 'react'; | ||
import { userEvent } from '@testing-library/user-event'; | ||
import { FIELD_PERMISSIONS_CAN_UPLOAD } from '../../../constants'; | ||
import { screen, render } from '../../../test-utils/testing-library'; | ||
import { | ||
MetadataSidebarRedesignComponent as MetadataSidebarRedesign, | ||
type MetadataSidebarRedesignProps, | ||
} from '../MetadataSidebarRedesign'; | ||
import useSidebarMetadataFetcher, { STATUS } from '../hooks/useSidebarMetadataFetcher'; | ||
|
||
jest.mock('../hooks/useSidebarMetadataFetcher'); | ||
const mockUseSidebarMetadataFetcher = useSidebarMetadataFetcher as jest.MockedFunction< | ||
typeof useSidebarMetadataFetcher | ||
>; | ||
|
||
describe('elements/content-sidebar/Metadata/MetadataSidebarRedesign', () => { | ||
const mockTemplates = [ | ||
{ | ||
id: 'metadata_template_custom_1', | ||
scope: 'global', | ||
templateKey: 'properties', | ||
hidden: false, | ||
}, | ||
]; | ||
|
||
const mockFile = { | ||
id: '123', | ||
permissions: { [FIELD_PERMISSIONS_CAN_UPLOAD]: true }, | ||
}; | ||
|
||
const renderComponent = (props = {}) => { | ||
const defaultProps = { | ||
api: {}, | ||
fileId: 'test-file-id-1', | ||
elementId: 'element-1', | ||
isFeatureEnabled: true, | ||
onError: jest.fn(), | ||
} satisfies MetadataSidebarRedesignProps; | ||
|
||
render(<MetadataSidebarRedesign {...defaultProps} {...props} />); | ||
}; | ||
|
||
beforeEach(() => { | ||
mockUseSidebarMetadataFetcher.mockReturnValue({ | ||
templates: mockTemplates, | ||
errorMessage: null, | ||
status: STATUS.SUCCESS, | ||
file: mockFile, | ||
}); | ||
}); | ||
|
||
afterEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
test('should render title', () => { | ||
renderComponent(); | ||
|
||
expect(screen.getByRole('heading', { level: 3, name: 'Metadata' })).toBeInTheDocument(); | ||
}); | ||
|
||
test('should have accessible "Add template" button', () => { | ||
renderComponent(); | ||
|
||
expect(screen.getByRole('button', { name: 'Add template' })).toBeInTheDocument(); | ||
}); | ||
|
||
test('should have selectable "Custom Metadata" template in dropdown', async () => { | ||
renderComponent(); | ||
|
||
const addTemplateButton = screen.getByRole('button', { name: 'Add template' }); | ||
await userEvent.click(addTemplateButton); | ||
|
||
const customMetadataOption = screen.getByRole('option', { name: 'Custom Metadata' }); | ||
expect(customMetadataOption).toBeInTheDocument(); | ||
userEvent.click(customMetadataOption); | ||
|
||
// instead of below assertions check if template was added when MetadataInstanceList will be implemented | ||
await userEvent.click(addTemplateButton); | ||
|
||
expect(customMetadataOption).toHaveAttribute('aria-disabled', 'true'); | ||
}); | ||
|
||
test('should render metadata sidebar with error', async () => { | ||
mockUseSidebarMetadataFetcher.mockReturnValue({ | ||
templates: [], | ||
errorMessage: { | ||
id: 'error', | ||
defaultMessage: 'error message', | ||
}, | ||
status: STATUS.ERROR, | ||
file: mockFile, | ||
}); | ||
|
||
const errorMessage = { id: 'error', defaultMessage: 'error message' }; | ||
renderComponent(); | ||
|
||
expect(screen.getByRole('heading', { level: 3, name: 'Metadata' })).toBeInTheDocument(); | ||
expect(screen.getByText(errorMessage.defaultMessage)).toBeInTheDocument(); | ||
}); | ||
|
||
test('should render metadata sidebar with loading indicator', async () => { | ||
mockUseSidebarMetadataFetcher.mockReturnValue({ | ||
templates: [], | ||
errorMessage: null, | ||
status: STATUS.LOADING, | ||
file: mockFile, | ||
}); | ||
|
||
renderComponent(); | ||
|
||
expect(screen.getByRole('heading', { level: 3, name: 'Metadata' })).toBeInTheDocument(); | ||
expect(screen.getByTestId('loading')).toBeInTheDocument(); | ||
expect(screen.getByRole('status', { name: 'Loading' })).toBeInTheDocument(); | ||
}); | ||
}); |
23 changes: 0 additions & 23 deletions
23
src/elements/content-sidebar/__tests__/MetadataSidebarRedesigned.test.tsx
This file was deleted.
Oops, something went wrong.
109 changes: 109 additions & 0 deletions
109
src/elements/content-sidebar/__tests__/useSidebarMetadataFetcher.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
import { renderHook, waitFor } from '../../../test-utils/testing-library'; | ||
import messages from '../../common/messages'; | ||
import { FIELD_PERMISSIONS_CAN_UPLOAD } from '../../../constants'; | ||
import useSidebarMetadataFetcher, { STATUS } from '../hooks/useSidebarMetadataFetcher'; | ||
|
||
const mockError = { | ||
status: 500, | ||
message: 'Internal Server Error', | ||
}; | ||
|
||
const mockFile = { | ||
id: '123', | ||
permissions: { [FIELD_PERMISSIONS_CAN_UPLOAD]: true }, | ||
}; | ||
|
||
const mockTemplates = [ | ||
{ | ||
id: 'metadata_template_custom_1', | ||
scope: 'global', | ||
templateKey: 'properties', | ||
hidden: false, | ||
}, | ||
]; | ||
|
||
const mockAPI = { | ||
getFile: jest.fn((id, successCallback, errorCallback) => { | ||
try { | ||
successCallback(mockFile); | ||
} catch (error) { | ||
errorCallback(error); | ||
} | ||
}), | ||
getMetadata: jest.fn((_file, successCallback, errorCallback) => { | ||
try { | ||
successCallback({ | ||
editors: [], | ||
templates: mockTemplates, | ||
}); | ||
} catch (error) { | ||
errorCallback(error); | ||
} | ||
}), | ||
}; | ||
const api = { | ||
getFileAPI: jest.fn().mockReturnValue(mockAPI), | ||
getMetadataAPI: jest.fn().mockReturnValue(mockAPI), | ||
}; | ||
|
||
describe('useSidebarMetadataFetcher', () => { | ||
const onErrorMock = jest.fn(); | ||
const isFeatureEnabledMock = true; | ||
|
||
const setupHook = (fileId = '123') => | ||
renderHook(() => useSidebarMetadataFetcher(api, fileId, onErrorMock, isFeatureEnabledMock)); | ||
|
||
test('should fetch the file and metadata successfully', async () => { | ||
const { result } = setupHook(); | ||
|
||
await waitFor(() => expect(result.current.status).toBe(STATUS.SUCCESS)); | ||
|
||
expect(result.current.file).toEqual(mockFile); | ||
expect(result.current.templates).toEqual(mockTemplates); | ||
expect(result.current.errorMessage).toBeNull(); | ||
}); | ||
|
||
test('should handle file fetching error', async () => { | ||
mockAPI.getFile.mockImplementation((id, successCallback, errorCallback) => | ||
errorCallback(mockError, 'file_fetch_error'), | ||
); | ||
|
||
const { result } = setupHook(); | ||
|
||
await waitFor(() => expect(result.current.status).toBe(STATUS.ERROR)); | ||
|
||
expect(result.current.file).toBeUndefined(); | ||
expect(result.current.errorMessage).toBe(messages.sidebarMetadataEditingErrorContent); | ||
expect(onErrorMock).toHaveBeenCalledWith( | ||
mockError, | ||
'file_fetch_error', | ||
expect.objectContaining({ | ||
error: mockError, | ||
isErrorDisplayed: true, | ||
}), | ||
); | ||
}); | ||
|
||
test('should handle metadata fetching error', async () => { | ||
mockAPI.getFile.mockImplementation((id, successCallback) => { | ||
successCallback(mockFile); | ||
}); | ||
mockAPI.getMetadata.mockImplementation((file, successCallback, errorCallback) => { | ||
errorCallback(mockError, 'metadata_fetch_error'); | ||
}); | ||
const { result } = setupHook(); | ||
|
||
await waitFor(() => expect(result.current.status).toBe(STATUS.ERROR)); | ||
|
||
expect(result.current.templates).toBeNull(); | ||
expect(result.current.errorMessage).toBe(messages.sidebarMetadataFetchingErrorContent); | ||
expect(onErrorMock).toHaveBeenCalledWith( | ||
mockError, | ||
'metadata_fetch_error', | ||
expect.objectContaining({ | ||
error: mockError, | ||
isErrorDisplayed: true, | ||
}), | ||
); | ||
}); | ||
}); |
Oops, something went wrong.