import { describe, it, expect, beforeEach, vi } from 'vitest' import axios from 'axios' import { tenantService } from '../tenant.service' import type { Tenant, TenantUpdateRequest, TenantUpdateResponse } from '../../types/tenant' // Mock axios vi.mock('axios', () => ({ default: { get: vi.fn(), put: vi.fn(), }, })) const mockedAxios = axios as unknown as { get: ReturnType put: ReturnType } describe('TenantService', () => { beforeEach(() => { vi.clearAllMocks() }) describe('getTenant', () => { it('should fetch tenant information successfully', async () => { // Arrange const tenantId = 1 const mockTenant: Tenant = { id: 1, code: 'PWD', name: 'Porsche World', name_eng: 'Porsche World Co., Ltd.', tax_id: '12345678', prefix: 'PWD', tel: '02-1234-5678', add: '台北市信義區...', url: 'https://porscheworld.tw', plan_id: 'starter', max_users: 50, storage_quota_gb: 1000, status: 'active', is_sysmana: false, is_active: true, created_at: '2026-01-01T00:00:00', updated_at: '2026-02-21T00:00:00', } mockedAxios.get.mockResolvedValueOnce({ data: mockTenant }) // Act const result = await tenantService.getTenant(tenantId) // Assert expect(mockedAxios.get).toHaveBeenCalledWith( `http://localhost:10181/api/v1/tenants/${tenantId}` ) expect(result).toEqual(mockTenant) }) it('should throw error when tenant not found', async () => { // Arrange const tenantId = 999 mockedAxios.get.mockRejectedValueOnce({ response: { data: { detail: 'Tenant not found' }, status: 404, }, }) // Act & Assert await expect(tenantService.getTenant(tenantId)).rejects.toThrow() }) }) describe('updateTenant', () => { it('should update tenant information successfully', async () => { // Arrange const tenantId = 1 const updateData: TenantUpdateRequest = { name: 'Porsche World Updated', tax_id: '87654321', tel: '02-8765-4321', add: '台北市大安區...', url: 'https://newporscheworld.tw', } const mockResponse: TenantUpdateResponse = { message: 'Tenant updated successfully', tenant: { id: 1, code: 'PWD', name: 'Porsche World Updated', name_eng: 'Porsche World Co., Ltd.', tax_id: '87654321', prefix: 'PWD', tel: '02-8765-4321', add: '台北市大安區...', url: 'https://newporscheworld.tw', plan_id: 'starter', max_users: 50, storage_quota_gb: 1000, status: 'active', is_sysmana: false, is_active: true, created_at: '2026-01-01T00:00:00', updated_at: '2026-02-21T10:00:00', }, } mockedAxios.put.mockResolvedValueOnce({ data: mockResponse }) // Act const result = await tenantService.updateTenant(tenantId, updateData) // Assert expect(mockedAxios.put).toHaveBeenCalledWith( `http://localhost:10181/api/v1/tenants/${tenantId}`, updateData ) expect(result).toEqual(mockResponse) }) it('should throw error when update fails', async () => { // Arrange const tenantId = 1 const updateData: TenantUpdateRequest = { name: 'Test', } mockedAxios.put.mockRejectedValueOnce({ response: { data: { detail: 'Update failed' }, status: 400, }, }) // Act & Assert await expect(tenantService.updateTenant(tenantId, updateData)).rejects.toThrow() }) }) })