import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import SettingsPage from '../SettingsPage.tsx'; const { listMock, createMock, removeMock, usersListMock, buhsMock, pendingMock, requestMock, approveMock, refreshUserMock, authState, } = vi.hoisted(() => ({ listMock: vi.fn(), createMock: vi.fn(), removeMock: vi.fn(), usersListMock: vi.fn(), buhsMock: vi.fn(), pendingMock: vi.fn(), requestMock: vi.fn(), approveMock: vi.fn(), refreshUserMock: vi.fn(), authState: { user: { id: 5, user_name: 'gm.user', display_name: 'gm.user', status: 'gm' as string, managed_by: null as number | null, managed_by_name: null as string | null, managed_by_pending: null as number | null, managed_by_pending_name: null as string | null, created_at: '', updated_at: '', }, }, })); vi.mock('../../services/apiClient.ts', () => ({ api: { activeSites: { list: listMock, create: createMock, remove: removeMock, }, users: { list: usersListMock, listBuhs: buhsMock, listPendingManaged: pendingMock, requestManagedBy: requestMock, cancelManagedByRequest: vi.fn(), approveManagedBy: approveMock, rejectManagedBy: vi.fn(), }, }, errorMessage: (err: unknown) => (err instanceof Error ? err.message : 'Terjadi kesalahan'), })); vi.mock('../../context/AuthContext.tsx', () => ({ useAuth: () => ({ user: authState.user, refreshUser: refreshUserMock, }), })); vi.mock('../../context/FarmContext.tsx', () => ({ useFarm: () => ({ reload: vi.fn().mockResolvedValue(undefined), }), })); describe('SettingsPage city site registry', () => { beforeEach(() => { listMock.mockReset(); createMock.mockReset(); removeMock.mockReset(); usersListMock.mockReset(); buhsMock.mockReset(); pendingMock.mockReset(); requestMock.mockReset(); approveMock.mockReset(); refreshUserMock.mockReset(); authState.user = { id: 5, user_name: 'gm.user', display_name: 'gm.user', status: 'gm', managed_by: null, managed_by_name: null, managed_by_pending: null, managed_by_pending_name: null, created_at: '', updated_at: '', }; refreshUserMock.mockResolvedValue(authState.user); listMock.mockResolvedValue([ { id: 1, code: 'sukawarna', name: 'Sukawarna', api_base_url: 'https://sukawarna.example/api/v1', has_api_key: true, managed_by: 5, managed_by_name: 'gm.user', is_active: true, last_synced_at: null, last_sync_status: '', last_sync_message: '', created_at: '', updated_at: '', }, ]); createMock.mockResolvedValue({ id: 2, code: 'cikupa', name: 'Cikupa', api_base_url: 'https://cikupa.example/api/v1', has_api_key: false, managed_by: 5, managed_by_name: 'gm.user', is_active: true, last_synced_at: null, last_sync_status: '', last_sync_message: '', created_at: '', updated_at: '', }); buhsMock.mockResolvedValue([ { id: 2, user_name: 'buh', display_name: 'buh', status: 'buh', created_at: '', updated_at: '' }, ]); usersListMock.mockResolvedValue([ { id: 5, user_name: 'gm', display_name: 'gm', status: 'gm', managed_by: 2, created_at: '', updated_at: '', }, ]); pendingMock.mockResolvedValue([]); }); it('lists registered city sites for GM', async () => { render(); expect(await screen.findByText('Sukawarna')).toBeInTheDocument(); expect(screen.getByText('BUH pengelola')).toBeInTheDocument(); }); it('submits a new city site to the view list', async () => { render(); await screen.findByText('Sukawarna'); fireEvent.change(screen.getByPlaceholderText('Contoh: Sukawarna'), { target: { value: 'Cikupa' }, }); fireEvent.click(screen.getByRole('button', { name: 'Tambah ke daftar' })); await waitFor(() => expect(createMock).toHaveBeenCalledTimes(1)); expect(createMock).toHaveBeenCalledWith({ code: 'cikupa', name: 'Cikupa', is_active: true, }); }); it('lets GM request a BUH', async () => { requestMock.mockResolvedValue({ ...authState.user, managed_by_pending: 2, managed_by_pending_name: 'buh', }); render(); await screen.findByText('BUH pengelola'); fireEvent.change(screen.getByLabelText(/Pilih BUH/i), { target: { value: '2' } }); fireEvent.click(screen.getByRole('button', { name: 'Kirim permintaan' })); await waitFor(() => expect(requestMock).toHaveBeenCalledWith(2)); }); it('shows pending GM confirmation for BUH', async () => { authState.user = { id: 2, user_name: 'buh', display_name: 'buh', status: 'buh', managed_by: null, managed_by_name: null, managed_by_pending: null, managed_by_pending_name: null, created_at: '', updated_at: '', }; pendingMock.mockResolvedValue([ { id: 5, user_name: 'gm.user', display_name: 'gm.user', status: 'gm', created_at: '', updated_at: '', }, ]); render(); expect(await screen.findByText('Permintaan GM')).toBeInTheDocument(); expect(screen.getByText('gm.user')).toBeInTheDocument(); expect(screen.getByRole('button', { name: 'Konfirmasi' })).toBeInTheDocument(); }); });