import axios from 'axios'; import { HostexApiClient } from '../client/index.js'; jest.mock('axios'); const mockedAxios = axios as jest.Mocked; function makeClient() { const mockInstance = { request: jest.fn(), post: jest.fn(), patch: jest.fn(), delete: jest.fn(), interceptors: { request: { use: jest.fn() }, response: { use: jest.fn() } }, }; mockedAxios.create.mockReturnValue(mockInstance as any); return { client: new HostexApiClient({ accessToken: 'test-token' }), mockInstance }; } describe('HostexApiClient finance dictionaries', () => { it.each([ ['getIncomeItems', '/income_items', { income_items: [{ id: 1, name: 'Rent' }] }], ['getExpenseItems', '/expense_items', { expense_items: [{ id: 2, name: 'Cleaning' }] }], ['getExpenseMethods', '/expense_methods', { expense_methods: [{ id: 3, name: 'Cash' }] }], ])('%s sends GET %s and unwraps data', async (method, url, payload) => { const { client, mockInstance } = makeClient(); mockInstance.request.mockResolvedValue({ data: { error_code: 200, data: payload } }); const res = await (client as any)[method](); expect(mockInstance.request).toHaveBeenCalledWith({ method: 'GET', url }); expect(res).toEqual(payload); }); }); describe('HostexApiClient transactions CRUD', () => { it('getTransactions sends GET /transactions and unwraps data', async () => { const { client, mockInstance } = makeClient(); const payload = { transactions: [{ id: 11, direction: 'income', amount: 50 }], total: 1 }; mockInstance.request.mockResolvedValue({ data: { error_code: 200, data: payload } }); const res = await client.getTransactions({ direction: 'income', start_date: '2026-06-01' }); expect(mockInstance.request).toHaveBeenCalledWith({ method: 'GET', url: '/transactions', params: { direction: 'income', start_date: '2026-06-01' }, }); expect(res).toEqual(payload); }); it('createTransaction sends POST /transactions', async () => { const { client, mockInstance } = makeClient(); mockInstance.post.mockResolvedValue({ data: { error_code: 200, data: { transaction_id: 11 } }, }); await client.createTransaction({ direction: 'income', amount: 50, item_id: 1, payment_method_id: 2, stay_code: 'S1', }); expect(mockInstance.post).toHaveBeenCalledWith('/transactions', { direction: 'income', amount: 50, item_id: 1, payment_method_id: 2, stay_code: 'S1', }); }); it('createTransaction requires currency when stay_code is absent', async () => { const { client } = makeClient(); await expect( client.createTransaction({ direction: 'income', amount: 50, item_id: 1, payment_method_id: 2, property_id: 1, }) ).rejects.toThrow('currency is required'); }); it('updateTransaction sends PATCH /transactions/:id without id in body', async () => { const { client, mockInstance } = makeClient(); mockInstance.patch.mockResolvedValue({ data: { error_code: 200 } }); await client.updateTransaction({ id: 11, amount: 75 }); expect(mockInstance.patch).toHaveBeenCalledWith('/transactions/11', { amount: 75 }); }); it('deleteTransaction sends DELETE /transactions/:id', async () => { const { client, mockInstance } = makeClient(); mockInstance.delete.mockResolvedValue({ data: { error_code: 200 } }); await client.deleteTransaction(11); expect(mockInstance.delete).toHaveBeenCalledWith('/transactions/11'); }); });