feat: Implement routines feature with CRUD operations and child assignment
All checks were successful
Chore App Build, Test, and Push Docker Images / build-and-push (push) Successful in 3m0s
All checks were successful
Chore App Build, Test, and Push Docker Images / build-and-push (push) Successful in 3m0s
- Add backend routines management with add, get, update, delete, and list functionalities. - Create models for Routine, RoutineItem, RoutineSchedule, and RoutineExtension. - Develop event types for routine confirmation and modification. - Implement frontend components for routine assignment, confirmation dialog, and routine management views. - Add unit tests for routine API and integration tests for routine CRUD flow. - Create end-to-end test plan for routines feature covering parent and child interactions.
This commit is contained in:
@@ -2,17 +2,21 @@ import { describe, it, expect, vi, beforeEach } from 'vitest'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { nextTick } from 'vue'
|
||||
import ScheduleModal from '../components/shared/ScheduleModal.vue'
|
||||
import type { ChildTask, ChoreSchedule } from '../common/models'
|
||||
import type { ChildTask, ChoreSchedule, RoutineSchedule } from '../common/models'
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Mocks
|
||||
// ---------------------------------------------------------------------------
|
||||
const mockSetChoreSchedule = vi.fn()
|
||||
const mockDeleteChoreSchedule = vi.fn()
|
||||
const mockSetRoutineSchedule = vi.fn()
|
||||
const mockDeleteRoutineSchedule = vi.fn()
|
||||
|
||||
vi.mock('@/common/api', () => ({
|
||||
setChoreSchedule: (...args: unknown[]) => mockSetChoreSchedule(...args),
|
||||
deleteChoreSchedule: (...args: unknown[]) => mockDeleteChoreSchedule(...args),
|
||||
setRoutineSchedule: (...args: unknown[]) => mockSetRoutineSchedule(...args),
|
||||
deleteRoutineSchedule: (...args: unknown[]) => mockDeleteRoutineSchedule(...args),
|
||||
parseErrorResponse: vi.fn().mockResolvedValue({ msg: 'error', code: 'ERR' }),
|
||||
}))
|
||||
|
||||
@@ -39,9 +43,9 @@ const DateInputFieldStub = {
|
||||
const TASK: ChildTask = { id: 'task-1', name: 'Clean Room', type: 'chore', points: 5, image_id: '' }
|
||||
const CHILD_ID = 'child-1'
|
||||
|
||||
function mountModal(schedule: ChoreSchedule | null = null) {
|
||||
function mountModal(schedule: ChoreSchedule | RoutineSchedule | null = null) {
|
||||
return mount(ScheduleModal, {
|
||||
props: { task: TASK, childId: CHILD_ID, schedule },
|
||||
props: { entity: TASK, entityType: 'task', childId: CHILD_ID, schedule },
|
||||
global: {
|
||||
stubs: {
|
||||
ModalDialog: ModalDialogStub,
|
||||
@@ -55,8 +59,12 @@ function mountModal(schedule: ChoreSchedule | null = null) {
|
||||
beforeEach(() => {
|
||||
mockSetChoreSchedule.mockReset()
|
||||
mockDeleteChoreSchedule.mockReset()
|
||||
mockSetRoutineSchedule.mockReset()
|
||||
mockDeleteRoutineSchedule.mockReset()
|
||||
mockSetChoreSchedule.mockResolvedValue({ ok: true })
|
||||
mockDeleteChoreSchedule.mockResolvedValue({ ok: true })
|
||||
mockSetRoutineSchedule.mockResolvedValue({ ok: true })
|
||||
mockDeleteRoutineSchedule.mockResolvedValue({ ok: true })
|
||||
})
|
||||
// ---------------------------------------------------------------------------
|
||||
// Mode toggle
|
||||
@@ -488,3 +496,39 @@ describe('ScheduleModal backdrop', () => {
|
||||
expect(w.emitted('cancelled')).toBeFalsy()
|
||||
})
|
||||
})
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Entity type routing
|
||||
// ---------------------------------------------------------------------------
|
||||
describe('ScheduleModal entityType routing', () => {
|
||||
it('uses routine schedule API when entityType is routine', async () => {
|
||||
const routineEntity = { ...TASK, id: 'routine-1', items: [] }
|
||||
const w = mount(ScheduleModal, {
|
||||
props: {
|
||||
entity: routineEntity,
|
||||
entityType: 'routine',
|
||||
childId: CHILD_ID,
|
||||
schedule: null,
|
||||
},
|
||||
global: {
|
||||
stubs: {
|
||||
ModalDialog: ModalDialogStub,
|
||||
TimePickerPopover: TimePickerPopoverStub,
|
||||
DateInputField: DateInputFieldStub,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
await w.findAll('.chip')[1].trigger('click')
|
||||
await nextTick()
|
||||
await w.find('.btn-primary').trigger('click')
|
||||
await nextTick()
|
||||
|
||||
expect(mockSetRoutineSchedule).toHaveBeenCalledWith(
|
||||
CHILD_ID,
|
||||
'routine-1',
|
||||
expect.objectContaining({ mode: 'days' }),
|
||||
)
|
||||
expect(mockSetChoreSchedule).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user