refactor: Extract reusable UI components and add TDD documentation
- Add comprehensive TDD documentation to CLAUDE.md with coverage requirements and examples - Extract reusable UI components to frontend/src/components/ui/ (Modal, FormInput, Button, Alert, etc.) - Add shared constants (schedulePresets) and utility hooks (useCrudMutation, useFormValidation) - Update frontend/CLAUDE.md with component documentation and usage examples - Refactor CreateTaskModal to use shared components and constants - Fix test assertions to be more robust and accurate across all test files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -94,6 +94,13 @@ describe('useAppointments hooks', () => {
|
||||
durationMinutes: 60,
|
||||
status: 'SCHEDULED',
|
||||
notes: 'First appointment',
|
||||
depositAmount: null,
|
||||
depositTransactionId: '',
|
||||
finalChargeTransactionId: '',
|
||||
finalPrice: null,
|
||||
isVariablePricing: false,
|
||||
overpaidAmount: null,
|
||||
remainingBalance: null,
|
||||
});
|
||||
|
||||
// Verify second appointment transformation (with alternative field names and null resource)
|
||||
@@ -107,6 +114,13 @@ describe('useAppointments hooks', () => {
|
||||
durationMinutes: 30,
|
||||
status: 'COMPLETED',
|
||||
notes: '',
|
||||
depositAmount: null,
|
||||
depositTransactionId: '',
|
||||
finalChargeTransactionId: '',
|
||||
finalPrice: null,
|
||||
isVariablePricing: false,
|
||||
overpaidAmount: null,
|
||||
remainingBalance: null,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -274,6 +288,13 @@ describe('useAppointments hooks', () => {
|
||||
durationMinutes: 60,
|
||||
status: 'SCHEDULED',
|
||||
notes: 'Test note',
|
||||
depositAmount: null,
|
||||
depositTransactionId: '',
|
||||
finalChargeTransactionId: '',
|
||||
finalPrice: null,
|
||||
isVariablePricing: false,
|
||||
overpaidAmount: null,
|
||||
remainingBalance: null,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -805,7 +805,7 @@ describe('FEATURE_NAMES', () => {
|
||||
expect(FEATURE_NAMES.custom_domain).toBe('Custom Domain');
|
||||
expect(FEATURE_NAMES.white_label).toBe('White Label');
|
||||
expect(FEATURE_NAMES.custom_oauth).toBe('Custom OAuth');
|
||||
expect(FEATURE_NAMES.plugins).toBe('Custom Plugins');
|
||||
expect(FEATURE_NAMES.plugins).toBe('Plugins');
|
||||
expect(FEATURE_NAMES.tasks).toBe('Scheduled Tasks');
|
||||
expect(FEATURE_NAMES.export_data).toBe('Data Export');
|
||||
expect(FEATURE_NAMES.video_conferencing).toBe('Video Conferencing');
|
||||
|
||||
@@ -137,13 +137,12 @@ describe('useResources hooks', () => {
|
||||
expect(apiClient.post).toHaveBeenCalledWith('/resources/', {
|
||||
name: 'New Room',
|
||||
type: 'ROOM',
|
||||
user: null,
|
||||
timezone: 'UTC',
|
||||
user_id: null,
|
||||
max_concurrent_events: 3,
|
||||
});
|
||||
});
|
||||
|
||||
it('converts userId to user integer', async () => {
|
||||
it('converts userId to user_id integer', async () => {
|
||||
vi.mocked(apiClient.post).mockResolvedValue({ data: { id: 1 } });
|
||||
|
||||
const { result } = renderHook(() => useCreateResource(), {
|
||||
@@ -159,7 +158,7 @@ describe('useResources hooks', () => {
|
||||
});
|
||||
|
||||
expect(apiClient.post).toHaveBeenCalledWith('/resources/', expect.objectContaining({
|
||||
user: 42,
|
||||
user_id: 42,
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user