import { describe, it, expect, vi, beforeEach } from 'vitest' vi.mock('../api/client', () => ({ default: { get: vi.fn(), post: vi.fn(), put: vi.fn(), delete: vi.fn(), interceptors: { request: { use: vi.fn() }, response: { use: vi.fn() }, }, }, })) import api from '../api/client' import { tasksApi } from '../api/tasks' import { habitsApi } from '../api/habits' import { savingsApi } from '../api/savings' import { profileApi } from '../api/profile' describe('tasksApi', () => { beforeEach(() => vi.clearAllMocks()) it('should list all tasks', async () => { api.get.mockResolvedValueOnce({ data: [{ id: 1, title: 'Test' }] }) const result = await tasksApi.list() expect(api.get).toHaveBeenCalledWith('tasks') expect(result).toEqual([{ id: 1, title: 'Test' }]) }) it('should list completed tasks', async () => { api.get.mockResolvedValueOnce({ data: [] }) await tasksApi.list(true) expect(api.get).toHaveBeenCalledWith('tasks?completed=true') }) it('should list incomplete tasks', async () => { api.get.mockResolvedValueOnce({ data: [] }) await tasksApi.list(false) expect(api.get).toHaveBeenCalledWith('tasks?completed=false') }) it('should get today tasks', async () => { api.get.mockResolvedValueOnce({ data: [] }) await tasksApi.today() expect(api.get).toHaveBeenCalledWith('tasks/today') }) it('should create a task', async () => { const taskData = { title: 'New Task', priority: 1 } api.post.mockResolvedValueOnce({ data: { id: 1, ...taskData } }) const result = await tasksApi.create(taskData) expect(api.post).toHaveBeenCalledWith('tasks', taskData) expect(result.title).toBe('New Task') }) it('should update a task', async () => { api.put.mockResolvedValueOnce({ data: { id: 1, title: 'Updated' } }) await tasksApi.update(1, { title: 'Updated' }) expect(api.put).toHaveBeenCalledWith('tasks/1', { title: 'Updated' }) }) it('should delete a task', async () => { api.delete.mockResolvedValueOnce({}) await tasksApi.delete(1) expect(api.delete).toHaveBeenCalledWith('tasks/1') }) it('should complete a task', async () => { api.post.mockResolvedValueOnce({ data: { id: 1, completed: true } }) await tasksApi.complete(1) expect(api.post).toHaveBeenCalledWith('tasks/1/complete') }) it('should uncomplete a task', async () => { api.post.mockResolvedValueOnce({ data: { id: 1, completed: false } }) await tasksApi.uncomplete(1) expect(api.post).toHaveBeenCalledWith('tasks/1/uncomplete') }) it('should get a single task', async () => { api.get.mockResolvedValueOnce({ data: { id: 5, title: 'Task 5' } }) const result = await tasksApi.get(5) expect(api.get).toHaveBeenCalledWith('tasks/5') expect(result.id).toBe(5) }) }) describe('habitsApi', () => { beforeEach(() => vi.clearAllMocks()) it('should list habits', async () => { api.get.mockResolvedValueOnce({ data: [{ id: 1, name: 'Exercise' }] }) const result = await habitsApi.list() expect(api.get).toHaveBeenCalledWith('/habits') expect(result).toEqual([{ id: 1, name: 'Exercise' }]) }) it('should create a habit', async () => { api.post.mockResolvedValueOnce({ data: { id: 1, name: 'Read' } }) await habitsApi.create({ name: 'Read' }) expect(api.post).toHaveBeenCalledWith('/habits', { name: 'Read' }) }) it('should update a habit', async () => { api.put.mockResolvedValueOnce({ data: { id: 1, name: 'Updated' } }) await habitsApi.update(1, { name: 'Updated' }) expect(api.put).toHaveBeenCalledWith('/habits/1', { name: 'Updated' }) }) it('should log a habit', async () => { api.post.mockResolvedValueOnce({ data: { id: 1 } }) await habitsApi.log(5, { date: '2025-03-01' }) expect(api.post).toHaveBeenCalledWith('/habits/5/log', { date: '2025-03-01' }) }) it('should log habit with empty data', async () => { api.post.mockResolvedValueOnce({ data: { id: 1 } }) await habitsApi.log(5) expect(api.post).toHaveBeenCalledWith('/habits/5/log', {}) }) it('should get logs with custom days', async () => { api.get.mockResolvedValueOnce({ data: [] }) await habitsApi.getLogs(5, 60) expect(api.get).toHaveBeenCalledWith('/habits/5/logs?days=60') }) it('should get overall stats', async () => { api.get.mockResolvedValueOnce({ data: { total_habits: 5 } }) await habitsApi.getStats() expect(api.get).toHaveBeenCalledWith('/habits/stats') }) it('should get single habit stats', async () => { api.get.mockResolvedValueOnce({ data: { habit_id: 3 } }) await habitsApi.getHabitStats(3) expect(api.get).toHaveBeenCalledWith('/habits/3/stats') }) it('should get freezes', async () => { api.get.mockResolvedValueOnce({ data: [] }) await habitsApi.getFreezes(3) expect(api.get).toHaveBeenCalledWith('/habits/3/freezes') }) it('should add freeze', async () => { const freezeData = { start_date: '2025-03-01', end_date: '2025-03-07' } api.post.mockResolvedValueOnce({ data: { id: 1 } }) await habitsApi.addFreeze(3, freezeData) expect(api.post).toHaveBeenCalledWith('/habits/3/freezes', freezeData) }) it('should delete freeze', async () => { api.delete.mockResolvedValueOnce({}) await habitsApi.deleteFreeze(3, 10) expect(api.delete).toHaveBeenCalledWith('/habits/3/freezes/10') }) it('should delete a habit', async () => { api.delete.mockResolvedValueOnce({}) await habitsApi.delete(5) expect(api.delete).toHaveBeenCalledWith('/habits/5') }) it('should delete a log', async () => { api.delete.mockResolvedValueOnce({}) await habitsApi.deleteLog(3, 7) expect(api.delete).toHaveBeenCalledWith('/habits/3/logs/7') }) }) describe('savingsApi', () => { beforeEach(() => vi.clearAllMocks()) it('should list categories', async () => { api.get.mockResolvedValueOnce({ data: [] }) await savingsApi.listCategories() expect(api.get).toHaveBeenCalledWith('/savings/categories') }) it('should get single category', async () => { api.get.mockResolvedValueOnce({ data: { id: 1 } }) await savingsApi.getCategory(1) expect(api.get).toHaveBeenCalledWith('/savings/categories/1') }) it('should create category', async () => { api.post.mockResolvedValueOnce({ data: { id: 1 } }) await savingsApi.createCategory({ name: 'Savings' }) expect(api.post).toHaveBeenCalledWith('/savings/categories', { name: 'Savings' }) }) it('should update category', async () => { api.put.mockResolvedValueOnce({ data: { id: 1 } }) await savingsApi.updateCategory(1, { name: 'Updated' }) expect(api.put).toHaveBeenCalledWith('/savings/categories/1', { name: 'Updated' }) }) it('should delete category', async () => { api.delete.mockResolvedValueOnce({}) await savingsApi.deleteCategory(1) expect(api.delete).toHaveBeenCalledWith('/savings/categories/1') }) it('should create transaction', async () => { const data = { category_id: 1, amount: 1000, type: 'deposit', date: '2025-03-01' } api.post.mockResolvedValueOnce({ data: { id: 1 } }) await savingsApi.createTransaction(data) expect(api.post).toHaveBeenCalledWith('/savings/transactions', data) }) it('should list transactions with category filter', async () => { api.get.mockResolvedValueOnce({ data: [] }) await savingsApi.listTransactions(5, 50, 10) expect(api.get).toHaveBeenCalledWith('/savings/transactions?limit=50&offset=10&category_id=5') }) it('should list transactions without category filter', async () => { api.get.mockResolvedValueOnce({ data: [] }) await savingsApi.listTransactions(null) expect(api.get).toHaveBeenCalledWith('/savings/transactions?limit=100&offset=0') }) it('should get stats', async () => { api.get.mockResolvedValueOnce({ data: { total_balance: 5000 } }) await savingsApi.getStats() expect(api.get).toHaveBeenCalledWith('/savings/stats') }) it('should get members', async () => { api.get.mockResolvedValueOnce({ data: [] }) await savingsApi.getMembers(1) expect(api.get).toHaveBeenCalledWith('/savings/categories/1/members') }) it('should add member', async () => { api.post.mockResolvedValueOnce({ data: [] }) await savingsApi.addMember(1, 42) expect(api.post).toHaveBeenCalledWith('/savings/categories/1/members', { user_id: 42 }) }) it('should get recurring plans', async () => { api.get.mockResolvedValueOnce({ data: [] }) await savingsApi.getRecurringPlans(1) expect(api.get).toHaveBeenCalledWith('/savings/categories/1/recurring-plans') }) }) describe('profileApi', () => { beforeEach(() => vi.clearAllMocks()) it('should get profile', async () => { api.get.mockResolvedValueOnce({ data: { username: 'test' } }) const result = await profileApi.get() expect(api.get).toHaveBeenCalledWith('/profile') expect(result.username).toBe('test') }) it('should update profile', async () => { api.put.mockResolvedValueOnce({ data: { username: 'updated' } }) const result = await profileApi.update({ username: 'updated' }) expect(api.put).toHaveBeenCalledWith('/profile', { username: 'updated' }) expect(result.username).toBe('updated') }) })