debian-image-builder-frontend/src/test/Components/CreateImageWizard/steps/FileSystemConfiguration/FileSystemConfiguration.test.tsx
regexowl a0fe3644c3 src: Remove more data-testids
As using `data-testid`s in tests is an anti-pattern, this removes more of them and replaces them with appropriate locators in the tests.
2025-07-15 16:51:29 +00:00

406 lines
12 KiB
TypeScript

import { screen, waitFor, within } from '@testing-library/react';
import { userEvent } from '@testing-library/user-event';
import {
CREATE_BLUEPRINT,
EDIT_BLUEPRINT,
UNIT_GIB,
UNIT_KIB,
UNIT_MIB,
} from '../../../../../constants';
import { mockBlueprintIds } from '../../../../fixtures/blueprints';
import { fscCreateBlueprintRequest } from '../../../../fixtures/editMode';
import {
clickNext,
clickReviewAndFinish,
getNextButton,
} from '../../wizardTestUtils';
import {
blueprintRequest,
clickRegisterLater,
enterBlueprintName,
interceptBlueprintRequest,
interceptEditBlueprintRequest,
openAndDismissSaveAndBuildModal,
renderCreateMode,
renderEditMode,
} from '../../wizardTestUtils';
const selectGuestImage = async () => {
const user = userEvent.setup();
const guestImageCheckBox = await screen.findByRole('checkbox', {
name: /virtualization guest image checkbox/i,
});
await waitFor(() => user.click(guestImageCheckBox));
};
const selectImageInstaller = async () => {
const user = userEvent.setup();
const imageInstallerCheckbox = await screen.findByRole('checkbox', {
name: /Bare metal installer/i,
});
await waitFor(() => user.click(imageInstallerCheckbox));
};
const goToFileSystemConfigurationStep = async () => {
await clickNext(); // Registration
await clickRegisterLater();
await clickNext(); // OpenSCAP
await clickNext(); // File System
};
const clickManuallyConfigurePartitions = async () => {
const user = userEvent.setup();
const button = await screen.findByText(/manually configure partitions/i);
await waitFor(() => user.click(button));
};
const addPartition = async () => {
const user = userEvent.setup();
const button = await screen.findByRole('button', { name: /add partition/i });
await waitFor(() => user.click(button));
};
const customizePartition = async () => {
const user = userEvent.setup();
const row = await getRow(2);
const minSize = await within(row).findByRole('textbox', {
name: /mountpoint suffix/i,
});
await waitFor(() => user.type(minSize, 'cakerecipes'));
};
const getRow = async (row: number) => {
const rows = await screen.findAllByRole('row');
return rows[row];
};
const changePartitionSize = async () => {
const user = userEvent.setup();
const row = await getRow(1);
const minSize = await within(row).findByRole('textbox', {
name: /minimum partition size/i,
});
await waitFor(() => user.type(minSize, '{backspace}5'));
};
const changePartitionUnitsToKiB = async () => {
const user = userEvent.setup();
const row = await getRow(1);
const units = await within(row).findByText('GiB');
await waitFor(() => user.click(units));
const kibOption = await screen.findByRole('option', { name: 'KiB' });
await waitFor(() => user.click(kibOption));
};
const changePartitionUnitsToMiB = async () => {
const user = userEvent.setup();
const row = await getRow(1);
const units = await within(row).findByText('GiB');
await waitFor(() => user.click(units));
const mibOption = await screen.findByRole('option', { name: 'MiB' });
await waitFor(() => user.click(mibOption));
};
const goToReviewStep = async () => {
await clickNext(); // File system configuration
await clickNext(); // Repository snapshot/Repeatable builds
await clickNext(); // Custom repositories
await clickNext(); // Additional packages
await clickNext(); // Users
await clickNext(); // Timezone
await clickNext(); // Locale
await clickNext(); // Hostname
await clickNext(); // Kernel
await clickNext(); // Firewall
await clickNext(); // Services
await clickNext(); // Details
await enterBlueprintName();
await clickNext(); // Review
};
const clickRevisitButton = async () => {
const user = userEvent.setup();
const expandable = await screen.findByTestId(
'file-system-configuration-expandable'
);
const revisitButton = await within(expandable).findByTestId(
'revisit-file-system'
);
await waitFor(() => user.click(revisitButton));
};
describe('Step File system configuration', () => {
beforeEach(() => {
vi.clearAllMocks();
});
const user = userEvent.setup();
test('clicking Review and finish leads to Review', async () => {
await renderCreateMode();
await selectGuestImage();
await goToFileSystemConfigurationStep();
await clickReviewAndFinish();
await screen.findByRole('heading', {
name: /Review/i,
});
});
test('button Review and finish is disabled for invalid state', async () => {
await renderCreateMode();
await selectGuestImage();
await goToFileSystemConfigurationStep();
await clickManuallyConfigurePartitions();
// Create duplicate partitions
await addPartition();
await addPartition();
await clickReviewAndFinish();
expect(
await screen.findByRole('button', { name: /Review and finish/ })
).toBeDisabled();
});
test('error validation occurs upon clicking next button', async () => {
await renderCreateMode();
await selectGuestImage();
await goToFileSystemConfigurationStep();
await clickManuallyConfigurePartitions();
// Create duplicate partitions
await addPartition();
await addPartition();
// Clicking next causes errors to appear
await clickNext();
expect(await getNextButton()).toBeDisabled();
const mountPointAlerts = screen.getAllByRole('heading', {
name: /danger alert: duplicate mount point/i,
});
const rows = await screen.findAllByRole('row');
rows.shift(); // remove table header
expect(rows).toHaveLength(3);
//Change mountpoint of final row to /var, resolving errors
const mountPointOptions = await within(rows[2]).findByText('/home');
await waitFor(() => user.click(mountPointOptions));
const varButton = await screen.findByRole('option', {
name: /\/var/i,
});
user.click(varButton);
await waitFor(() => expect(mountPointAlerts[0]).not.toBeInTheDocument());
await waitFor(() => expect(mountPointAlerts[1]).not.toBeInTheDocument());
expect(await getNextButton()).toBeEnabled();
});
test('manual partitioning is hidden for ISO targets only', async () => {
await renderCreateMode();
await selectImageInstaller();
await goToFileSystemConfigurationStep();
expect(
screen.queryByText(/manually configure partitions/i)
).not.toBeInTheDocument();
});
test('manual partitioning is shown for ISO target and other target', async () => {
await renderCreateMode();
await selectImageInstaller();
await selectGuestImage();
await goToFileSystemConfigurationStep();
await clickManuallyConfigurePartitions();
await screen.findByText('Configure partitions');
});
test('revisit step button on Review works', async () => {
await renderCreateMode();
await selectGuestImage();
await goToFileSystemConfigurationStep();
await goToReviewStep();
await clickRevisitButton();
await screen.findByRole('heading', { name: /File system configuration/ });
});
});
describe('File system configuration request generated correctly', () => {
beforeEach(() => {
vi.clearAllMocks();
});
test('10 GiB / correct', async () => {
await renderCreateMode();
await selectGuestImage();
await goToFileSystemConfigurationStep();
await clickManuallyConfigurePartitions();
await goToReviewStep();
// informational modal pops up in the first test only as it's tied
// to a 'imageBuilder.saveAndBuildModalSeen' variable in localStorage
await openAndDismissSaveAndBuildModal();
const receivedRequest = await interceptBlueprintRequest(CREATE_BLUEPRINT);
const expectedRequest = {
...blueprintRequest,
customizations: {
filesystem: [
{
min_size: 10 * UNIT_GIB,
mountpoint: '/',
},
],
},
};
expect(receivedRequest).toEqual(expectedRequest);
});
test('15 GiB / correct', async () => {
await renderCreateMode();
await selectGuestImage();
await goToFileSystemConfigurationStep();
await clickManuallyConfigurePartitions();
await changePartitionSize();
await goToReviewStep();
const receivedRequest = await interceptBlueprintRequest(CREATE_BLUEPRINT);
const expectedRequest = {
...blueprintRequest,
customizations: {
filesystem: [
{
min_size: 15 * UNIT_GIB,
mountpoint: '/',
},
],
},
};
expect(receivedRequest).toEqual(expectedRequest);
});
test('MiB / correct', async () => {
await renderCreateMode();
await selectGuestImage();
await goToFileSystemConfigurationStep();
await clickManuallyConfigurePartitions();
await changePartitionUnitsToMiB();
await goToReviewStep();
const receivedRequest = await interceptBlueprintRequest(CREATE_BLUEPRINT);
const expectedRequest = {
...blueprintRequest,
customizations: {
filesystem: [
{
min_size: 10 * UNIT_MIB,
mountpoint: '/',
},
],
},
};
expect(receivedRequest).toEqual(expectedRequest);
});
test('KiB / correct', async () => {
await renderCreateMode();
await selectGuestImage();
await goToFileSystemConfigurationStep();
await clickManuallyConfigurePartitions();
await changePartitionUnitsToKiB();
await goToReviewStep();
const receivedRequest = await interceptBlueprintRequest(CREATE_BLUEPRINT);
const expectedRequest = {
...blueprintRequest,
customizations: {
filesystem: [
{
min_size: 10 * UNIT_KIB,
mountpoint: '/',
},
],
},
};
expect(receivedRequest).toEqual(expectedRequest);
});
test('/home correct', async () => {
await renderCreateMode();
await selectGuestImage();
await goToFileSystemConfigurationStep();
await clickManuallyConfigurePartitions();
await addPartition();
await goToReviewStep();
const receivedRequest = await interceptBlueprintRequest(CREATE_BLUEPRINT);
const expectedRequest = {
...blueprintRequest,
customizations: {
filesystem: [
{
min_size: 10 * UNIT_GIB,
mountpoint: '/',
},
{
min_size: 1 * UNIT_GIB,
mountpoint: '/home',
},
],
},
};
expect(receivedRequest).toEqual(expectedRequest);
});
test('/home/cakerecipes correct', async () => {
await renderCreateMode();
await selectGuestImage();
await goToFileSystemConfigurationStep();
await clickManuallyConfigurePartitions();
await addPartition();
await customizePartition();
await goToReviewStep();
const receivedRequest = await interceptBlueprintRequest(CREATE_BLUEPRINT);
const expectedRequest = {
...blueprintRequest,
customizations: {
filesystem: [
{
min_size: 10 * UNIT_GIB,
mountpoint: '/',
},
{
min_size: 1 * UNIT_GIB,
mountpoint: '/home/cakerecipes',
},
],
},
};
await waitFor(() => {
expect(receivedRequest).toEqual(expectedRequest);
});
});
});
describe('File system configuration edit mode', () => {
beforeEach(() => {
vi.clearAllMocks();
});
test('edit mode works', async () => {
const id = mockBlueprintIds['fsc'];
await renderEditMode(id);
// starts on review step
const receivedRequest = await interceptEditBlueprintRequest(
`${EDIT_BLUEPRINT}/${id}`
);
const expectedRequest = fscCreateBlueprintRequest;
expect(receivedRequest).toEqual(expectedRequest);
});
});