import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { screen, waitFor } from '@testing-library/react'; import { Route, Routes } from 'react-router-dom'; import MockAdapter from 'axios-mock-adapter'; import { apiClient } from '@/api/client'; import { EngagementDetailPage } from '@/pages/EngagementDetailPage'; import { renderWithProviders } from './utils'; import type { Engagement } from '@/api/types'; vi.mock('@/api/exports', () => ({ downloadEngagementExport: vi.fn(), })); const ENGAGEMENT: Engagement = { id: 1, name: 'Test Engagement', description: 'A test engagement', start_date: '2026-06-01', end_date: null, status: 'active', created_at: '2026-06-01T08:00:00', created_by: { id: 1, username: 'alice' }, }; type MockRole = 'admin' | 'redteam' | 'soc'; let mockRole: MockRole = 'admin'; function DetailPage() { return ( } /> ); } vi.mock('@/hooks/useAuth', () => ({ useAuth: () => ({ user: { id: 1, username: 'alice', role: mockRole, created_at: '2026-01-01' }, status: 'authenticated', login: vi.fn(), logout: vi.fn(), isAdmin: mockRole === 'admin', isRedteam: mockRole === 'redteam', isSoc: mockRole === 'soc', canEditEngagements: mockRole === 'admin' || mockRole === 'redteam', }), })); describe('EngagementDetailPage — RBAC for Export button', () => { let mock: MockAdapter; beforeEach(() => { mock = new MockAdapter(apiClient); mock.onGet('/engagements/1').reply(200, ENGAGEMENT); mock.onGet('/engagements/1/simulations').reply(200, []); }); afterEach(() => { mock.restore(); }); it('admin sees Export button', async () => { mockRole = 'admin'; renderWithProviders(, { routerProps: { initialEntries: ['/engagements/1'] }, }); await waitFor(() => { expect(screen.getByText('Test Engagement')).toBeInTheDocument(); }); expect(screen.getByTestId('export-dropdown')).toBeInTheDocument(); }); it('redteam sees Export button', async () => { mockRole = 'redteam'; renderWithProviders(, { routerProps: { initialEntries: ['/engagements/1'] }, }); await waitFor(() => { expect(screen.getByText('Test Engagement')).toBeInTheDocument(); }); expect(screen.getByTestId('export-dropdown')).toBeInTheDocument(); }); it('soc does NOT see Export button', async () => { mockRole = 'soc'; renderWithProviders(, { routerProps: { initialEntries: ['/engagements/1'] }, }); await waitFor(() => { expect(screen.getByText('Test Engagement')).toBeInTheDocument(); }); expect(screen.queryByTestId('export-dropdown')).toBeNull(); }); });