From 8c675813c66705e6a484b7c719a3d8c4d0eb1341 Mon Sep 17 00:00:00 2001 From: Kawa Date: Mon, 30 Mar 2026 09:33:05 +0200 Subject: [PATCH] test(05-00): add failing TECH-01 and TECH-02 test cases to ReviewStep.test.tsx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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) --- src/components/wizard/ReviewStep.test.tsx | 90 ++++++++++++++++++++++- 1 file changed, 87 insertions(+), 3 deletions(-) diff --git a/src/components/wizard/ReviewStep.test.tsx b/src/components/wizard/ReviewStep.test.tsx index fff8316..b50ccbc 100644 --- a/src/components/wizard/ReviewStep.test.tsx +++ b/src/components/wizard/ReviewStep.test.tsx @@ -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( + + + + + + ); +} + 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); + }); +});