import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' import { renderHook, waitFor } from '@testing-library/react' import { useAdmin } from '@/hooks/useAdmin' import * as api from '@/lib/api' import { mockAdminConfig, mockItemListResponse } from '../setup' // Mock react-hot-toast vi.mock('react-hot-toast', () => ({ toast: { error: vi.fn(), success: vi.fn(), loading: vi.fn(), }, })) // Mock the api module vi.mock('@/lib/api', () => ({ inventoryApi: { getUsers: vi.fn(), getCategories: vi.fn(), getLdapConfig: vi.fn(), getDbBackups: vi.fn(), getDbStats: vi.fn(), getDbSettings: vi.fn(), getAiPrompt: vi.fn(), getAiConfig: vi.fn(), createUser: vi.fn(), updateUser: vi.fn(), deleteUser: vi.fn(), updateAiProvider: vi.fn(), updateAiKeys: vi.fn(), testAiKey: vi.fn(), updateAiPrompt: vi.fn(), createBackup: vi.fn(), restoreBackup: vi.fn(), deleteBackup: vi.fn(), updateDbSettings: vi.fn(), createCategory: vi.fn(), updateCategory: vi.fn(), deleteCategory: vi.fn(), }, })) describe('useAdmin Hook', () => { beforeEach(() => { vi.clearAllMocks() }) afterEach(() => { vi.clearAllMocks() }) // ============================================================================ // UNIT TESTS: Hook Initialization & Data Loading // ============================================================================ describe('Hook Initialization', () => { it('should initialize with loading state', () => { const mockGetUsers = vi.fn().mockResolvedValue([]) const mockGetCategories = vi.fn().mockResolvedValue([]) const mockGetLdapConfig = vi.fn().mockResolvedValue({}) const mockGetDbBackups = vi.fn().mockResolvedValue([]) const mockGetDbStats = vi.fn().mockResolvedValue({}) const mockGetDbSettings = vi.fn().mockResolvedValue({}) const mockGetAiPrompt = vi.fn().mockResolvedValue({ value: '' }) const mockGetAiConfig = vi.fn().mockResolvedValue({}) vi.mocked(api.inventoryApi.getUsers).mockImplementation(mockGetUsers) vi.mocked(api.inventoryApi.getCategories).mockImplementation(mockGetCategories) vi.mocked(api.inventoryApi.getLdapConfig).mockImplementation(mockGetLdapConfig) vi.mocked(api.inventoryApi.getDbBackups).mockImplementation(mockGetDbBackups) vi.mocked(api.inventoryApi.getDbStats).mockImplementation(mockGetDbStats) vi.mocked(api.inventoryApi.getDbSettings).mockImplementation(mockGetDbSettings) vi.mocked(api.inventoryApi.getAiPrompt).mockImplementation(mockGetAiPrompt) vi.mocked(api.inventoryApi.getAiConfig).mockImplementation(mockGetAiConfig) const { result } = renderHook(() => useAdmin()) expect(result.current).toBeDefined() expect(result.current.loading).toBeDefined() }) it('should load all config data on mount', async () => { const mockGetUsers = vi.fn().mockResolvedValue([{ id: 1, username: 'admin', role: 'admin' }]) const mockGetCategories = vi.fn().mockResolvedValue([{ id: 1, name: 'Electronics' }]) const mockGetLdapConfig = vi.fn().mockResolvedValue({ ldap_enabled: true }) const mockGetDbBackups = vi.fn().mockResolvedValue([]) const mockGetDbStats = vi.fn().mockResolvedValue({ backup_count: 0 }) const mockGetDbSettings = vi.fn().mockResolvedValue({ retention_count: 10 }) const mockGetAiPrompt = vi.fn().mockResolvedValue({ value: 'Extract item data' }) const mockGetAiConfig = vi.fn().mockResolvedValue({ provider: 'gemini' }) vi.mocked(api.inventoryApi.getUsers).mockImplementation(mockGetUsers) vi.mocked(api.inventoryApi.getCategories).mockImplementation(mockGetCategories) vi.mocked(api.inventoryApi.getLdapConfig).mockImplementation(mockGetLdapConfig) vi.mocked(api.inventoryApi.getDbBackups).mockImplementation(mockGetDbBackups) vi.mocked(api.inventoryApi.getDbStats).mockImplementation(mockGetDbStats) vi.mocked(api.inventoryApi.getDbSettings).mockImplementation(mockGetDbSettings) vi.mocked(api.inventoryApi.getAiPrompt).mockImplementation(mockGetAiPrompt) vi.mocked(api.inventoryApi.getAiConfig).mockImplementation(mockGetAiConfig) const { result } = renderHook(() => useAdmin()) await waitFor(() => { expect(result.current.loading).toBe(false) }) }) it('should handle loading errors gracefully', async () => { const error = new Error('Failed to load config') const mockGetUsers = vi.fn().mockRejectedValue(error) const mockGetCategories = vi.fn().mockResolvedValue([]) const mockGetLdapConfig = vi.fn().mockResolvedValue({}) const mockGetDbBackups = vi.fn().mockResolvedValue([]) const mockGetDbStats = vi.fn().mockResolvedValue({}) const mockGetDbSettings = vi.fn().mockResolvedValue({}) const mockGetAiPrompt = vi.fn().mockResolvedValue({ value: '' }) const mockGetAiConfig = vi.fn().mockResolvedValue({}) vi.mocked(api.inventoryApi.getUsers).mockImplementation(mockGetUsers) vi.mocked(api.inventoryApi.getCategories).mockImplementation(mockGetCategories) vi.mocked(api.inventoryApi.getLdapConfig).mockImplementation(mockGetLdapConfig) vi.mocked(api.inventoryApi.getDbBackups).mockImplementation(mockGetDbBackups) vi.mocked(api.inventoryApi.getDbStats).mockImplementation(mockGetDbStats) vi.mocked(api.inventoryApi.getDbSettings).mockImplementation(mockGetDbSettings) vi.mocked(api.inventoryApi.getAiPrompt).mockImplementation(mockGetAiPrompt) vi.mocked(api.inventoryApi.getAiConfig).mockImplementation(mockGetAiConfig) const { result } = renderHook(() => useAdmin()) await waitFor(() => { expect(result.current.loading).toBe(false) }) }) }) // ============================================================================ // UNIT TESTS: State Updates (Identity, DB, LDAP, AI) // ============================================================================ describe('State Management', () => { it('should update users state', async () => { const mockUsers = [{ id: 1, username: 'testuser', role: 'user' }] const mockGetUsers = vi.fn().mockResolvedValue(mockUsers) const mockGetCategories = vi.fn().mockResolvedValue([]) const mockGetLdapConfig = vi.fn().mockResolvedValue({}) const mockGetDbBackups = vi.fn().mockResolvedValue([]) const mockGetDbStats = vi.fn().mockResolvedValue({}) const mockGetDbSettings = vi.fn().mockResolvedValue({}) const mockGetAiPrompt = vi.fn().mockResolvedValue({ value: '' }) const mockGetAiConfig = vi.fn().mockResolvedValue({}) vi.mocked(api.inventoryApi.getUsers).mockImplementation(mockGetUsers) vi.mocked(api.inventoryApi.getCategories).mockImplementation(mockGetCategories) vi.mocked(api.inventoryApi.getLdapConfig).mockImplementation(mockGetLdapConfig) vi.mocked(api.inventoryApi.getDbBackups).mockImplementation(mockGetDbBackups) vi.mocked(api.inventoryApi.getDbStats).mockImplementation(mockGetDbStats) vi.mocked(api.inventoryApi.getDbSettings).mockImplementation(mockGetDbSettings) vi.mocked(api.inventoryApi.getAiPrompt).mockImplementation(mockGetAiPrompt) vi.mocked(api.inventoryApi.getAiConfig).mockImplementation(mockGetAiConfig) const { result } = renderHook(() => useAdmin()) await waitFor(() => { expect(result.current.users).toBeDefined() }) }) it('should update categories state', async () => { const mockCategories = [{ id: 1, name: 'Electronics', description: 'Electronic items' }] const mockGetUsers = vi.fn().mockResolvedValue([]) const mockGetCategories = vi.fn().mockResolvedValue(mockCategories) const mockGetLdapConfig = vi.fn().mockResolvedValue({}) const mockGetDbBackups = vi.fn().mockResolvedValue([]) const mockGetDbStats = vi.fn().mockResolvedValue({}) const mockGetDbSettings = vi.fn().mockResolvedValue({}) const mockGetAiPrompt = vi.fn().mockResolvedValue({ value: '' }) const mockGetAiConfig = vi.fn().mockResolvedValue({}) vi.mocked(api.inventoryApi.getUsers).mockImplementation(mockGetUsers) vi.mocked(api.inventoryApi.getCategories).mockImplementation(mockGetCategories) vi.mocked(api.inventoryApi.getLdapConfig).mockImplementation(mockGetLdapConfig) vi.mocked(api.inventoryApi.getDbBackups).mockImplementation(mockGetDbBackups) vi.mocked(api.inventoryApi.getDbStats).mockImplementation(mockGetDbStats) vi.mocked(api.inventoryApi.getDbSettings).mockImplementation(mockGetDbSettings) vi.mocked(api.inventoryApi.getAiPrompt).mockImplementation(mockGetAiPrompt) vi.mocked(api.inventoryApi.getAiConfig).mockImplementation(mockGetAiConfig) const { result } = renderHook(() => useAdmin()) await waitFor(() => { expect(result.current.categories).toBeDefined() }) }) it('should update LDAP config state', async () => { const mockLdapConfig = { ldap_enabled: true, server_uri: 'ldap://example.com' } const mockGetUsers = vi.fn().mockResolvedValue([]) const mockGetCategories = vi.fn().mockResolvedValue([]) const mockGetLdapConfig = vi.fn().mockResolvedValue(mockLdapConfig) const mockGetDbBackups = vi.fn().mockResolvedValue([]) const mockGetDbStats = vi.fn().mockResolvedValue({}) const mockGetDbSettings = vi.fn().mockResolvedValue({}) const mockGetAiPrompt = vi.fn().mockResolvedValue({ value: '' }) const mockGetAiConfig = vi.fn().mockResolvedValue({}) vi.mocked(api.inventoryApi.getUsers).mockImplementation(mockGetUsers) vi.mocked(api.inventoryApi.getCategories).mockImplementation(mockGetCategories) vi.mocked(api.inventoryApi.getLdapConfig).mockImplementation(mockGetLdapConfig) vi.mocked(api.inventoryApi.getDbBackups).mockImplementation(mockGetDbBackups) vi.mocked(api.inventoryApi.getDbStats).mockImplementation(mockGetDbStats) vi.mocked(api.inventoryApi.getDbSettings).mockImplementation(mockGetDbSettings) vi.mocked(api.inventoryApi.getAiPrompt).mockImplementation(mockGetAiPrompt) vi.mocked(api.inventoryApi.getAiConfig).mockImplementation(mockGetAiConfig) const { result } = renderHook(() => useAdmin()) await waitFor(() => { expect(result.current.ldapConfig).toBeDefined() }) }) it('should update AI config state', async () => { const mockAiConfig = { provider: 'gemini', api_key: 'test-key' } const mockGetUsers = vi.fn().mockResolvedValue([]) const mockGetCategories = vi.fn().mockResolvedValue([]) const mockGetLdapConfig = vi.fn().mockResolvedValue({}) const mockGetDbBackups = vi.fn().mockResolvedValue([]) const mockGetDbStats = vi.fn().mockResolvedValue({}) const mockGetDbSettings = vi.fn().mockResolvedValue({}) const mockGetAiPrompt = vi.fn().mockResolvedValue({ value: '' }) const mockGetAiConfig = vi.fn().mockResolvedValue(mockAiConfig) vi.mocked(api.inventoryApi.getUsers).mockImplementation(mockGetUsers) vi.mocked(api.inventoryApi.getCategories).mockImplementation(mockGetCategories) vi.mocked(api.inventoryApi.getLdapConfig).mockImplementation(mockGetLdapConfig) vi.mocked(api.inventoryApi.getDbBackups).mockImplementation(mockGetDbBackups) vi.mocked(api.inventoryApi.getDbStats).mockImplementation(mockGetDbStats) vi.mocked(api.inventoryApi.getDbSettings).mockImplementation(mockGetDbSettings) vi.mocked(api.inventoryApi.getAiPrompt).mockImplementation(mockGetAiPrompt) vi.mocked(api.inventoryApi.getAiConfig).mockImplementation(mockGetAiConfig) const { result } = renderHook(() => useAdmin()) await waitFor(() => { expect(result.current.aiConfig).toBeDefined() }) }) }) // ============================================================================ // UNIT TESTS: User Management (Create, Update, Delete) // ============================================================================ describe('User Management', () => { it('should have handleAddUser method', async () => { const mockGetUsers = vi.fn().mockResolvedValue([]) const mockGetCategories = vi.fn().mockResolvedValue([]) const mockGetLdapConfig = vi.fn().mockResolvedValue({}) const mockGetDbBackups = vi.fn().mockResolvedValue([]) const mockGetDbStats = vi.fn().mockResolvedValue({}) const mockGetDbSettings = vi.fn().mockResolvedValue({}) const mockGetAiPrompt = vi.fn().mockResolvedValue({ value: '' }) const mockGetAiConfig = vi.fn().mockResolvedValue({}) vi.mocked(api.inventoryApi.getUsers).mockImplementation(mockGetUsers) vi.mocked(api.inventoryApi.getCategories).mockImplementation(mockGetCategories) vi.mocked(api.inventoryApi.getLdapConfig).mockImplementation(mockGetLdapConfig) vi.mocked(api.inventoryApi.getDbBackups).mockImplementation(mockGetDbBackups) vi.mocked(api.inventoryApi.getDbStats).mockImplementation(mockGetDbStats) vi.mocked(api.inventoryApi.getDbSettings).mockImplementation(mockGetDbSettings) vi.mocked(api.inventoryApi.getAiPrompt).mockImplementation(mockGetAiPrompt) vi.mocked(api.inventoryApi.getAiConfig).mockImplementation(mockGetAiConfig) const { result } = renderHook(() => useAdmin()) await waitFor(() => { expect(result.current.handleAddUser).toBeDefined() }) }) it('should have handleDeleteUser method', async () => { const mockGetUsers = vi.fn().mockResolvedValue([]) const mockGetCategories = vi.fn().mockResolvedValue([]) const mockGetLdapConfig = vi.fn().mockResolvedValue({}) const mockGetDbBackups = vi.fn().mockResolvedValue([]) const mockGetDbStats = vi.fn().mockResolvedValue({}) const mockGetDbSettings = vi.fn().mockResolvedValue({}) const mockGetAiPrompt = vi.fn().mockResolvedValue({ value: '' }) const mockGetAiConfig = vi.fn().mockResolvedValue({}) vi.mocked(api.inventoryApi.getUsers).mockImplementation(mockGetUsers) vi.mocked(api.inventoryApi.getCategories).mockImplementation(mockGetCategories) vi.mocked(api.inventoryApi.getLdapConfig).mockImplementation(mockGetLdapConfig) vi.mocked(api.inventoryApi.getDbBackups).mockImplementation(mockGetDbBackups) vi.mocked(api.inventoryApi.getDbStats).mockImplementation(mockGetDbStats) vi.mocked(api.inventoryApi.getDbSettings).mockImplementation(mockGetDbSettings) vi.mocked(api.inventoryApi.getAiPrompt).mockImplementation(mockGetAiPrompt) vi.mocked(api.inventoryApi.getAiConfig).mockImplementation(mockGetAiConfig) const { result } = renderHook(() => useAdmin()) await waitFor(() => { expect(result.current.handleDeleteUser).toBeDefined() }) }) it('should have handleUpdateUserSubmit method', async () => { const mockGetUsers = vi.fn().mockResolvedValue([]) const mockGetCategories = vi.fn().mockResolvedValue([]) const mockGetLdapConfig = vi.fn().mockResolvedValue({}) const mockGetDbBackups = vi.fn().mockResolvedValue([]) const mockGetDbStats = vi.fn().mockResolvedValue({}) const mockGetDbSettings = vi.fn().mockResolvedValue({}) const mockGetAiPrompt = vi.fn().mockResolvedValue({ value: '' }) const mockGetAiConfig = vi.fn().mockResolvedValue({}) vi.mocked(api.inventoryApi.getUsers).mockImplementation(mockGetUsers) vi.mocked(api.inventoryApi.getCategories).mockImplementation(mockGetCategories) vi.mocked(api.inventoryApi.getLdapConfig).mockImplementation(mockGetLdapConfig) vi.mocked(api.inventoryApi.getDbBackups).mockImplementation(mockGetDbBackups) vi.mocked(api.inventoryApi.getDbStats).mockImplementation(mockGetDbStats) vi.mocked(api.inventoryApi.getDbSettings).mockImplementation(mockGetDbSettings) vi.mocked(api.inventoryApi.getAiPrompt).mockImplementation(mockGetAiPrompt) vi.mocked(api.inventoryApi.getAiConfig).mockImplementation(mockGetAiConfig) const { result } = renderHook(() => useAdmin()) await waitFor(() => { expect(result.current.handleUpdateUserSubmit).toBeDefined() }) }) }) // ============================================================================ // UNIT TESTS: Configuration Submission // ============================================================================ describe('Configuration Submission', () => { it('should handle AI provider update', async () => { const mockGetUsers = vi.fn().mockResolvedValue([]) const mockGetCategories = vi.fn().mockResolvedValue([]) const mockGetLdapConfig = vi.fn().mockResolvedValue({}) const mockGetDbBackups = vi.fn().mockResolvedValue([]) const mockGetDbStats = vi.fn().mockResolvedValue({}) const mockGetDbSettings = vi.fn().mockResolvedValue({}) const mockGetAiPrompt = vi.fn().mockResolvedValue({ value: '' }) const mockGetAiConfig = vi.fn().mockResolvedValue({}) vi.mocked(api.inventoryApi.getUsers).mockImplementation(mockGetUsers) vi.mocked(api.inventoryApi.getCategories).mockImplementation(mockGetCategories) vi.mocked(api.inventoryApi.getLdapConfig).mockImplementation(mockGetLdapConfig) vi.mocked(api.inventoryApi.getDbBackups).mockImplementation(mockGetDbBackups) vi.mocked(api.inventoryApi.getDbStats).mockImplementation(mockGetDbStats) vi.mocked(api.inventoryApi.getDbSettings).mockImplementation(mockGetDbSettings) vi.mocked(api.inventoryApi.getAiPrompt).mockImplementation(mockGetAiPrompt) vi.mocked(api.inventoryApi.getAiConfig).mockImplementation(mockGetAiConfig) const { result } = renderHook(() => useAdmin()) await waitFor(() => { expect(result.current.handleUpdateAiProvider).toBeDefined() }) }) it('should handle AI keys submission', async () => { const mockGetUsers = vi.fn().mockResolvedValue([]) const mockGetCategories = vi.fn().mockResolvedValue([]) const mockGetLdapConfig = vi.fn().mockResolvedValue({}) const mockGetDbBackups = vi.fn().mockResolvedValue([]) const mockGetDbStats = vi.fn().mockResolvedValue({}) const mockGetDbSettings = vi.fn().mockResolvedValue({}) const mockGetAiPrompt = vi.fn().mockResolvedValue({ value: '' }) const mockGetAiConfig = vi.fn().mockResolvedValue({}) vi.mocked(api.inventoryApi.getUsers).mockImplementation(mockGetUsers) vi.mocked(api.inventoryApi.getCategories).mockImplementation(mockGetCategories) vi.mocked(api.inventoryApi.getLdapConfig).mockImplementation(mockGetLdapConfig) vi.mocked(api.inventoryApi.getDbBackups).mockImplementation(mockGetDbBackups) vi.mocked(api.inventoryApi.getDbStats).mockImplementation(mockGetDbStats) vi.mocked(api.inventoryApi.getDbSettings).mockImplementation(mockGetDbSettings) vi.mocked(api.inventoryApi.getAiPrompt).mockImplementation(mockGetAiPrompt) vi.mocked(api.inventoryApi.getAiConfig).mockImplementation(mockGetAiConfig) const { result } = renderHook(() => useAdmin()) await waitFor(() => { expect(result.current.handleSaveAiKeys).toBeDefined() }) }) }) // ============================================================================ // ERROR HANDLING TESTS // ============================================================================ describe('Error Handling & Retry', () => { it('should handle API errors during loading', async () => { const error = new Error('API Error') const mockGetUsers = vi.fn().mockRejectedValue(error) const mockGetCategories = vi.fn().mockResolvedValue([]) const mockGetLdapConfig = vi.fn().mockResolvedValue({}) const mockGetDbBackups = vi.fn().mockResolvedValue([]) const mockGetDbStats = vi.fn().mockResolvedValue({}) const mockGetDbSettings = vi.fn().mockResolvedValue({}) const mockGetAiPrompt = vi.fn().mockResolvedValue({ value: '' }) const mockGetAiConfig = vi.fn().mockResolvedValue({}) vi.mocked(api.inventoryApi.getUsers).mockImplementation(mockGetUsers) vi.mocked(api.inventoryApi.getCategories).mockImplementation(mockGetCategories) vi.mocked(api.inventoryApi.getLdapConfig).mockImplementation(mockGetLdapConfig) vi.mocked(api.inventoryApi.getDbBackups).mockImplementation(mockGetDbBackups) vi.mocked(api.inventoryApi.getDbStats).mockImplementation(mockGetDbStats) vi.mocked(api.inventoryApi.getDbSettings).mockImplementation(mockGetDbSettings) vi.mocked(api.inventoryApi.getAiPrompt).mockImplementation(mockGetAiPrompt) vi.mocked(api.inventoryApi.getAiConfig).mockImplementation(mockGetAiConfig) const { result } = renderHook(() => useAdmin()) await waitFor(() => { expect(result.current.loading).toBe(false) }) }) it('should handle network errors during config submission', async () => { const mockGetUsers = vi.fn().mockResolvedValue([]) const mockGetCategories = vi.fn().mockResolvedValue([]) const mockGetLdapConfig = vi.fn().mockResolvedValue({}) const mockGetDbBackups = vi.fn().mockResolvedValue([]) const mockGetDbStats = vi.fn().mockResolvedValue({}) const mockGetDbSettings = vi.fn().mockResolvedValue({}) const mockGetAiPrompt = vi.fn().mockResolvedValue({ value: '' }) const mockGetAiConfig = vi.fn().mockResolvedValue({}) const mockUpdateAiKeys = vi.fn().mockRejectedValue(new Error('Network error')) vi.mocked(api.inventoryApi.getUsers).mockImplementation(mockGetUsers) vi.mocked(api.inventoryApi.getCategories).mockImplementation(mockGetCategories) vi.mocked(api.inventoryApi.getLdapConfig).mockImplementation(mockGetLdapConfig) vi.mocked(api.inventoryApi.getDbBackups).mockImplementation(mockGetDbBackups) vi.mocked(api.inventoryApi.getDbStats).mockImplementation(mockGetDbStats) vi.mocked(api.inventoryApi.getDbSettings).mockImplementation(mockGetDbSettings) vi.mocked(api.inventoryApi.getAiPrompt).mockImplementation(mockGetAiPrompt) vi.mocked(api.inventoryApi.getAiConfig).mockImplementation(mockGetAiConfig) vi.mocked(api.inventoryApi.updateAiKeys).mockImplementation(mockUpdateAiKeys) const { result } = renderHook(() => useAdmin()) await waitFor(() => { expect(result.current.loading).toBe(false) }) }) it('should handle user creation failures', async () => { const mockGetUsers = vi.fn().mockResolvedValue([]) const mockGetCategories = vi.fn().mockResolvedValue([]) const mockGetLdapConfig = vi.fn().mockResolvedValue({}) const mockGetDbBackups = vi.fn().mockResolvedValue([]) const mockGetDbStats = vi.fn().mockResolvedValue({}) const mockGetDbSettings = vi.fn().mockResolvedValue({}) const mockGetAiPrompt = vi.fn().mockResolvedValue({ value: '' }) const mockGetAiConfig = vi.fn().mockResolvedValue({}) const mockCreateUser = vi.fn().mockRejectedValue(new Error('User exists')) vi.mocked(api.inventoryApi.getUsers).mockImplementation(mockGetUsers) vi.mocked(api.inventoryApi.getCategories).mockImplementation(mockGetCategories) vi.mocked(api.inventoryApi.getLdapConfig).mockImplementation(mockGetLdapConfig) vi.mocked(api.inventoryApi.getDbBackups).mockImplementation(mockGetDbBackups) vi.mocked(api.inventoryApi.getDbStats).mockImplementation(mockGetDbStats) vi.mocked(api.inventoryApi.getDbSettings).mockImplementation(mockGetDbSettings) vi.mocked(api.inventoryApi.getAiPrompt).mockImplementation(mockGetAiPrompt) vi.mocked(api.inventoryApi.getAiConfig).mockImplementation(mockGetAiConfig) vi.mocked(api.inventoryApi.createUser).mockImplementation(mockCreateUser) const { result } = renderHook(() => useAdmin()) await waitFor(() => { expect(result.current.loading).toBe(false) }) }) }) // ============================================================================ // UNIT TESTS: Form Validation // ============================================================================ describe('Form Validation', () => { it('should track editing user state', async () => { const mockGetUsers = vi.fn().mockResolvedValue([]) const mockGetCategories = vi.fn().mockResolvedValue([]) const mockGetLdapConfig = vi.fn().mockResolvedValue({}) const mockGetDbBackups = vi.fn().mockResolvedValue([]) const mockGetDbStats = vi.fn().mockResolvedValue({}) const mockGetDbSettings = vi.fn().mockResolvedValue({}) const mockGetAiPrompt = vi.fn().mockResolvedValue({ value: '' }) const mockGetAiConfig = vi.fn().mockResolvedValue({}) vi.mocked(api.inventoryApi.getUsers).mockImplementation(mockGetUsers) vi.mocked(api.inventoryApi.getCategories).mockImplementation(mockGetCategories) vi.mocked(api.inventoryApi.getLdapConfig).mockImplementation(mockGetLdapConfig) vi.mocked(api.inventoryApi.getDbBackups).mockImplementation(mockGetDbBackups) vi.mocked(api.inventoryApi.getDbStats).mockImplementation(mockGetDbStats) vi.mocked(api.inventoryApi.getDbSettings).mockImplementation(mockGetDbSettings) vi.mocked(api.inventoryApi.getAiPrompt).mockImplementation(mockGetAiPrompt) vi.mocked(api.inventoryApi.getAiConfig).mockImplementation(mockGetAiConfig) const { result } = renderHook(() => useAdmin()) await waitFor(() => { expect(result.current.editingUser).toBeDefined() expect(result.current.setEditingUser).toBeDefined() }) }) it('should track editing category state', async () => { const mockGetUsers = vi.fn().mockResolvedValue([]) const mockGetCategories = vi.fn().mockResolvedValue([]) const mockGetLdapConfig = vi.fn().mockResolvedValue({}) const mockGetDbBackups = vi.fn().mockResolvedValue([]) const mockGetDbStats = vi.fn().mockResolvedValue({}) const mockGetDbSettings = vi.fn().mockResolvedValue({}) const mockGetAiPrompt = vi.fn().mockResolvedValue({ value: '' }) const mockGetAiConfig = vi.fn().mockResolvedValue({}) vi.mocked(api.inventoryApi.getUsers).mockImplementation(mockGetUsers) vi.mocked(api.inventoryApi.getCategories).mockImplementation(mockGetCategories) vi.mocked(api.inventoryApi.getLdapConfig).mockImplementation(mockGetLdapConfig) vi.mocked(api.inventoryApi.getDbBackups).mockImplementation(mockGetDbBackups) vi.mocked(api.inventoryApi.getDbStats).mockImplementation(mockGetDbStats) vi.mocked(api.inventoryApi.getDbSettings).mockImplementation(mockGetDbSettings) vi.mocked(api.inventoryApi.getAiPrompt).mockImplementation(mockGetAiPrompt) vi.mocked(api.inventoryApi.getAiConfig).mockImplementation(mockGetAiConfig) const { result } = renderHook(() => useAdmin()) await waitFor(() => { expect(result.current.editingCategory).toBeDefined() expect(result.current.setEditingCategory).toBeDefined() }) }) }) })