fix: unify task detail saving
This commit is contained in:
+31
-10
@@ -275,11 +275,12 @@ describe('completion feedback motion', () => {
|
||||
expect(authBlock.indexOf("await syncBrowserTimezone(data.user?.timezone)")).toBeLessThan(authBlock.indexOf('await loadRestoredView()'))
|
||||
})
|
||||
|
||||
it('saves due removal atomically without deleting recurrence a second time', () => {
|
||||
const saveTaskBlock = app.slice(app.indexOf('async function saveTask()'), app.indexOf('async function removeTask('))
|
||||
expect(saveTaskBlock).not.toContain("method: 'DELETE'")
|
||||
expect(saveTaskBlock).toContain('selectedTaskRecurrence.value = null')
|
||||
expect(saveTaskBlock).toContain("selectedTaskRepeat.value = 'none'")
|
||||
it('relies on the task PATCH for atomic due and recurrence synchronization', () => {
|
||||
const saveTaskBlock = app.slice(app.indexOf('async function saveTask('), app.indexOf('async function saveSelectedTaskChanges('))
|
||||
expect(saveTaskBlock).not.toContain('/recurrences/')
|
||||
expect(saveTaskBlock).toContain('as Partial<Task>, false')
|
||||
const unifiedSaveBlock = app.slice(app.indexOf('async function saveSelectedTaskChanges('), app.indexOf('async function removeTask('))
|
||||
expect(unifiedSaveBlock).toContain('const repeatRecurrence = taskSaved.due_at ? recurrence : null')
|
||||
})
|
||||
|
||||
it('keeps all task composer touch controls at least 44px on mobile without horizontal overflow', () => {
|
||||
@@ -739,8 +740,8 @@ describe('task and habit row decoration', () => {
|
||||
})
|
||||
|
||||
it('reclassifies Today tasks after due edits without toggling page loading', () => {
|
||||
const saveBlock = app.slice(app.indexOf('async function saveTask()'), app.indexOf('async function removeTask'))
|
||||
const refreshBlock = app.slice(app.indexOf('async function refreshTodayAfterTaskSave()'), app.indexOf('async function saveTask()'))
|
||||
const saveBlock = app.slice(app.indexOf('async function saveTask('), app.indexOf('async function removeTask'))
|
||||
const refreshBlock = app.slice(app.indexOf('async function refreshTodayAfterTaskSave()'), app.indexOf('async function saveTask('))
|
||||
expect(saveBlock).toContain('await refreshTodayAfterTaskSave()')
|
||||
expect(refreshBlock).toContain('loadTasksPage(request)')
|
||||
expect(refreshBlock).toContain('loadOverdueTasks(request)')
|
||||
@@ -966,13 +967,33 @@ describe('unified floating add interaction', () => {
|
||||
expect(app).toContain('完成后 <input v-model="selectedAfterCompletionDays"')
|
||||
expect(app).toContain('每次完成后,将截止时间顺延对应天数;首版永不结束')
|
||||
expect(app).toContain('buildTaskRecurrencePayload(composeRepeat.value')
|
||||
expect(app).toContain('buildTaskRecurrencePayload(value, { afterCompletionDays: selectedAfterCompletionDays.value')
|
||||
expect(app).toContain('buildTaskRecurrencePayload(value, { afterCompletionDays, repeatConfig: config })')
|
||||
expect(app).toContain("api(`/tasks/${task.id}/recurrence`)")
|
||||
const createBlock = app.slice(app.indexOf('async function submitTaskCompose()'), app.indexOf('function toggleSidebar()'))
|
||||
expect(createBlock).toContain("api('/tasks',")
|
||||
expect(createBlock).not.toContain("api('/recurrences'")
|
||||
const saveBlock = app.slice(app.indexOf('async function updateSelectedTaskRepeat()'), app.indexOf('async function submitTaskCompose()'))
|
||||
expect(saveBlock).not.toContain('selectedTaskRepeat.value = parseTaskRecurrence')
|
||||
const saveBlock = app.slice(app.indexOf('async function saveSelectedTaskChanges()'), app.indexOf('async function removeTask'))
|
||||
expect(saveBlock).toContain("const taskId = selectedTask.value?.id")
|
||||
expect(saveBlock).toContain('const selectionToken = recurrenceLoadToken')
|
||||
expect(saveBlock).toContain("const repeatValue = selectedTask.value?.due_at ? selectedTaskRepeat.value : 'none'")
|
||||
expect(saveBlock).toContain('structuredClone(selectedRepeatConfig.value)')
|
||||
expect(saveBlock).toContain("const taskSaved = await saveTask({ showSuccess: false, expectedTaskId: taskId, expectedSelectionToken: selectionToken })")
|
||||
expect(saveBlock).toContain("recurrenceLoadToken !== selectionToken")
|
||||
expect(saveBlock).toContain('const repeatRecurrence = taskSaved.due_at ? recurrence : null')
|
||||
expect(saveBlock).toContain('await saveRepeat(taskSaved, repeatValue, repeatConfig, afterCompletionDays, repeatRecurrence)')
|
||||
expect(saveBlock).toContain("selectedRepeatError.value = ''")
|
||||
expect(saveBlock).toContain("selectedRepeatError.value = reason instanceof Error ? reason.message : '保存失败'")
|
||||
expect(saveBlock.indexOf("toast('已保存')")).toBeGreaterThan(saveBlock.indexOf('await saveRepeat(taskSaved, repeatValue, repeatConfig, afterCompletionDays, repeatRecurrence)'))
|
||||
expect(saveBlock).toContain('if (savingSelectedTask.value || recurrenceLoading.value) return')
|
||||
expect(saveBlock).toContain('savingSelectedTask.value = true')
|
||||
expect(saveBlock).toContain('savingSelectedTask.value = false')
|
||||
expect(saveBlock).toContain("const repeatValue = selectedTask.value?.due_at ? selectedTaskRepeat.value : 'none'")
|
||||
expect(app).toContain(':disabled="savingSelectedTask || recurrenceLoading" @click="saveSelectedTaskChanges"')
|
||||
expect(app).not.toContain('@blur="saveTask()"')
|
||||
expect(app).not.toContain('@change="saveTask()"')
|
||||
expect(app).not.toContain('value;saveTask()')
|
||||
expect(app).not.toContain('async function updateSelectedTaskRepeat()')
|
||||
expect(app).not.toContain('保存重复设置')
|
||||
expect(css).toContain('.after-completion-fields input{width:76px;min-height:44px')
|
||||
expect(app).toContain('<option value="custom">自定义…</option>')
|
||||
expect(app).toContain('class="repeat-custom-fields"')
|
||||
|
||||
Reference in New Issue
Block a user