274 lines
8.2 KiB
TypeScript
274 lines
8.2 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 { timezoneCreateBlueprintRequest } from '../../../../fixtures/editMode';
|
|
import {
|
|
blueprintRequest,
|
|
clickBack,
|
|
clickNext,
|
|
enterBlueprintName,
|
|
interceptBlueprintRequest,
|
|
interceptEditBlueprintRequest,
|
|
openAndDismissSaveAndBuildModal,
|
|
renderEditMode,
|
|
verifyCancelButton,
|
|
} from '../../wizardTestUtils';
|
|
import { clickRegisterLater, renderCreateMode } from '../../wizardTestUtils';
|
|
|
|
let router: RemixRouter | undefined = undefined;
|
|
|
|
const goToTimezoneStep = async () => {
|
|
const user = userEvent.setup();
|
|
const guestImageCheckBox = await screen.findByRole('checkbox', {
|
|
name: /virtualization guest image checkbox/i,
|
|
});
|
|
await waitFor(() => user.click(guestImageCheckBox));
|
|
await clickNext(); // Registration
|
|
await clickRegisterLater();
|
|
await clickNext(); // OpenSCAP
|
|
await clickNext(); // File system configuration
|
|
await clickNext(); // Snapshots
|
|
await clickNext(); // Custom repositories
|
|
await clickNext(); // Additional packages
|
|
await clickNext(); // Users
|
|
await clickNext(); // Timezone
|
|
};
|
|
|
|
const goToReviewStep = async () => {
|
|
await clickNext(); // Locale
|
|
await clickNext(); // Hostname
|
|
await clickNext(); // Kernel
|
|
await clickNext(); // Firewall
|
|
await clickNext(); // Services
|
|
await clickNext(); // First boot script
|
|
await clickNext(); // Details
|
|
await enterBlueprintName();
|
|
await clickNext(); // Review
|
|
};
|
|
|
|
const selectTimezone = async () => {
|
|
const user = userEvent.setup({ delay: null });
|
|
const timezoneDropdown = await screen.findByPlaceholderText(
|
|
/select a timezone/i
|
|
);
|
|
await waitFor(() => user.type(timezoneDropdown, 'Europe/Am'));
|
|
const amsterdamTimezone = await screen.findByText('Europe/Amsterdam');
|
|
await waitFor(() => user.click(amsterdamTimezone));
|
|
};
|
|
|
|
const searchForUnknownTimezone = async () => {
|
|
const user = userEvent.setup();
|
|
const timezoneDropdown = await screen.findByPlaceholderText(
|
|
/select a timezone/i
|
|
);
|
|
await waitFor(() => user.type(timezoneDropdown, 'foo'));
|
|
};
|
|
|
|
const addNtpServerViaKeyDown = async (ntpServer: string) => {
|
|
const user = userEvent.setup();
|
|
const ntpServersInput = await screen.findByPlaceholderText(
|
|
/add ntp servers/i
|
|
);
|
|
await waitFor(() => user.type(ntpServersInput, ntpServer.concat(' ')));
|
|
};
|
|
|
|
const addNtpServerViaAddButton = async (ntpServer: string) => {
|
|
const user = userEvent.setup();
|
|
const ntpServersInput = await screen.findByPlaceholderText(
|
|
/add ntp servers/i
|
|
);
|
|
const addServerBtn = await screen.findByRole('button', {
|
|
name: /add ntp server/i,
|
|
});
|
|
await waitFor(() => user.type(ntpServersInput, ntpServer));
|
|
await waitFor(() => user.click(addServerBtn));
|
|
};
|
|
|
|
const clearInput = async () => {
|
|
const user = userEvent.setup();
|
|
const clearInputBtn = await screen.findByRole('button', {
|
|
name: /clear input/i,
|
|
});
|
|
await waitFor(() => user.click(clearInputBtn));
|
|
};
|
|
|
|
const clickRevisitButton = async () => {
|
|
const user = userEvent.setup();
|
|
const expandable = await screen.findByTestId('timezone-expandable');
|
|
const revisitButton = await within(expandable).findByTestId(
|
|
'revisit-timezone'
|
|
);
|
|
await waitFor(() => user.click(revisitButton));
|
|
};
|
|
|
|
describe('Step Timezone', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
router = undefined;
|
|
});
|
|
|
|
test('clicking Next loads Locale', async () => {
|
|
await renderCreateMode();
|
|
await goToTimezoneStep();
|
|
await clickNext();
|
|
await screen.findByRole('heading', {
|
|
name: 'Locale',
|
|
});
|
|
});
|
|
|
|
test('clicking Back loads Users', async () => {
|
|
await renderCreateMode();
|
|
await goToTimezoneStep();
|
|
await clickBack();
|
|
await screen.findByRole('heading', { name: 'Users' });
|
|
});
|
|
|
|
test('clicking Cancel loads landing page', async () => {
|
|
await renderCreateMode();
|
|
await goToTimezoneStep();
|
|
await verifyCancelButton(router);
|
|
});
|
|
|
|
test('unknown option is disabled', async () => {
|
|
await renderCreateMode();
|
|
await goToTimezoneStep();
|
|
await searchForUnknownTimezone();
|
|
await screen.findByText(/no results found/i);
|
|
expect(
|
|
await screen.findByRole('option', { name: /no results found/i })
|
|
).toBeDisabled();
|
|
});
|
|
|
|
test('duplicate NTP server cannnot be added', async () => {
|
|
await renderCreateMode();
|
|
await goToTimezoneStep();
|
|
expect(
|
|
screen.queryByText('NTP server already exists.')
|
|
).not.toBeInTheDocument();
|
|
await addNtpServerViaKeyDown('0.nl.pool.ntp.org');
|
|
await addNtpServerViaKeyDown('0.nl.pool.ntp.org');
|
|
await screen.findByText('NTP server already exists.');
|
|
await clearInput();
|
|
expect(
|
|
screen.queryByText('NTP server already exists.')
|
|
).not.toBeInTheDocument();
|
|
await addNtpServerViaAddButton('0.nl.pool.ntp.org');
|
|
await screen.findByText('NTP server already exists.');
|
|
});
|
|
|
|
test('NTP server in an invalid format cannot be added', async () => {
|
|
await renderCreateMode();
|
|
await goToTimezoneStep();
|
|
expect(
|
|
screen.queryByText(
|
|
'Expected format: <ntp-server>. Example: time.redhat.com'
|
|
)
|
|
).not.toBeInTheDocument();
|
|
await addNtpServerViaKeyDown('this is not NTP server');
|
|
await screen.findByText(
|
|
'Expected format: <ntp-server>. Example: time.redhat.com'
|
|
);
|
|
});
|
|
|
|
test('revisit step button on Review works', async () => {
|
|
await renderCreateMode();
|
|
await goToTimezoneStep();
|
|
await selectTimezone();
|
|
await goToReviewStep();
|
|
await clickRevisitButton();
|
|
await screen.findByRole('heading', { name: /Timezone/ });
|
|
});
|
|
});
|
|
|
|
describe('Timezone request generated correctly', () => {
|
|
test('with timezone selected', async () => {
|
|
await renderCreateMode();
|
|
await goToTimezoneStep();
|
|
await selectTimezone();
|
|
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: {
|
|
timezone: {
|
|
timezone: 'Europe/Amsterdam',
|
|
},
|
|
},
|
|
};
|
|
|
|
await waitFor(() => {
|
|
expect(receivedRequest).toEqual(expectedRequest);
|
|
});
|
|
});
|
|
|
|
test('with NTP servers', async () => {
|
|
await renderCreateMode();
|
|
await goToTimezoneStep();
|
|
await addNtpServerViaKeyDown('0.nl.pool.ntp.org');
|
|
await addNtpServerViaKeyDown('1.nl.pool.ntp.org');
|
|
await goToReviewStep();
|
|
const receivedRequest = await interceptBlueprintRequest(CREATE_BLUEPRINT);
|
|
|
|
const expectedRequest = {
|
|
...blueprintRequest,
|
|
customizations: {
|
|
timezone: {
|
|
ntpservers: ['0.nl.pool.ntp.org', '1.nl.pool.ntp.org'],
|
|
},
|
|
},
|
|
};
|
|
|
|
await waitFor(() => {
|
|
expect(receivedRequest).toEqual(expectedRequest);
|
|
});
|
|
});
|
|
|
|
test('with timezone and NTP servers', async () => {
|
|
await renderCreateMode();
|
|
await goToTimezoneStep();
|
|
await selectTimezone();
|
|
await addNtpServerViaKeyDown('0.nl.pool.ntp.org');
|
|
await addNtpServerViaKeyDown('1.nl.pool.ntp.org');
|
|
await goToReviewStep();
|
|
const receivedRequest = await interceptBlueprintRequest(CREATE_BLUEPRINT);
|
|
|
|
const expectedRequest = {
|
|
...blueprintRequest,
|
|
customizations: {
|
|
timezone: {
|
|
timezone: 'Europe/Amsterdam',
|
|
ntpservers: ['0.nl.pool.ntp.org', '1.nl.pool.ntp.org'],
|
|
},
|
|
},
|
|
};
|
|
|
|
await waitFor(() => {
|
|
expect(receivedRequest).toEqual(expectedRequest);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('Timezone edit mode', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
test('edit mode works', async () => {
|
|
const id = mockBlueprintIds['timezone'];
|
|
await renderEditMode(id);
|
|
|
|
// starts on review step
|
|
const receivedRequest = await interceptEditBlueprintRequest(
|
|
`${EDIT_BLUEPRINT}/${id}`
|
|
);
|
|
const expectedRequest = timezoneCreateBlueprintRequest;
|
|
expect(receivedRequest).toEqual(expectedRequest);
|
|
});
|
|
});
|