Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: [M3-8501] - AccessSelect Optimization: Use React Hook Form #10952

Open
wants to merge 9 commits into
base: develop
Choose a base branch
from
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Tech Stories
---

Optimize AccessSelect component: Use React Hook Form & React Query ([#10952](https://github.com/linode/manager/pull/10952))
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { act, fireEvent, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import * as React from 'react';

import { HttpResponse, http, server } from 'src/mocks/testServer';
import { renderWithTheme } from 'src/utilities/testHelpers';

import { AccessSelect } from './AccessSelect';
Expand All @@ -11,31 +12,27 @@ import type { ObjectStorageEndpointTypes } from '@linode/api-v4';

const CORS_ENABLED_TEXT = 'CORS Enabled';
const AUTHENTICATED_READ_TEXT = 'Authenticated Read';
const BUCKET_ACCESS_URL = '*object-storage/buckets/*/*/access';
const OBJECT_ACCESS_URL = '*object-storage/buckets/*/*/object-acl';

vi.mock('src/components/EnhancedSelect/Select');

const mockGetAccess = vi.fn().mockResolvedValue({
acl: 'private',
cors_enabled: true,
});
const mockUpdateAccess = vi.fn().mockResolvedValue({});

const defaultProps: Props = {
clusterOrRegion: 'in-maa',
endpointType: 'E1',
getAccess: mockGetAccess,
name: 'my-object-name',
updateAccess: mockUpdateAccess,
variant: 'bucket',
};

describe('AccessSelect', () => {
const renderComponent = (props: Partial<Props> = {}) =>
renderWithTheme(<AccessSelect {...defaultProps} {...props} />);
renderWithTheme(<AccessSelect {...defaultProps} {...props} />, {
flags: { objectStorageGen2: { enabled: true } },
});

beforeEach(() => {
vi.clearAllMocks();
});

it.each([
['bucket', 'E0', true],
['bucket', 'E1', true],
Expand All @@ -48,13 +45,21 @@ describe('AccessSelect', () => {
])(
'shows correct UI for %s variant and %s endpoint type',
async (variant, endpointType, shouldShowCORS) => {
server.use(
http.get(BUCKET_ACCESS_URL, () => {
return HttpResponse.json({ acl: 'private', cors_enabled: true });
}),
http.get(OBJECT_ACCESS_URL, () => {
return HttpResponse.json({ acl: 'private' });
})
);

renderComponent({
endpointType: endpointType as ObjectStorageEndpointTypes,
variant: variant as 'bucket' | 'object',
});

const aclSelect = screen.getByRole('combobox');

await waitFor(() => {
expect(aclSelect).toBeEnabled();
expect(aclSelect).toHaveValue('Private');
Expand All @@ -69,7 +74,6 @@ describe('AccessSelect', () => {
'aria-selected',
'true'
);

if (shouldShowCORS) {
await waitFor(() => {
expect(screen.getByLabelText(CORS_ENABLED_TEXT)).toBeInTheDocument();
Expand All @@ -92,13 +96,25 @@ describe('AccessSelect', () => {
it('updates the access and CORS settings and submits the appropriate values', async () => {
renderComponent();

server.use(
http.get(BUCKET_ACCESS_URL, () => {
return HttpResponse.json({ acl: 'private', cors_enabled: true });
}),
http.put(BUCKET_ACCESS_URL, () => {
return HttpResponse.json({});
})
);

const aclSelect = screen.getByRole('combobox');
const saveButton = screen.getByText('Save').closest('button')!;

await waitFor(() => {
expect(aclSelect).toBeEnabled();
expect(aclSelect).toHaveValue('Private');
});
await waitFor(
() => {
expect(aclSelect).toBeEnabled();
expect(aclSelect).toHaveValue('Private');
},
{ interval: 100, timeout: 5000 }
);

// Wait for CORS toggle to appear and be checked
const corsToggle = await screen.findByRole('checkbox', {
Expand Down Expand Up @@ -131,12 +147,8 @@ describe('AccessSelect', () => {
});

await userEvent.click(saveButton);
expect(mockUpdateAccess).toHaveBeenCalledWith('authenticated-read', false);

await userEvent.click(corsToggle);
await waitFor(() => expect(corsToggle).toBeChecked());

await userEvent.click(saveButton);
expect(mockUpdateAccess).toHaveBeenCalledWith('authenticated-read', true);
await waitFor(() =>
screen.findByText('Bucket access updated successfully.')
);
});
});
Loading