---
phase: 05-tech-debt
plan: "00"
type: tdd
wave: 0
depends_on: []
files_modified:
- src/components/wizard/ReviewStep.test.tsx
- src/schemas/registry.test.ts
autonomous: true
requirements:
- TECH-01
- TECH-02
- TECH-03
must_haves:
truths:
- "ReviewStep test suite has failing cases for intune-only rendering"
- "ReviewStep test suite has a failing case for rmm-only rendering"
- "ReviewStep test suite has a failing case for neither-target rendering (only rclone.conf)"
- "ReviewStep test suite has a failing case for Back button dispatching SET_STEP(2)"
- "registry.test.ts accesses BACKEND_REGISTRY entries via .fields — ready for shape change"
artifacts:
- path: "src/components/wizard/ReviewStep.test.tsx"
provides: "Failing test cases for TECH-01 and TECH-02"
contains: "scriptTargets"
- path: "src/schemas/registry.test.ts"
provides: "Updated field access via .fields for TECH-03"
contains: ".fields"
key_links:
- from: "ReviewStep.test.tsx new cases"
to: "ReviewStep.tsx (not yet modified)"
via: "renderWithDeployment helper dispatching SET_DEPLOYMENT"
pattern: "SET_DEPLOYMENT"
---
Write Wave 0 test stubs: failing test cases for TECH-01 (scriptTargets filtering) and TECH-02 (Back button) in ReviewStep.test.tsx, and update registry.test.ts field access to use .fields ahead of the TECH-03 registry shape change.
Purpose: Establish RED state before implementation plans run — per project TDD pattern (Wave 0 stubs before implementation).
Output: Modified ReviewStep.test.tsx with 4 new failing describe blocks, modified registry.test.ts with .fields access.
@C:/Users/SebastienQUEROL/.claude/get-shit-done/workflows/execute-plan.md
@C:/Users/SebastienQUEROL/.claude/get-shit-done/templates/summary.md
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/05-tech-debt/05-CONTEXT.md
@.planning/phases/05-tech-debt/05-RESEARCH.md
From src/store/types.ts:
```typescript
export interface WizardState {
currentStep: number;
remote: { name: string; backendType: BackendType | null; params: Record };
deployment: {
includeInstall: boolean;
configPath: 'machine-wide' | 'user-profile';
scriptTargets: ('intune' | 'rmm')[];
};
}
export type WizardAction =
| { type: 'SET_STEP'; payload: number }
| { type: 'SET_DEPLOYMENT'; payload: Partial }
// ... other actions
export const INITIAL_STATE: WizardState = {
deployment: { scriptTargets: ['intune', 'rmm'], ... },
};
```
From src/store/context.tsx:
```typescript
// WizardProvider does NOT accept initialState — uses INITIAL_STATE hardcoded
export function WizardProvider({ children }: { children: React.ReactNode })
```
From src/schemas/registry.ts (CURRENT shape — will change in Plan 01):
```typescript
export const BACKEND_REGISTRY: Record = { ... }
// After TECH-03 it becomes: Record
```
Task 1: Add TECH-01 and TECH-02 failing test cases to ReviewStep.test.tsx
src/components/wizard/ReviewStep.test.tsx
- TECH-01-a: When scriptTargets is ['intune'] only, Intune Install and Intune Detection OutputBlocks are present, RMM Script OutputBlock is absent
- TECH-01-b: When scriptTargets is ['rmm'] only, RMM Script OutputBlock is present, Intune blocks are absent
- TECH-01-c: When scriptTargets is [], only rclone.conf OutputBlock is shown (no intune or rmm blocks)
- TECH-01-d: When scriptTargets is [], ZIP download button calls downloadZip with only 1 file (rclone.conf)
- TECH-02: Back button is present in rendered output and clicking it dispatches SET_STEP(2) (verify via step change — component navigates away or via mock)
Add a `renderWithDeployment` helper at the top of the test file (after existing `renderStep`) that wraps in WizardProvider and dispatches SET_DEPLOYMENT before assertions. Pattern: render with WizardProvider, use `act(() => dispatch({ type: 'SET_DEPLOYMENT', payload: { scriptTargets: [...] } }))` via a TestHelper component that receives a dispatch ref, OR use a wrapper component that accepts a prop and dispatches in useEffect.
Preferred approach (no code changes to production): create a `WizardConsumerSetup` React component inside the test file that calls `dispatch(SET_DEPLOYMENT)` in a `useEffect` on mount, then renders children. Wrap ReviewStep with it in renderWithDeployment.
Add these new describe blocks (append to existing file — do NOT remove any existing tests):
- describe('TECH-01: scriptTargets filtering', ...) with 4 it() cases covering intune-only, rmm-only, neither, and ZIP-neither
- describe('TECH-02: Back button navigation', ...) with 1 it() case verifying button labeled 'Back' renders
These tests MUST FAIL (RED state) because ReviewStep not yet modified. Confirm by running the test suite and seeing failures on the new cases.
Note: ZIP-neither test — mock downloadZip is already set up in beforeEach. The test clicks the ZIP button with scriptTargets=[] and asserts files array has length 1.
Note: TECH-02 Back button test — check `screen.getByRole('button', { name: /back/i })` renders. The navigation itself (SET_STEP dispatch) is trivially verifiable by asserting the button exists and is not disabled (dispatch correctness verified by ReviewStep implementation, not mocked here).
cd /c/Users/SebastienQUEROL/Documents/projets/Ready2Blob && npx vitest run src/components/wizard/ReviewStep.test.tsx 2>&1 | tail -20
Existing ReviewStep tests still pass (CONF-02, CONF-03, DOWN-01 through DOWN-06, SECU-01, SECU-02).
New TECH-01 and TECH-02 test cases exist in the file and fail (RED state — ReviewStep not yet modified).
Task 2: Update registry.test.ts field access to use .fields
src/schemas/registry.test.ts
Update registry.test.ts to access fields via `.fields` in preparation for the TECH-03 shape change. The current registry shape is `FieldDef[]` directly — these tests will break after Plan 01 enriches the shape. Update them now so they are ready.
Changes needed (per RESEARCH.md pitfall 2):
- Line 15: `BACKEND_REGISTRY[backend].length` → `BACKEND_REGISTRY[backend].fields.length`
- Line 21: `for (const field of BACKEND_REGISTRY[backend])` → `for (const field of BACKEND_REGISTRY[backend].fields)`
- Line 38: `BACKEND_REGISTRY.azureblob.find(f => f.key === 'account')` → `BACKEND_REGISTRY.azureblob.fields.find(f => f.key === 'account')`
- Line 44: `BACKEND_REGISTRY.s3.map(f => f.key)` → `BACKEND_REGISTRY.s3.fields.map(f => f.key)`
- Line 51: `BACKEND_REGISTRY['s3-compatible'].find(f => f.key === 'endpoint')` → `BACKEND_REGISTRY['s3-compatible'].fields.find(f => f.key === 'endpoint')`
These changes will make registry.test.ts FAIL (RED state) because registry.ts still has the old `FieldDef[]` shape. That's expected — Plan 01 fixes the production code to green.
Also add a new test case verifying the enriched shape structure (will also be RED until Plan 01):
```
it('each backend entry has displayName and description metadata', () => {
for (const backend of EXPECTED_BACKENDS) {
expect(BACKEND_REGISTRY[backend].displayName).toBeTruthy();
expect(BACKEND_REGISTRY[backend].description).toBeTruthy();
}
});
```
cd /c/Users/SebastienQUEROL/Documents/projets/Ready2Blob && npx vitest run src/schemas/registry.test.ts 2>&1 | tail -15
registry.test.ts uses .fields access throughout.
Test suite shows failures on the registry tests (RED — registry shape not yet enriched). TypeScript may show type errors — that is expected and correct until Plan 01 runs.
Run full suite to confirm scope of RED state:
```
cd /c/Users/SebastienQUEROL/Documents/projets/Ready2Blob && npx vitest run 2>&1 | tail -20
```
Expected: existing passing tests still pass, only new TECH-01/TECH-02/TECH-03 stubs fail.
- ReviewStep.test.tsx has new failing test cases for TECH-01 (intune-only, rmm-only, neither, ZIP-neither) and TECH-02 (Back button present)
- registry.test.ts uses .fields access throughout and has a new displayName/description test case
- All pre-existing tests (CONF-02, CONF-03, DOWN-01–DOWN-06, SECU-01, SECU-02, WIZD-01, WIZD-04, all registry tests that existed) remain green or show the expected RED only on the new .fields lines