feat: Update user authentication data and enhance routine item handling in RoutineEditView
All checks were successful
Chore App Build, Test, and Push Docker Images / build-and-push (push) Successful in 3m16s

This commit is contained in:
2026-05-18 16:39:05 -04:00
parent 5392e5af70
commit ad8a8bf867
5 changed files with 91 additions and 24 deletions

View File

@@ -372,12 +372,23 @@ async function handleSubmit(form: { name: string; points: number; image_id: stri
})
if (!resp.ok) throw new Error('Failed to save routine')
const routineData = await resp.json()
const routineId = routineData.id || props.id
const routineId =
props.id ||
(typeof routineData?.id === 'string' && routineData.id) ||
(typeof routineData?.routine?.id === 'string' && routineData.routine.id) ||
''
if (!routineId) {
throw new Error('Failed to resolve routine id after save')
}
for (const itemId of removedItemIds.value) {
await fetch(`/api/routine/${routineId}/item/${itemId}`, {
const deleteResp = await fetch(`/api/routine/${routineId}/item/${itemId}`, {
method: 'DELETE',
})
if (!deleteResp.ok) {
throw new Error('Failed to delete routine item')
}
}
for (const item of items.value) {
@@ -385,17 +396,23 @@ async function handleSubmit(form: { name: string; points: number; image_id: stri
const payload = { name: item.name, image_id: resolvedImageId, order: item.order }
if (item.id?.startsWith('temp-') || !item.id) {
await fetch(`/api/routine/${routineId}/item/add`, {
const addItemResp = await fetch(`/api/routine/${routineId}/item/add`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
})
if (!addItemResp.ok) {
throw new Error('Failed to add routine item')
}
} else {
await fetch(`/api/routine/${routineId}/item/${item.id}/edit`, {
const editItemResp = await fetch(`/api/routine/${routineId}/item/${item.id}/edit`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
})
if (!editItemResp.ok) {
throw new Error('Failed to edit routine item')
}
}
}

View File

@@ -3,13 +3,15 @@ import { defineComponent, nextTick } from 'vue'
import { mount } from '@vue/test-utils'
import RoutineEditView from '../RoutineEditView.vue'
const mockPush = vi.fn()
vi.mock('vue-router', () => ({
useRoute: vi.fn(() => ({
params: {},
query: { name: 'Timmy' },
})),
useRouter: vi.fn(() => ({
push: vi.fn(),
push: mockPush,
back: vi.fn(),
})),
}))
@@ -35,7 +37,7 @@ const EntityEditFormStub = defineComponent({
emits: ['submit', 'cancel', 'add-image'],
template: `
<div class="entity-edit-form-stub">
<button type="submit" class="submit-btn" :disabled="submitDisabled">Submit</button>
<button type="button" class="submit-btn" :disabled="submitDisabled" @click="$emit('submit', { name: 'Morning Routine', points: 5, image_id: null })">Submit</button>
<slot name="before-actions" />
</div>
`,
@@ -49,6 +51,9 @@ const ImagePickerStub = defineComponent({
describe('RoutineEditView', () => {
beforeEach(() => {
vi.clearAllMocks()
globalThis.fetch = vi
.fn()
.mockResolvedValue({ ok: true, json: async () => ({}) }) as typeof fetch
})
it('disables Create when there are no routine tasks', async () => {
@@ -69,4 +74,49 @@ describe('RoutineEditView', () => {
expect((submitButton.element as HTMLButtonElement).disabled).toBe(true)
expect(wrapper.findComponent(EntityEditFormStub).props('submitDisabled')).toBe(true)
})
it('creates routine items using nested routine id from create response', async () => {
const fetchMock = vi.fn<typeof fetch>()
fetchMock
.mockResolvedValueOnce({
ok: true,
json: async () => ({ message: 'Routine added', routine: { id: 'routine-123' } }),
} as Response)
.mockResolvedValueOnce({ ok: true, json: async () => ({ id: 'item-1' }) } as Response)
globalThis.fetch = fetchMock
const wrapper = mount(RoutineEditView, {
props: {},
global: {
stubs: {
EntityEditForm: EntityEditFormStub,
ImagePicker: ImagePickerStub,
},
},
})
await wrapper.find('.add-task-trigger').trigger('click')
await nextTick()
const nameInput = wrapper.find('#item-name')
await nameInput.setValue('Make bed')
await wrapper.find('.item-form-actions .btn.btn-primary').trigger('click')
await nextTick()
await wrapper.find('.submit-btn').trigger('click')
await nextTick()
expect(fetchMock).toHaveBeenNthCalledWith(
1,
'/api/routine/add',
expect.objectContaining({ method: 'PUT' }),
)
expect(fetchMock).toHaveBeenNthCalledWith(
2,
'/api/routine/routine-123/item/add',
expect.objectContaining({ method: 'PUT' }),
)
expect(mockPush).toHaveBeenCalledWith({ name: 'RoutineView' })
})
})