Skip to content

Commit 6dfacb9

Browse files
fix: tests fixed
1 parent 071f872 commit 6dfacb9

3 files changed

Lines changed: 63 additions & 25 deletions

File tree

src/authz-module/audit-user/index.test.tsx

Lines changed: 61 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import { render, screen, waitFor } from '@testing-library/react';
1+
import {
2+
render, screen, waitFor, act,
3+
} from '@testing-library/react';
24
import { AppContext } from '@edx/frontend-platform/react';
35
import userEvent from '@testing-library/user-event';
46
import { MemoryRouter, Route, Routes } from 'react-router-dom';
@@ -17,6 +19,21 @@ jest.mock('@edx/frontend-platform/logging', () => ({
1719
logError: jest.fn(),
1820
}));
1921

22+
// Mock StudioHeader to avoid prop validation errors in tests
23+
jest.mock('@edx/frontend-component-header', () => ({
24+
StudioHeader: ({ children, ...props }: any) => <div data-testid="mocked-studio-header" {...props}>{children}</div>,
25+
}));
26+
27+
// Mock the useRevokeUserRoles hook
28+
const mockRevokeUserRoles = jest.fn();
29+
jest.mock('@src/authz-module/data/hooks', () => ({
30+
...jest.requireActual('@src/authz-module/data/hooks'),
31+
useRevokeUserRoles: () => ({
32+
mutate: mockRevokeUserRoles,
33+
isPending: false,
34+
}),
35+
}));
36+
2037
const mockUser = {
2138
username: 'johndoe',
2239
@@ -50,9 +67,16 @@ const renderWithRouter = (route = '/audit/johndoe') => {
5067
authenticatedUser: {
5168
username: 'testuser',
5269
70+
userId: 1,
5371
},
5472
config: {
55-
// @ts-ignore
73+
LMS_BASE_URL: 'http://localhost:18000',
74+
STUDIO_BASE_URL: 'http://localhost:18010',
75+
AUTHZ_MICROFRONTEND_URL: 'http://localhost:18012',
76+
ACCESS_TOKEN_COOKIE_NAME: 'edx-jwt-cookie-header-payload',
77+
BASE_URL: 'http://localhost:18012',
78+
ENVIRONMENT: 'test',
79+
LANGUAGE_PREFERENCE_COOKIE_NAME: 'openedx-language-preference',
5680
...process.env,
5781
},
5882
};
@@ -78,6 +102,11 @@ const renderWithRouter = (route = '/audit/johndoe') => {
78102
describe('AuditUserPage', () => {
79103
beforeEach(() => {
80104
jest.clearAllMocks();
105+
// Set up default mock behavior for useRevokeUserRoles
106+
mockRevokeUserRoles.mockImplementation((variables, { onSuccess }) => {
107+
// Simulate successful deletion by default
108+
onSuccess({ errors: [], completed: ['role1'] });
109+
});
81110
});
82111

83112
beforeAll(() => {
@@ -250,7 +279,6 @@ describe('AuditUserPage', () => {
250279
.fn()
251280
.mockResolvedValueOnce({ data: mockUser })
252281
.mockResolvedValueOnce({ data: mockAssignments }),
253-
delete: jest.fn().mockResolvedValue({ data: { errors: [] } }),
254282
});
255283

256284
renderWithRouter();
@@ -269,26 +297,35 @@ describe('AuditUserPage', () => {
269297
});
270298

271299
const removeButton = screen.getByRole('button', { name: /remove/i });
272-
await user.click(removeButton);
300+
301+
await act(async () => {
302+
await user.click(removeButton);
303+
});
273304

274305
await waitFor(() => {
275306
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
307+
});
308+
309+
await waitFor(() => {
276310
expect(screen.getByText(/role has been successfully removed/i)).toBeInTheDocument();
277311
});
278312
});
279313

280314
it('shows error toast when role revocation succeeds but returns errors', async () => {
315+
// Override mock for this specific test case
316+
mockRevokeUserRoles.mockImplementation((_, { onSuccess }) => {
317+
// Call onSuccess immediately with errors
318+
onSuccess({
319+
errors: ['Failed to revoke user role'],
320+
completed: [],
321+
});
322+
});
323+
281324
(getAuthenticatedHttpClient as jest.Mock).mockReturnValue({
282325
get: jest
283326
.fn()
284327
.mockResolvedValueOnce({ data: mockUser })
285328
.mockResolvedValueOnce({ data: mockAssignments }),
286-
delete: jest.fn().mockResolvedValue({
287-
data: {
288-
errors: ['Failed to revoke user role'],
289-
completed: [],
290-
},
291-
}),
292329
});
293330

294331
renderWithRouter();
@@ -307,20 +344,28 @@ describe('AuditUserPage', () => {
307344
});
308345

309346
const removeButton = screen.getByRole('button', { name: /remove/i });
310-
await user.click(removeButton);
347+
348+
await act(async () => {
349+
await user.click(removeButton);
350+
});
311351

312352
await waitFor(() => {
313353
expect(screen.getByText(/something went wrong/i)).toBeInTheDocument();
314354
});
315355
});
316356

317357
it('shows error toast with retry when role revocation fails', async () => {
358+
// Override mock for this specific test case
359+
mockRevokeUserRoles.mockImplementation((variables, { onError }) => {
360+
// Call onError immediately to simulate failure
361+
onError(new Error('Network error'));
362+
});
363+
318364
(getAuthenticatedHttpClient as jest.Mock).mockReturnValue({
319365
get: jest
320366
.fn()
321367
.mockResolvedValueOnce({ data: mockUser })
322368
.mockResolvedValueOnce({ data: mockAssignments }),
323-
delete: jest.fn().mockRejectedValue(new Error('Network error')),
324369
});
325370

326371
renderWithRouter();
@@ -339,7 +384,10 @@ describe('AuditUserPage', () => {
339384
});
340385

341386
const removeButton = screen.getByRole('button', { name: /remove/i });
342-
await user.click(removeButton);
387+
388+
await act(async () => {
389+
await user.click(removeButton);
390+
});
343391

344392
await waitFor(() => {
345393
expect(screen.getByText(/something went wrong on our end/i)).toBeInTheDocument();

src/authz-module/audit-user/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ import { useQuerySettings } from '@src/authz-module/hooks/useQuerySettings';
2424
import { useRevokeUserRoles, useUserAssignedRoles } from '@src/authz-module/data/hooks';
2525
import { RoleToDelete } from 'types';
2626
import { useToastManager } from '@src/components/ToastManager/ToastManagerContext';
27+
import UserPermissions from '@src/authz-module/components/UserPermissions';
2728
import messages from './messages';
2829
import ConfirmDeletionModal from '../components/ConfirmDeletionModal';
29-
import UserPermissions from '@src/authz-module/components/UserPermissions';
3030

3131
const AuditUserPage = () => {
3232
const { formatMessage } = useIntl();

src/authz-module/components/TableCells.tsx

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,12 @@ import { useNavigate } from 'react-router-dom';
1212
import { useContext, useMemo } from 'react';
1313
import { ADMIN_ROLES, DJANGO_MANAGED_ROLES, MAP_ROLE_KEY_TO_LABEL } from '@src/authz-module/constants';
1414
import {
15-
Icon, IconButton, OverlayTrigger, Tooltip,
15+
Icon, IconButton, OverlayTrigger, Tooltip, DataTableContext,
1616
} from '@openedx/paragon';
1717
import { RESOURCE_ICONS } from './constants';
1818
import messages from './messages';
1919
import ViewMoreLink from './ViewMoreLink';
2020

21-
interface ExpandableTableRow<T> extends TableCellValue<T> {
22-
row: TableCellValue<T>['row'] & {
23-
id: string;
24-
isExpanded: boolean;
25-
toggleRowExpanded: () => void;
26-
values: T;
27-
};
28-
}
29-
3021
interface DataTableInstance {
3122
state?: {
3223
expanded?: Record<string, boolean>;
@@ -35,7 +26,6 @@ interface DataTableInstance {
3526
}
3627

3728
type CellProps = TableCellValue<UserRole>;
38-
type ExpandableCellProps = ExpandableTableRow<UserRole>;
3929
type CellPropsWithValue = CellProps & {
4030
value: string;
4131
};

0 commit comments

Comments
 (0)