describe('API CRUD Operations', () => { const uid = () => 'cy_' + Date.now().toString(36) + Math.random().toString(36).slice(2, 6) // ---- Notes ---- it('POST /api/notes creates a note', () => { const id = uid() cy.request('POST', '/api/notes', { id, text: 'E2E test note', tag: '灵感' }).then(res => { expect(res.status).to.eq(200) expect(res.body.ok).to.be.true }) }) it('DELETE /api/notes/:id deletes a note', () => { const id = uid() cy.request('POST', '/api/notes', { id, text: 'to delete', tag: '灵感' }) cy.request('DELETE', `/api/notes/${id}`).then(res => { expect(res.status).to.eq(200) }) }) // ---- Todos ---- it('POST /api/todos creates a todo', () => { const id = uid() cy.request('POST', '/api/todos', { id, text: 'E2E todo', quadrant: 'q1', done: 0 }).then(res => { expect(res.body.ok).to.be.true }) }) it('POST /api/todos updates a todo (upsert)', () => { const id = uid() cy.request('POST', '/api/todos', { id, text: 'before', quadrant: 'q1', done: 0 }) cy.request('POST', '/api/todos', { id, text: 'after', quadrant: 'q2', done: 1 }).then(res => { expect(res.body.ok).to.be.true }) cy.request('/api/todos').then(res => { const todo = res.body.find(t => t.id === id) expect(todo.text).to.eq('after') expect(todo.quadrant).to.eq('q2') expect(todo.done).to.eq(1) }) }) it('DELETE /api/todos/:id deletes a todo', () => { const id = uid() cy.request('POST', '/api/todos', { id, text: 'to delete', quadrant: 'q1', done: 0 }) cy.request('DELETE', `/api/todos/${id}`).then(res => { expect(res.status).to.eq(200) }) }) // ---- Inbox ---- it('POST /api/inbox creates inbox item', () => { const id = uid() cy.request('POST', '/api/inbox', { id, text: 'inbox test' }).then(res => { expect(res.body.ok).to.be.true }) }) it('DELETE /api/inbox clears all inbox', () => { cy.request('DELETE', '/api/inbox').then(res => { expect(res.body.ok).to.be.true }) cy.request('/api/inbox').then(res => { expect(res.body).to.have.length(0) }) }) // ---- Reminders ---- it('POST /api/reminders creates a reminder', () => { const id = uid() cy.request('POST', '/api/reminders', { id, text: 'test reminder', time: '09:00', repeat: 'daily', enabled: 1 }).then(res => { expect(res.body.ok).to.be.true }) }) it('DELETE /api/reminders/:id deletes a reminder', () => { const id = uid() cy.request('POST', '/api/reminders', { id, text: 'to delete', repeat: 'none', enabled: 1 }) cy.request('DELETE', `/api/reminders/${id}`).then(res => { expect(res.status).to.eq(200) }) }) // ---- Goals ---- it('POST /api/goals creates and updates a goal', () => { const id = uid() cy.request('POST', '/api/goals', { id, name: 'test goal', month: '2026-06', checks: '{}' }).then(res => { expect(res.body.ok).to.be.true }) cy.request('POST', '/api/goals', { id, name: 'updated goal', month: '2026-07', checks: '{"2026-07-01":true}' }) cy.request('/api/goals').then(res => { const goal = res.body.find(g => g.id === id) expect(goal.name).to.eq('updated goal') }) }) // ---- Checklists ---- it('POST /api/checklists creates a checklist', () => { const id = uid() cy.request('POST', '/api/checklists', { id, title: 'test list', items: '[]', archived: 0 }).then(res => { expect(res.body.ok).to.be.true }) }) // ---- Sleep ---- it('POST /api/sleep creates a record', () => { cy.request('POST', '/api/sleep', { date: '2026-01-01', time: '22:30' }).then(res => { expect(res.body.ok).to.be.true }) }) it('POST /api/sleep upserts on same date', () => { cy.request('POST', '/api/sleep', { date: '2026-01-02', time: '22:00' }) cy.request('POST', '/api/sleep', { date: '2026-01-02', time: '23:00' }) cy.request('/api/sleep').then(res => { const rec = res.body.find(r => r.date === '2026-01-02') expect(rec.time).to.eq('23:00') }) }) it('DELETE /api/sleep/:date deletes a record', () => { cy.request('POST', '/api/sleep', { date: '2026-01-03', time: '21:00' }) cy.request('DELETE', '/api/sleep/2026-01-03').then(res => { expect(res.status).to.eq(200) }) }) // ---- Gym ---- it('POST /api/gym creates a record', () => { const id = uid() cy.request('POST', '/api/gym', { id, date: '2026-04-07', type: '跑步', duration: '30min', note: '5km' }).then(res => { expect(res.body.ok).to.be.true }) }) // ---- Period ---- it('POST /api/period creates a record', () => { const id = uid() cy.request('POST', '/api/period', { id, start_date: '2026-04-01', end_date: '2026-04-05', note: '' }).then(res => { expect(res.body.ok).to.be.true }) }) // ---- Docs ---- it('POST /api/docs creates a doc', () => { const id = uid() cy.request('POST', '/api/docs', { id, name: 'test doc', icon: '📖', keywords: 'test', extract_rule: 'none' }).then(res => { expect(res.body.ok).to.be.true }) }) it('POST /api/doc-entries creates an entry', () => { const docId = uid() const entryId = uid() cy.request('POST', '/api/docs', { id: docId, name: 'doc for entry', icon: '📄', keywords: '', extract_rule: 'none' }) cy.request('POST', '/api/doc-entries', { id: entryId, doc_id: docId, text: 'entry text' }).then(res => { expect(res.body.ok).to.be.true }) cy.request('/api/docs').then(res => { const doc = res.body.find(d => d.id === docId) expect(doc.entries).to.have.length(1) expect(doc.entries[0].text).to.eq('entry text') }) }) // ---- Bugs ---- it('POST /api/bugs creates a bug', () => { const id = uid() cy.request('POST', '/api/bugs', { id, text: 'test bug', status: 'open' }).then(res => { expect(res.body.ok).to.be.true }) }) it('DELETE /api/bugs/:id deletes a bug', () => { const id = uid() cy.request('POST', '/api/bugs', { id, text: 'to delete', status: 'open' }) cy.request('DELETE', `/api/bugs/${id}`).then(res => { expect(res.status).to.eq(200) }) }) // ---- Schedule ---- it('POST /api/schedule-modules creates a module', () => { const id = uid() cy.request('POST', '/api/schedule-modules', { id, name: 'work', emoji: '💼', color: '#667eea', sort_order: 0 }).then(res => { expect(res.body.ok).to.be.true }) }) it('POST /api/schedule-slots creates a slot', () => { const modId = uid() cy.request('POST', '/api/schedule-modules', { id: modId, name: 'slot test', emoji: '📌', color: '#333', sort_order: 0 }) cy.request('POST', '/api/schedule-slots', { date: '2026-04-07', time_slot: '09:00', module_id: modId }).then(res => { expect(res.body.ok).to.be.true }) }) // ---- Reviews ---- it('POST /api/reviews creates a review', () => { cy.request('POST', '/api/reviews', { week: '2026-W15', data: '{"wins":"test"}' }).then(res => { expect(res.body.ok).to.be.true }) }) // ---- Health check-in ---- it('POST /api/health-items creates an item', () => { const id = uid() cy.request('POST', '/api/health-items', { id, name: 'vitamin C', type: 'health' }).then(res => { expect(res.body.ok).to.be.true }) }) it('POST /api/health-plans saves a plan', () => { cy.request('POST', '/api/health-plans', { month: '2026-04', type: 'health', item_ids: '["item1"]' }).then(res => { expect(res.body.ok).to.be.true }) }) it('POST /api/health-checks toggles a check', () => { cy.request('POST', '/api/health-checks', { date: '2026-04-07', type: 'health', item_id: 'item1', checked: 1 }).then(res => { expect(res.body.ok).to.be.true }) }) // ---- Backup ---- it('POST /api/backup triggers backup', () => { cy.request('POST', '/api/backup').then(res => { expect(res.body.ok).to.be.true }) }) })