diff --git a/packages/manager/src/features/ObjectStorage/BucketLanding/CreateBucketDrawer.test.tsx b/packages/manager/src/features/ObjectStorage/BucketLanding/CreateBucketDrawer.test.tsx new file mode 100644 index 00000000000..3fa1b692376 --- /dev/null +++ b/packages/manager/src/features/ObjectStorage/BucketLanding/CreateBucketDrawer.test.tsx @@ -0,0 +1,81 @@ +import * as React from 'react'; +import { CreateBucketDrawer } from './CreateBucketDrawer'; +import { waitFor } from '@testing-library/react'; +import { renderWithTheme } from 'src/utilities/testHelpers'; +import userEvent from '@testing-library/user-event'; +import { rest, server } from 'src/mocks/testServer'; +import { makeResourcePage } from 'src/mocks/serverHandlers'; +import { + accountSettingsFactory, + objectStorageClusterFactory, + regionFactory, +} from 'src/factories'; + +const props = { + isOpen: true, + onClose: jest.fn(), +}; + +jest.mock('src/components/EnhancedSelect/Select'); + +describe('CreateBucketDrawer', () => { + it('Should show a general error notice if the API returns one', async () => { + server.use( + rest.post('*/object-storage/buckets', (req, res, ctx) => { + return res( + ctx.status(500), + ctx.json({ errors: [{ reason: 'Object Storage is offline!' }] }) + ); + }), + rest.get('*/regions', async (req, res, ctx) => { + return res( + ctx.json( + makeResourcePage( + regionFactory.buildList(1, { id: 'us-east', label: 'Newark, NJ' }) + ) + ) + ); + }), + rest.get('*object-storage/clusters', (req, res, ctx) => { + return res( + ctx.json( + makeResourcePage( + objectStorageClusterFactory.buildList(1, { + region: 'us-east', + id: 'us-east-1', + }) + ) + ) + ); + }), + rest.get('*/account/settings', (req, res, ctx) => { + return res( + ctx.json(accountSettingsFactory.build({ object_storage: 'active' })) + ); + }) + ); + + const { + getByTestId, + getByLabelText, + getByPlaceholderText, + findByText, + } = renderWithTheme(); + + userEvent.type(getByLabelText('Label'), 'my-test-bucket'); + + // We must waitFor because we need to load region and cluster data from the API + await waitFor(() => + userEvent.selectOptions( + getByPlaceholderText('Select a Region'), + 'Newark, NJ (us-east-1)' + ) + ); + + const saveButton = getByTestId('create-bucket-button'); + + userEvent.click(saveButton); + + await findByText('Object Storage is offline!'); + }); +}); diff --git a/packages/manager/src/features/ObjectStorage/BucketLanding/CreateBucketDrawer.tsx b/packages/manager/src/features/ObjectStorage/BucketLanding/CreateBucketDrawer.tsx index 8e9e1193a5b..7784a2c1b29 100644 --- a/packages/manager/src/features/ObjectStorage/BucketLanding/CreateBucketDrawer.tsx +++ b/packages/manager/src/features/ObjectStorage/BucketLanding/CreateBucketDrawer.tsx @@ -54,6 +54,7 @@ export const CreateBucketDrawer = (props: Props) => { error, reset, } = useCreateBucketMutation(); + const { data: agreements } = useAccountAgreements(); const { mutateAsync: updateAccountAgreements } = useMutateAccountAgreements(); const { data: accountSettings } = useAccountSettings(); @@ -121,6 +122,7 @@ export const CreateBucketDrawer = (props: Props) => { data-qa-permissions-notice /> )} + {Boolean(errorMap.none) && } { /> formik.setFieldValue('cluster', value)} selectedCluster={formik.values.cluster} @@ -153,7 +155,12 @@ export const CreateBucketDrawer = (props: Props) => { - diff --git a/packages/manager/src/mocks/serverHandlers.ts b/packages/manager/src/mocks/serverHandlers.ts index d4b8464b5bf..3d067ed28c9 100644 --- a/packages/manager/src/mocks/serverHandlers.ts +++ b/packages/manager/src/mocks/serverHandlers.ts @@ -635,6 +635,9 @@ export const handlers = [ const buckets = objectStorageBucketFactory.buildList(10); return res(ctx.json(makeResourcePage(buckets))); }), + rest.post('*/object-storage/buckets', (req, res, ctx) => { + return res(ctx.json(objectStorageBucketFactory.build())); + }), rest.get('*object-storage/clusters', (req, res, ctx) => { const clusters = objectStorageClusterFactory.buildList(3); return res(ctx.json(makeResourcePage(clusters))); diff --git a/packages/manager/src/queries/objectStorage.ts b/packages/manager/src/queries/objectStorage.ts index af627ef922d..7032395aa29 100644 --- a/packages/manager/src/queries/objectStorage.ts +++ b/packages/manager/src/queries/objectStorage.ts @@ -26,7 +26,7 @@ import { getObjectURL, ObjectStorageObjectURLOptions, ObjectStorageObjectURL, -} from '@linode/api-v4/lib/object-storage'; +} from '@linode/api-v4'; import { queryKey as accountSettingsQueryKey } from './accountSettings'; export interface BucketError { diff --git a/packages/manager/src/utilities/testHelpers.tsx b/packages/manager/src/utilities/testHelpers.tsx index 93926a4a632..315daccda04 100644 --- a/packages/manager/src/utilities/testHelpers.tsx +++ b/packages/manager/src/utilities/testHelpers.tsx @@ -13,6 +13,7 @@ import thunk from 'redux-thunk'; import { FlagSet } from 'src/featureFlags'; import LinodeThemeWrapper from 'src/LinodeThemeWrapper'; import { queryClientFactory } from 'src/queries/base'; +import { setupInterceptors } from 'src/request'; import { storeFactory, ApplicationState, @@ -55,6 +56,13 @@ export const wrapWithTheme = (ui: any, options: Options = {}) => { const storeToPass = customStore ? baseStore(customStore) : storeFactory(queryClient); + + // we have to call setupInterceptors so that our API error normalization works as expected + // I'm sorry that it makes us pass it the "ApplicationStore" + setupInterceptors( + configureStore([thunk])(defaultState) + ); + return (