test(05-00): add failing TECH-01 and TECH-02 test cases to ReviewStep.test.tsx

- Add WizardConsumerSetup helper to dispatch SET_DEPLOYMENT in tests
- Add renderWithDeployment helper for scriptTargets-specific rendering
- Add TECH-01-a: intune-only — Intune blocks present, RMM block absent (RED)
- Add TECH-01-b: rmm-only — RMM block present, Intune blocks absent (RED)
- Add TECH-01-c: neither target — only rclone.conf OutputBlock shown (RED)
- Add TECH-01-d: neither target ZIP — downloadZip with 1 file only (RED)
- Add TECH-02: Back button rendered and not disabled (RED)
This commit is contained in:
2026-03-30 09:33:05 +02:00
parent 0a0a51b45a
commit 8c675813c6
+87 -3
View File
@@ -3,11 +3,13 @@
// Covers DOWN-01 through DOWN-06: individual and ZIP download buttons
// Covers SECU-01: download gating behind security checkbox
// Covers SECU-02: privacy/no-server message in rendered output
// Covers TECH-01: scriptTargets filtering in ReviewStep
// Covers TECH-02: Back button navigation in ReviewStep
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import React from 'react';
import { render, screen, fireEvent, act } from '@testing-library/react';
import React, { useEffect } from 'react';
import ReviewStep from './ReviewStep';
import { WizardProvider } from '../../store/context';
import { WizardProvider, useWizard } from '../../store/context';
import { downloadFile } from '../../utils/downloadFile';
import { downloadZip } from '../../utils/downloadZip';
@@ -39,6 +41,33 @@ function renderStep() {
);
}
// Helper component: dispatches SET_DEPLOYMENT on mount so tests can inject
// custom scriptTargets without modifying production code.
function WizardConsumerSetup({
scriptTargets,
children,
}: {
scriptTargets: ('intune' | 'rmm')[];
children: React.ReactNode;
}) {
const { dispatch } = useWizard();
useEffect(() => {
dispatch({ type: 'SET_DEPLOYMENT', payload: { scriptTargets } });
}, []); // eslint-disable-line react-hooks/exhaustive-deps
return <>{children}</>;
}
// Helper: render ReviewStep with a specific scriptTargets value.
function renderWithDeployment(scriptTargets: ('intune' | 'rmm')[]) {
return render(
<WizardProvider>
<WizardConsumerSetup scriptTargets={scriptTargets}>
<ReviewStep />
</WizardConsumerSetup>
</WizardProvider>
);
}
describe('CONF-02: live rclone.conf preview', () => {
it('shows rclone.conf preview text when backendType is set', () => {
renderStep();
@@ -214,3 +243,58 @@ describe('SECU-02: no-server privacy message', () => {
).toBeTruthy();
});
});
describe('TECH-01: scriptTargets filtering', () => {
it('TECH-01-a: intune-only — Intune blocks present, RMM block absent', async () => {
renderWithDeployment(['intune']);
// Allow useEffect to run
await act(async () => {});
// Intune Install and Detection blocks should be present (label text is rendered in OutputBlock)
expect(screen.queryByText(/Intune Install Script/i)).not.toBeNull();
expect(screen.queryByText(/Intune Detection Script/i)).not.toBeNull();
// RMM block should not be rendered
expect(screen.queryByText(/RMM Script/i)).toBeNull();
});
it('TECH-01-b: rmm-only — RMM block present, Intune blocks absent', async () => {
renderWithDeployment(['rmm']);
await act(async () => {});
// RMM block should be present
expect(screen.queryByText(/RMM Script/i)).not.toBeNull();
// Intune blocks should not be rendered
expect(screen.queryByText(/Intune Install Script/i)).toBeNull();
expect(screen.queryByText(/Intune Detection Script/i)).toBeNull();
});
it('TECH-01-c: neither target — only rclone.conf OutputBlock shown', async () => {
renderWithDeployment([]);
await act(async () => {});
// No intune or rmm blocks
expect(screen.queryByText(/Intune Install Script/i)).toBeNull();
expect(screen.queryByText(/Intune Detection Script/i)).toBeNull();
expect(screen.queryByText(/RMM Script/i)).toBeNull();
});
it('TECH-01-d: neither target ZIP — downloadZip called with only rclone.conf (1 file)', async () => {
renderWithDeployment([]);
await act(async () => {});
const checkbox = screen.getByRole('checkbox');
fireEvent.click(checkbox);
const zipButton = screen.getByText('Download All (ZIP)');
fireEvent.click(zipButton);
expect(vi.mocked(downloadZip)).toHaveBeenCalledTimes(1);
const [files] = vi.mocked(downloadZip).mock.calls[0];
expect(files).toHaveLength(1);
expect(files[0].name).toBe('rclone.conf');
});
});
describe('TECH-02: Back button navigation', () => {
it('Back button is rendered and is not disabled', async () => {
renderStep();
await act(async () => {});
const backButton = screen.getByRole('button', { name: /back/i });
expect(backButton).toBeTruthy();
expect((backButton as HTMLButtonElement).disabled).toBe(false);
});
});