File: components/DraftReview.test.tsx
- Lines: 444
- Test Cases: 56 (all failing)
- Status: Ready for implementation
npm test -- components/DraftReview.test.tsxExpected output: 56 failing tests (component doesn't exist)
# Create new file
touch components/DraftReview.tsxinterface DraftReviewProps {
draft: {
id: string;
originalEmail: {
id: string;
from: string;
subject: string;
date: Date;
body?: string;
priority: 'high' | 'low' | 'medium' | 'normal';
};
draftContent: string;
priority: 'high' | 'low' | 'medium' | 'normal';
confidence: number; // 0-1
status: 'pending' | 'processing' | 'approved' | 'rejected';
};
onApprove: (draftId: string) => void;
onReject: (draftId: string) => void;
onSave: (draftId: string, content: string) => void;
isLoading?: boolean;
error?: string;
}
export function DraftReview(props: DraftReviewProps): ReactNode- Render main container with
data-testid="draft-review-container" - Display original email subject (from
draft.originalEmail.subject) - Display original email sender (from
draft.originalEmail.from) - Display draft content (from
draft.draftContent) - Show section headers ("Original Email", "AI-Generated Reply")
- Import and use existing
PriorityBadgecomponent
- Add confidence badge showing
Math.round(draft.confidence * 100)% - Use
PriorityBadgefor priority display - Add
data-testid="confidence-badge"to confidence display - Add
data-testid="priority-badge"(via PriorityBadge)
- Create action buttons section with
data-testid="action-buttons" - Render "Approve" button
- Render "Reject" button
- Render "Edit" button
- Wire up onClick handlers
- Call
onApprove(draft.id)when approve clicked - Call
onReject(draft.id)when reject clicked - Toggle edit mode when edit clicked
- Add local state for edit mode toggle
- Show textarea in edit mode with current draft content
- Add "Save" button in edit mode
- Add "Cancel" button in edit mode
- Call
onSave(draft.id, editedContent)on save - Exit edit mode on save or cancel
- Preserve original content if cancel clicked
- Accept
isLoadingprop - Show loading indicator when
isLoading={true} - Add
data-testid="draft-review-loading"to loader - Add
aria-busy="true"to loading element - Disable all action buttons during loading
- Accept
errorprop (optional string) - Display error message when provided
- Add
data-testid="draft-review-error"to error element - Add
role="alert"to error element - Disable action buttons in error state
- Add
data-testid="original-email-body"to email body display - Add
data-testid="draft-content"to draft content display
- Use existing project's Tailwind classes
- Match styling from
PriorityBadgeandEmailCardcomponents - Ensure responsive design
- Use consistent spacing and colors
- Use semantic HTML (h2 for headers)
- Proper button labels
- ARIA attributes for loading/error states
- Keyboard navigation support
- Form controls properly labeled
npm test -- --watch components/DraftReview.test.tsx# Just rendering tests
npm test -- components/DraftReview.test.tsx -t "Rendering"
# Just interactions
npm test -- components/DraftReview.test.tsx -t "Interactions"
# Just edit mode
npm test -- components/DraftReview.test.tsx -t "Edit Mode"// Located: components/PriorityBadge.tsx
import { PriorityBadge } from './PriorityBadge';
<PriorityBadge priority="high" />Outputs: Badge with emoji, label, and color coding
// Located: components/EmailCard.tsx
// Good example of:
// - Proper data-testid naming
// - Tailwind styling patterns
// - Using existing components- Basic structure → All rendering tests pass
- Priority & confidence → Rendering tests pass
- Buttons & handlers → Interaction tests pass
- Edit mode state → Edit mode tests pass
- Loading state → State tests pass
- Error handling → Error tests pass
- Edge cases → Edge case tests pass
- Accessibility → Accessibility tests pass
| Step | Expected Passing | Expected Failing |
|---|---|---|
| Start | 0/56 | 56 |
| After basic render | 10/56 | 46 |
| After buttons wired | 13/56 | 43 |
| After edit mode | 20/56 | 36 |
| After loading | 24/56 | 32 |
| After error handling | 28/56 | 28 |
| Final (complete) | 56/56 | 0 |
- Start small: Get rendering tests passing first
- Use the test file as spec: Every test describes exact behavior
- Copy patterns: Look at
EmailCardandPriorityBadgefor style/structure - Test data is in tests: Use
mockDraftDataandmockOriginalEmailto understand expected structure - Data-testid is your friend: The test file specifies all required IDs
{isLoading && <div data-testid="draft-review-loading">...</div>}
{error && <div data-testid="draft-review-error" role="alert">...</div>}
{isEditMode && <textarea />}const handleApprove = () => onApprove(draft.id);
const handleSave = () => onSave(draft.id, editedContent);const confidencePercent = Math.round(draft.confidence * 100);
// Display: "87%"If a test seems unclear:
- Read the test case in
DraftReview.test.tsx - Look at the mock data to understand expected structure
- Check the Rendering section to see what's expected
- Reference existing components (PriorityBadge, EmailCard)
Once all tests pass, the component is ready for:
- Integration with Convex data layer
- API endpoint wiring
- Production deployment
- Further refinement in REFACTOR phase