docs(17): create phase plan for Jest unit tests

Phase 17: Unit Tests (Jest)
- 1 plan in 1 wave
- 1 parallel, 0 sequential
- Covers UNIT-01, UNIT-02, UNIT-03 requirements
- Ready for execution

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Nuwan 2026-02-08 12:15:30 +05:30
parent c5600e9315
commit 44cc57ad85
1 changed files with 325 additions and 0 deletions

View File

@ -0,0 +1,325 @@
---
phase: 17-unit-tests-jest
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
- jam-ui/src/components/client/__tests__/JKSessionSettingsModal.test.js
autonomous: true
must_haves:
truths:
- "Test file exists and runs without errors"
- "UNIT-01: Test verifies modal renders with currentSession props (privacy, description displayed)"
- "UNIT-02: Test verifies save button calls onSave with correctly transformed payload"
- "UNIT-03: Test verifies loading state disables form interactions"
- "All tests pass with npm run test:unit"
artifacts:
- path: "jam-ui/src/components/client/__tests__/JKSessionSettingsModal.test.js"
provides: "Jest unit tests for JKSessionSettingsModal component"
min_lines: 80
contains: "describe('JKSessionSettingsModal'"
key_links:
- from: "JKSessionSettingsModal.test.js"
to: "JKSessionSettingsModal.js"
via: "import"
pattern: "import JKSessionSettingsModal from"
- from: "JKSessionSettingsModal.test.js"
to: "globals.js"
via: "import SESSION_PRIVACY_MAP"
pattern: "SESSION_PRIVACY_MAP"
---
<objective>
Create Jest unit tests for JKSessionSettingsModal component covering all three requirements: rendering with props, save payload transformation, and loading state behavior.
Purpose: Enable confident changes to Session Settings modal by having automated test coverage for critical paths
Output: Test file with passing tests for UNIT-01, UNIT-02, UNIT-03
</objective>
<execution_context>
@/Users/nuwan/.claude/get-shit-done/workflows/execute-plan.md
@/Users/nuwan/.claude/get-shit-done/templates/summary.md
</execution_context>
<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
# Component under test
@jam-ui/src/components/client/JKSessionSettingsModal.js
# Existing test pattern to follow
@jam-ui/src/components/client/chat/__tests__/JKChatMessageList.test.js
# Globals with SESSION_PRIVACY_MAP
@jam-ui/src/helpers/globals.js
</context>
<tasks>
<task type="auto">
<name>Task 1: Create test file with setup and mocks</name>
<files>jam-ui/src/components/client/__tests__/JKSessionSettingsModal.test.js</files>
<action>
Create the __tests__ directory if needed and test file with proper setup:
1. Create directory structure:
- `jam-ui/src/components/client/__tests__/` (may already exist)
2. Set up test file with required imports:
```javascript
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import JKSessionSettingsModal from '../JKSessionSettingsModal';
import { SESSION_PRIVACY_MAP } from '../../../helpers/globals.js';
```
3. Mock react-i18next (required because component uses useTranslation):
```javascript
jest.mock('react-i18next', () => ({
useTranslation: () => ({
t: (key) => {
const translations = {
'new.privacy_opt_public': 'Public',
'new.privacy_opt_private_invite': 'Private (Invite Only)',
'new.privacy_opt_private_approve': 'Private (Approval Required)'
};
return translations[key] || key;
}
})
}));
```
4. Create helper function for rendering component:
```javascript
const renderModal = (props = {}) => {
const defaultProps = {
isOpen: true,
toggle: jest.fn(),
currentSession: {
privacy: SESSION_PRIVACY_MAP.private_approve,
description: 'Test session description'
},
onSave: jest.fn(),
loading: false
};
return render(<JKSessionSettingsModal {...defaultProps} {...props} />);
};
```
5. Add describe block shell:
```javascript
describe('JKSessionSettingsModal', () => {
// Tests will be added in next task
});
```
</action>
<verify>
File exists at jam-ui/src/components/client/__tests__/JKSessionSettingsModal.test.js
File compiles without syntax errors: `cd jam-ui && npm run test:unit -- --testPathPattern=JKSessionSettingsModal --passWithNoTests`
</verify>
<done>Test file created with all setup code, mocks, and helper functions in place</done>
</task>
<task type="auto">
<name>Task 2: Write tests for all three requirements</name>
<files>jam-ui/src/components/client/__tests__/JKSessionSettingsModal.test.js</files>
<action>
Add test cases inside the describe block for each requirement:
**UNIT-01: Modal renders with currentSession props**
```javascript
describe('rendering with currentSession props (UNIT-01)', () => {
test('displays privacy value from currentSession', () => {
renderModal({
currentSession: {
privacy: SESSION_PRIVACY_MAP.public,
description: ''
}
});
const privacySelect = screen.getByTestId('session-privacy');
expect(privacySelect.value).toBe(String(SESSION_PRIVACY_MAP.public));
});
test('displays description value from currentSession', () => {
const testDescription = 'My test session description';
renderModal({
currentSession: {
privacy: SESSION_PRIVACY_MAP.private_approve,
description: testDescription
}
});
const descriptionInput = screen.getByRole('textbox');
expect(descriptionInput.value).toBe(testDescription);
});
test('renders modal title', () => {
renderModal();
expect(screen.getByText('Session Settings')).toBeInTheDocument();
});
});
```
**UNIT-02: Save button calls onSave with correct payload**
```javascript
describe('save functionality (UNIT-02)', () => {
test('calls onSave with privacy and description when save clicked', () => {
const mockOnSave = jest.fn();
renderModal({
currentSession: {
privacy: SESSION_PRIVACY_MAP.public,
description: 'Original description'
},
onSave: mockOnSave
});
const saveButton = screen.getByRole('button', { name: /save/i });
fireEvent.click(saveButton);
expect(mockOnSave).toHaveBeenCalledTimes(1);
expect(mockOnSave).toHaveBeenCalledWith({
privacy: String(SESSION_PRIVACY_MAP.public),
description: 'Original description'
});
});
test('calls onSave with updated values after user changes', () => {
const mockOnSave = jest.fn();
renderModal({
currentSession: {
privacy: SESSION_PRIVACY_MAP.private_approve,
description: ''
},
onSave: mockOnSave
});
// Change privacy
const privacySelect = screen.getByTestId('session-privacy');
fireEvent.change(privacySelect, { target: { value: SESSION_PRIVACY_MAP.public } });
// Change description
const descriptionInput = screen.getByRole('textbox');
fireEvent.change(descriptionInput, { target: { value: 'New description' } });
// Click save
const saveButton = screen.getByRole('button', { name: /save/i });
fireEvent.click(saveButton);
expect(mockOnSave).toHaveBeenCalledWith({
privacy: String(SESSION_PRIVACY_MAP.public),
description: 'New description'
});
});
});
```
**UNIT-03: Loading state disables form interactions**
```javascript
describe('loading state (UNIT-03)', () => {
test('disables save button when loading', () => {
renderModal({ loading: true });
const saveButton = screen.getByRole('button', { name: /saving/i });
expect(saveButton).toBeDisabled();
});
test('disables cancel button when loading', () => {
renderModal({ loading: true });
const cancelButton = screen.getByRole('button', { name: /cancel/i });
expect(cancelButton).toBeDisabled();
});
test('disables description textarea when loading', () => {
renderModal({ loading: true });
const descriptionInput = screen.getByRole('textbox');
expect(descriptionInput).toBeDisabled();
});
test('shows "Saving..." text on save button when loading', () => {
renderModal({ loading: true });
expect(screen.getByRole('button', { name: /saving/i })).toBeInTheDocument();
});
});
```
Note: The privacy select dropdown is NOT disabled when loading (based on component code review - only description textarea has `disabled={loading}`). The tests reflect actual component behavior.
</action>
<verify>
Run tests: `cd jam-ui && npm run test:unit -- --testPathPattern=JKSessionSettingsModal`
All tests pass (exit code 0)
</verify>
<done>
All three requirements covered with passing tests:
- UNIT-01: 3 tests for rendering (privacy, description, title)
- UNIT-02: 2 tests for save functionality (initial values, updated values)
- UNIT-03: 4 tests for loading state (save disabled, cancel disabled, textarea disabled, button text)
</done>
</task>
<task type="auto">
<name>Task 3: Verify full test suite and clean up</name>
<files>jam-ui/src/components/client/__tests__/JKSessionSettingsModal.test.js</files>
<action>
1. Run full unit test suite to ensure no regressions:
```bash
cd jam-ui && npm run test:unit
```
2. Verify test count matches expectations (9 tests total: 3 + 2 + 4)
3. Check test output shows all test names correctly grouped:
- JKSessionSettingsModal
- rendering with currentSession props (UNIT-01)
- save functionality (UNIT-02)
- loading state (UNIT-03)
4. If any tests fail, debug and fix:
- Check if component behavior differs from expectations
- Adjust test assertions to match actual component behavior
- Do NOT modify the component - only fix test expectations
5. Add any missing edge case tests if time permits:
- Empty description handling
- Default privacy value when currentSession.privacy is undefined
</action>
<verify>
`cd jam-ui && npm run test:unit` passes with 0 failures
Test file has proper structure with requirement labels in describe blocks
</verify>
<done>
All unit tests pass, test file is complete and properly structured with requirement traceability (UNIT-01, UNIT-02, UNIT-03)
</done>
</task>
</tasks>
<verification>
1. Test file exists: `ls jam-ui/src/components/client/__tests__/JKSessionSettingsModal.test.js`
2. All tests pass: `cd jam-ui && npm run test:unit -- --testPathPattern=JKSessionSettingsModal`
3. Full unit test suite passes: `cd jam-ui && npm run test:unit`
4. Requirement coverage:
- UNIT-01: Tests in "rendering with currentSession props" describe block
- UNIT-02: Tests in "save functionality" describe block
- UNIT-03: Tests in "loading state" describe block
</verification>
<success_criteria>
1. Test file exists at `jam-ui/src/components/client/__tests__/JKSessionSettingsModal.test.js`
2. UNIT-01 covered: Tests verify privacy and description from currentSession are displayed
3. UNIT-02 covered: Tests verify onSave called with correct payload on save click
4. UNIT-03 covered: Tests verify loading state disables save button, cancel button, and description input
5. All tests pass with `npm run test:unit`
6. No regressions in existing test suite
</success_criteria>
<output>
After completion, create `.planning/phases/17-unit-tests-jest/17-01-SUMMARY.md`
</output>