debian-image-builder-frontend/src/test/Components/CreateImageWizard/steps/Users/Users.test.tsx

195 lines
6 KiB
TypeScript

import type { Router as RemixRouter } from '@remix-run/router';
import { screen, waitFor, within } from '@testing-library/react';
import { userEvent } from '@testing-library/user-event';
import { CREATE_BLUEPRINT, EDIT_BLUEPRINT } from '../../../../../constants';
import { mockBlueprintIds } from '../../../../fixtures/blueprints';
import { usersCreateBlueprintRequest } from '../../../../fixtures/editMode';
import {
blueprintRequest,
clickBack,
clickNext,
enterBlueprintName,
getNextButton,
interceptBlueprintRequest,
interceptEditBlueprintRequest,
openAndDismissSaveAndBuildModal,
renderEditMode,
verifyCancelButton,
} from '../../wizardTestUtils';
import {
clickRegisterLater,
goToRegistrationStep,
renderCreateMode,
} from '../../wizardTestUtils';
let router: RemixRouter | undefined = undefined;
const goToUsersStep = async () => {
await clickNext();
await clickNext();
await clickNext();
await clickNext();
await clickNext();
await clickNext();
};
const goToReviewStep = async () => {
await clickNext(); // Timezone
await clickNext(); // Locale
await clickNext(); // Hostname
await clickNext(); // Kernel
await clickNext(); // Firewall
await clickNext(); // First boot
await clickNext(); // Details
await enterBlueprintName();
await clickNext(); // Review
};
const clickRevisitButton = async () => {
const user = userEvent.setup();
const expandable = await screen.findByTestId('users-expandable');
const revisitButton = await within(expandable).findByTestId('revisit-users');
await waitFor(() => user.click(revisitButton));
};
const addValidUser = async () => {
const user = userEvent.setup();
const addUser = await screen.findByRole('button', { name: /add a user/i });
expect(addUser).toBeEnabled();
await waitFor(() => user.click(addUser));
const enterUserName = screen.getByRole('textbox', {
name: /blueprint user name/i,
});
const nextButton = await getNextButton();
await waitFor(() => user.type(enterUserName, 'best'));
await waitFor(() => expect(enterUserName).toHaveValue('best'));
const enterSshKey = await screen.findByRole('textbox', {
name: /public SSH key/i,
});
await waitFor(() => user.type(enterSshKey, 'ssh-rsa d'));
await waitFor(() => expect(enterSshKey).toHaveValue('ssh-rsa d'));
await waitFor(() => expect(nextButton).toBeEnabled());
};
const addInvalidUser = async () => {
const user = userEvent.setup();
const addUser = await screen.findByRole('button', { name: /add a user/i });
expect(addUser).toBeEnabled();
await waitFor(() => user.click(addUser));
const enterUserName = screen.getByRole('textbox', {
name: /blueprint user name/i,
});
const nextButton = await getNextButton();
await waitFor(() => user.type(enterUserName, '..'));
await waitFor(() => expect(enterUserName).toHaveValue('..'));
const enterSshKey = await screen.findByRole('textbox', {
name: /public SSH key/i,
});
await waitFor(() => user.type(enterSshKey, 'ssh-rsa d'));
await waitFor(() => expect(nextButton).toBeDisabled());
};
describe('Step Users', () => {
beforeEach(async () => {
vi.clearAllMocks();
router = undefined;
});
test('without adding user loads timezone', async () => {
const user = userEvent.setup();
await renderCreateMode();
await goToRegistrationStep();
await clickRegisterLater();
await goToUsersStep();
const nextButton = await getNextButton();
expect(nextButton).toBeEnabled();
await waitFor(() => user.click(nextButton));
await screen.findByText('Select a timezone for your image.');
});
test('clicking Back loads Additional packages', async () => {
await renderCreateMode();
await goToRegistrationStep();
await clickRegisterLater();
await goToUsersStep();
await clickBack();
await screen.findByRole('heading', { name: 'Additional packages' });
});
test('clicking Cancel loads landing page', async () => {
await renderCreateMode();
await goToUsersStep();
await verifyCancelButton(router);
});
test('revisit step button on Review works', async () => {
await renderCreateMode();
await goToRegistrationStep();
await clickRegisterLater();
await goToUsersStep();
await addValidUser();
await goToReviewStep();
await clickRevisitButton();
await screen.findByRole('heading', { name: /Users/ });
});
describe('User request generated correctly', () => {
test('with valid name and password', async () => {
await renderCreateMode();
await goToRegistrationStep();
await clickRegisterLater();
await goToUsersStep();
await addValidUser();
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: {
users: [
{
name: 'best',
ssh_key: 'ssh-rsa d',
},
],
},
};
await waitFor(() => {
expect(receivedRequest).toEqual(expectedRequest);
});
});
test('with invalid name', async () => {
await renderCreateMode();
await goToRegistrationStep();
await clickRegisterLater();
await goToUsersStep();
await addInvalidUser();
const invalidUserMessage = screen.getByText(/invalid user name/i);
await waitFor(() => expect(invalidUserMessage));
});
});
describe('Users edit mode', () => {
beforeEach(() => {
vi.clearAllMocks();
});
test('edit mode works', async () => {
const id = mockBlueprintIds['users'];
await renderEditMode(id);
// starts on review step
const receivedRequest = await interceptEditBlueprintRequest(
`${EDIT_BLUEPRINT}/${id}`
);
const expectedRequest = usersCreateBlueprintRequest;
expect(receivedRequest).toEqual(expectedRequest);
});
});
});