Wizard: Services step basics

This adds basic structure of the Services step.
This commit is contained in:
regexowl 2025-01-22 10:04:24 +01:00 committed by Klara Simickova
parent c6bee55544
commit 0f86336af6
23 changed files with 122 additions and 3 deletions

View file

@ -27,6 +27,7 @@ import RegistrationStep from './steps/Registration';
import RepositoriesStep from './steps/Repositories';
import ReviewStep from './steps/Review';
import ReviewWizardFooter from './steps/Review/Footer/Footer';
import ServicesStep from './steps/Services';
import SnapshotStep from './steps/Snapshot';
import Aws from './steps/TargetEnvironment/Aws';
import Azure from './steps/TargetEnvironment/Azure';
@ -146,6 +147,7 @@ const CreateImageWizard = ({ isEdit }: CreateImageWizardProps) => {
const isHostnameEnabled = useFlag('image-builder.hostname.enabled');
const isKernelEnabled = useFlag('image-builder.kernel.enabled');
const isFirewallEnabled = useFlag('image-builder.firewall.enabled');
const isServicesStepEnabled = useFlag('image-builder.services.enabled');
// Remove this and all fallthrough logic when snapshotting is enabled in Prod-stable
// =========================TO REMOVE=======================
@ -236,7 +238,7 @@ const CreateImageWizard = ({ isEdit }: CreateImageWizardProps) => {
let startIndex = 1; // default index
if (isEdit) {
startIndex = 21;
startIndex = 22;
}
// Duplicating some of the logic from the Wizard component to allow for custom nav items status
@ -541,6 +543,18 @@ const CreateImageWizard = ({ isEdit }: CreateImageWizardProps) => {
>
<FirewallStep />
</WizardStep>,
<WizardStep
name="Systemd services"
id="wizard-services"
key="wizard-services"
navItem={customStatusNavItem}
isHidden={!isServicesStepEnabled}
footer={
<CustomWizardFooter disableNext={false} optional={true} />
}
>
<ServicesStep />
</WizardStep>,
<WizardStep
name="First boot script configuration"
id="wizard-first-boot"

View file

@ -0,0 +1,16 @@
import React from 'react';
import { Text, Form, Title } from '@patternfly/react-core';
const ServicesStep = () => {
return (
<Form>
<Title headingLevel="h1" size="xl">
Systemd services
</Title>
<Text>Enable and disable systemd services.</Text>
</Form>
);
};
export default ServicesStep;

View file

@ -29,6 +29,7 @@ const goToDetailsStep = async () => {
await clickNext(); // Hostname
await clickNext(); // Kernel
await clickNext(); // Firewall
await clickNext(); // Services
await clickNext(); // First boot script
await clickNext(); // Details
};

View file

@ -118,6 +118,7 @@ const goToReviewStep = async () => {
await clickNext(); // Hostname
await clickNext(); // Kernel
await clickNext(); // Firewall
await clickNext(); // Services
await clickNext(); // Details
await enterBlueprintName();
await clickNext(); // Review

View file

@ -38,6 +38,7 @@ const goToFirewallStep = async () => {
};
const goToReviewStep = async () => {
await clickNext(); // Services
await clickNext(); // First boot script
await clickNext(); // Details
await enterBlueprintName();
@ -56,12 +57,12 @@ describe('Step Firewall', () => {
router = undefined;
});
test('clicking Next loads First boot', async () => {
test('clicking Next loads Services', async () => {
await renderCreateMode();
await goToFirewallStep();
await clickNext();
await screen.findByRole('heading', {
name: 'First boot configuration',
name: 'Systemd services',
});
});

View file

@ -51,6 +51,7 @@ const goToFirstBootStep = async (): Promise<void> => {
await clickNext(); // Hostname
await clickNext(); // Kernel
await clickNext(); // Firewall
await clickNext(); // Services
await clickNext(); // First Boot
};
@ -76,6 +77,7 @@ const goFromOscapToFirstBoot = async () => {
await clickNext(); // Hostname
await clickNext(); // Kernel
await clickNext(); // Firewall
await clickNext(); // Services
await clickNext(); // First boot script
};

View file

@ -43,6 +43,7 @@ const goToHostnameStep = async () => {
const goToReviewStep = async () => {
await clickNext(); // Kernel
await clickNext(); // Firewall
await clickNext(); // Services
await clickNext(); // First boot script
await clickNext(); // Details
await enterBlueprintName();

View file

@ -141,6 +141,7 @@ const goToReviewStep = async () => {
await clickNext(); // Hostname
await clickNext(); // Kernel
await clickNext(); // Firewall
await clickNext(); // Services
await clickNext(); // First boot
await clickNext(); // Details
await enterBlueprintName();

View file

@ -41,6 +41,7 @@ const goToKernelStep = async () => {
const goToReviewStep = async () => {
await clickNext(); // Firewall
await clickNext(); // Services
await clickNext(); // First boot script
await clickNext(); // Details
await enterBlueprintName();

View file

@ -42,6 +42,7 @@ const goToReviewStep = async () => {
await clickNext(); // Hostname
await clickNext(); // Kernel
await clickNext(); // Firewall
await clickNext(); // Services
await clickNext(); // First boot
await clickNext(); // Details
await enterBlueprintName();

View file

@ -104,6 +104,7 @@ const goToReviewStep = async () => {
await clickNext(); // Hostname
await clickNext(); // Kernel
await clickNext(); // Firewall
await clickNext(); // Services
await clickNext(); // FirstBoot
await clickNext(); // Details
await enterBlueprintName('Oscap test');

View file

@ -58,6 +58,7 @@ const goToReviewStep = async () => {
await clickNext(); // Hostname
await clickNext(); // Kernel
await clickNext(); // Firewall
await clickNext(); // Services
await clickNext(); // First Boot
await clickNext(); // Details
await enterBlueprintName();

View file

@ -101,6 +101,7 @@ const goToReviewStep = async () => {
await clickNext(); // Hostname
await clickNext(); // Kernel
await clickNext(); // Firewall
await clickNext(); // Services
await clickNext(); // Details
await enterBlueprintName();
await clickNext(); // Review

View file

@ -51,6 +51,7 @@ const goToReviewStep = async () => {
await clickNext(); // Hostname
await clickNext(); // Kernel
await clickNext(); // Firewall
await clickNext(); // Services
await clickNext(); // First Boot
await clickNext(); // Details
await enterBlueprintName();

View file

@ -59,6 +59,7 @@ const goToReviewStep = async () => {
await clickNext(); // Hostname
await clickNext(); // Kernel
await clickNext(); // Firewall
await clickNext(); // Services
await clickNext(); // First boot script
await clickNext(); // Details
await clickNext(); // Review

View file

@ -0,0 +1,67 @@
import type { Router as RemixRouter } from '@remix-run/router';
import { screen, waitFor } from '@testing-library/react';
import { userEvent } from '@testing-library/user-event';
import {
clickBack,
clickNext,
verifyCancelButton,
} from '../../wizardTestUtils';
import { clickRegisterLater, renderCreateMode } from '../../wizardTestUtils';
let router: RemixRouter | undefined = undefined;
const goToServicesStep = 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
await clickNext(); // Locale
await clickNext(); // Hostname
await clickNext(); // Kernel
await clickNext(); // Firewall
await clickNext(); // Services
};
describe('Step Services', () => {
beforeEach(() => {
vi.clearAllMocks();
router = undefined;
});
test('clicking Next loads First boot script', async () => {
await renderCreateMode();
await goToServicesStep();
await clickNext();
await screen.findByRole('heading', {
name: 'First boot configuration',
});
});
test('clicking Back loads Firewall', async () => {
await renderCreateMode();
await goToServicesStep();
await clickBack();
await screen.findByRole('heading', { name: 'Firewall' });
});
test('clicking Cancel loads landing page', async () => {
await renderCreateMode();
await goToServicesStep();
await verifyCancelButton(router);
});
});
// TO DO 'Services step' -> 'revisit step button on Review works'
// TO DO 'Services request generated correctly'
// TO DO 'Services edit mode'

View file

@ -43,6 +43,7 @@ const goToReviewStep = async () => {
await clickNext(); // Hostname
await clickNext(); // Kernel
await clickNext(); // Firewall
await clickNext(); // Services
await clickNext(); // First boot script
await enterBlueprintName();
await clickNext(); // Review

View file

@ -50,6 +50,7 @@ const goToReview = async () => {
await clickNext(); // Hostname
await clickNext(); // Kernel
await clickNext(); // Firewall
await clickNext(); // Services
await clickNext(); // FirstBoot
await clickNext(); // Details
await enterBlueprintName();

View file

@ -50,6 +50,7 @@ const goToReview = async () => {
await clickNext(); // Hostname
await clickNext(); // Kernel
await clickNext(); // Firewall
await clickNext(); // Services
await clickNext(); // FirstBoot
await clickNext(); // Details
await enterBlueprintName();

View file

@ -45,6 +45,7 @@ const goToReview = async () => {
await clickNext(); // Hostname
await clickNext(); // Kernel
await clickNext(); // Firewall
await clickNext(); // Services
await clickNext(); // FirstBoot
await clickNext(); // Details
await enterBlueprintName();

View file

@ -42,6 +42,7 @@ const goToReviewStep = async () => {
await clickNext(); // Hostname
await clickNext(); // Kernel
await clickNext(); // Firewall
await clickNext(); // Services
await clickNext(); // First boot script
await clickNext(); // Details
await enterBlueprintName();

View file

@ -40,6 +40,7 @@ const goToReviewStep = async () => {
await clickNext(); // Hostname
await clickNext(); // Kernel
await clickNext(); // Firewall
await clickNext(); // Services
await clickNext(); // First boot
await clickNext(); // Details
await enterBlueprintName();

View file

@ -75,6 +75,8 @@ vi.mock('@unleash/proxy-client-react', () => ({
return true;
case 'image-builder.firewall.enabled':
return true;
case 'image-builder.services.enabled':
return true;
case 'edgeParity.image-list':
return true;
case 'image-builder.edge.local-image-table':