test: replacing queries by test id
This commit is contained in:
committed by
Adolfo R. Brandes
parent
eb224b9f71
commit
0572a73fb4
@@ -44,9 +44,9 @@ describe('AuthZTitle', () => {
|
||||
});
|
||||
|
||||
it('renders page subtitle as ReactNode', () => {
|
||||
const subtitleNode = <div data-testid="custom-subtitle">Custom Subtitle</div>;
|
||||
const subtitleNode = <div>Custom Subtitle</div>;
|
||||
render(<AuthZTitle {...defaultProps} pageSubtitle={subtitleNode} />);
|
||||
expect(screen.getByTestId('custom-subtitle')).toBeInTheDocument();
|
||||
expect(screen.getByText('Custom Subtitle')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders action buttons and triggers onClick', () => {
|
||||
@@ -69,7 +69,7 @@ describe('AuthZTitle', () => {
|
||||
});
|
||||
|
||||
it('renders action buttons with icons', () => {
|
||||
const mockIcon = () => <span data-testid="mock-icon">Icon</span>;
|
||||
const mockIcon = () => <span role="img" aria-label="save icon">Icon</span>;
|
||||
const onClick = jest.fn();
|
||||
const actions = [
|
||||
{ label: 'Save', icon: mockIcon, onClick },
|
||||
@@ -77,14 +77,14 @@ describe('AuthZTitle', () => {
|
||||
|
||||
render(<AuthZTitle {...defaultProps} actions={actions} />);
|
||||
|
||||
const button = screen.getByRole('button', { name: 'Icon Save' });
|
||||
const button = screen.getByRole('button', { name: 'save icon Save' });
|
||||
expect(button).toBeInTheDocument();
|
||||
expect(screen.getByTestId('mock-icon')).toBeInTheDocument();
|
||||
expect(screen.getByRole('img', { name: 'save icon' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders ReactNode actions alongside button actions', () => {
|
||||
const onClick = jest.fn();
|
||||
const customAction = <div data-testid="custom-action">Custom Action</div>;
|
||||
const customAction = <div role="region" aria-label="custom action area">Custom Action</div>;
|
||||
const actions = [
|
||||
{ label: 'Save', onClick },
|
||||
customAction,
|
||||
@@ -93,6 +93,6 @@ describe('AuthZTitle', () => {
|
||||
render(<AuthZTitle {...defaultProps} actions={actions} />);
|
||||
|
||||
expect(screen.getByRole('button', { name: 'Save' })).toBeInTheDocument();
|
||||
expect(screen.getByTestId('custom-action')).toBeInTheDocument();
|
||||
expect(screen.getByRole('region', { name: 'custom action area' })).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,14 +4,14 @@ import userEvent from '@testing-library/user-event';
|
||||
import RoleCard from '.';
|
||||
|
||||
jest.mock('@openedx/paragon/icons', () => ({
|
||||
Delete: () => <svg data-testid="delete-icon" />,
|
||||
Person: () => <svg data-testid="person-icon" />,
|
||||
Delete: () => <svg role="img" aria-label="delete icon" />,
|
||||
Person: () => <svg role="img" aria-label="person icon" />,
|
||||
}));
|
||||
|
||||
jest.mock('./constants', () => ({
|
||||
actionsDictionary: {
|
||||
view: () => <svg data-testid="view-icon" />,
|
||||
manage: () => <svg data-testid="manage-icon" />,
|
||||
view: () => <svg role="img" aria-label="view action icon" />,
|
||||
manage: () => <svg role="img" aria-label="manage action icon" />,
|
||||
},
|
||||
}));
|
||||
|
||||
@@ -47,7 +47,7 @@ describe('RoleCard', () => {
|
||||
|
||||
// User counter with icon
|
||||
expect(screen.getByText('2')).toBeInTheDocument();
|
||||
expect(screen.getByTestId('person-icon')).toBeInTheDocument();
|
||||
expect(screen.getByRole('img', { name: 'person icon' })).toBeInTheDocument();
|
||||
|
||||
// Subtitle (object name)
|
||||
expect(screen.getByText('Test Library')).toBeInTheDocument();
|
||||
@@ -71,8 +71,8 @@ describe('RoleCard', () => {
|
||||
expect(screen.getByText('Manage')).toBeInTheDocument();
|
||||
|
||||
// Action icons
|
||||
expect(screen.getByTestId('view-icon')).toBeInTheDocument();
|
||||
expect(screen.getByTestId('manage-icon')).toBeInTheDocument();
|
||||
expect(screen.getByRole('img', { name: 'view action icon' })).toBeInTheDocument();
|
||||
expect(screen.getByRole('img', { name: 'manage action icon' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('does not show delete button when handleDelete is not passed', () => {
|
||||
@@ -82,7 +82,7 @@ describe('RoleCard', () => {
|
||||
|
||||
it('handles no userCounter gracefully', () => {
|
||||
renderWrapper(<RoleCard {...defaultProps} userCounter={null} />);
|
||||
expect(screen.queryByTestId('person-icon')).not.toBeInTheDocument();
|
||||
expect(screen.queryByRole('img', { name: 'person icon' })).not.toBeInTheDocument();
|
||||
expect(screen.queryByText('2')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
|
||||
@@ -8,9 +8,12 @@ import AuthZModule from './index';
|
||||
|
||||
jest.mock('./libraries-manager', () => ({
|
||||
// eslint-disable-next-line no-promise-executor-return
|
||||
LibrariesLayout: lazy(() => new Promise<{ default: ComponentType<any> }>(resolve => setTimeout(() => resolve({ default: () => <div data-testid="layout"><Outlet /></div> }), 100))),
|
||||
LibrariesTeamManager: () => <div data-testid="libraries-manager">Libraries Team Page</div>,
|
||||
LibrariesUserManager: () => <div data-testid="libraries-user-manager">Libraries User Page</div>,
|
||||
LibrariesLayout: lazy(() => new Promise<{ default: ComponentType<any> }>(resolve => setTimeout(
|
||||
() => resolve({ default: () => <div><Outlet /></div> }),
|
||||
100,
|
||||
))),
|
||||
LibrariesTeamManager: () => <div>Libraries Team Page</div>,
|
||||
LibrariesUserManager: () => <div>Libraries User Page</div>,
|
||||
}));
|
||||
|
||||
const createTestQueryClient = () => new QueryClient({
|
||||
@@ -42,10 +45,10 @@ describe('AuthZModule', () => {
|
||||
</IntlProvider>,
|
||||
);
|
||||
|
||||
expect(screen.getByTestId('loading-page')).toBeInTheDocument();
|
||||
expect(document.querySelector('.spinner-border')).toBeInTheDocument();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('libraries-manager')).toBeInTheDocument();
|
||||
expect(screen.getByText('Libraries Team Page')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -63,7 +66,7 @@ describe('AuthZModule', () => {
|
||||
</IntlProvider>,
|
||||
);
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('libraries-user-manager')).toBeInTheDocument();
|
||||
expect(screen.getByText('Libraries User Page')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -25,12 +25,12 @@ jest.mock('@src/authz-module/data/hooks', () => ({
|
||||
|
||||
jest.mock('./components/TeamTable', () => ({
|
||||
__esModule: true,
|
||||
default: () => <div data-testid="team-table">MockTeamTable</div>,
|
||||
default: () => <div role="table" aria-label="Team Members Table">Team member list</div>,
|
||||
}));
|
||||
|
||||
jest.mock('./components/AddNewTeamMemberModal', () => ({
|
||||
__esModule: true,
|
||||
AddNewTeamMemberTrigger: () => <div data-testid="add-team-member-trigger">MockAddNewTeamMemberTrigger</div>,
|
||||
AddNewTeamMemberTrigger: () => <button type="button">Add Team Member</button>,
|
||||
}));
|
||||
|
||||
jest.mock('../components/RoleCard', () => ({
|
||||
@@ -40,10 +40,10 @@ jest.mock('../components/RoleCard', () => ({
|
||||
description: string,
|
||||
permissionsByResource: any[]
|
||||
}) => (
|
||||
<div data-testid="role-card">
|
||||
<div>{title}</div>
|
||||
<div>{description}</div>
|
||||
<div>{permissionsByResource.length} permissions</div>
|
||||
<div role="article" aria-label={`Role: ${title}`}>
|
||||
<h3>{title}</h3>
|
||||
<p>{description}</p>
|
||||
<span>{permissionsByResource.length} permissions</span>
|
||||
</div>
|
||||
),
|
||||
}));
|
||||
@@ -108,10 +108,10 @@ describe('LibrariesTeamManager', () => {
|
||||
expect(screen.getByText('lib-001')).toBeInTheDocument(); // subtitle
|
||||
|
||||
// TeamTable is rendered
|
||||
expect(screen.getByTestId('team-table')).toBeInTheDocument();
|
||||
expect(screen.getByRole('table', { name: 'Team Members Table' })).toBeInTheDocument();
|
||||
|
||||
// AddNewTeamMemberTrigger is rendered
|
||||
expect(screen.getByTestId('add-team-member-trigger')).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: 'Add Team Member' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders role cards when "Roles" tab is selected', async () => {
|
||||
@@ -123,10 +123,10 @@ describe('LibrariesTeamManager', () => {
|
||||
const rolesTab = await screen.findByRole('tab', { name: /roles/i });
|
||||
await user.click(rolesTab);
|
||||
|
||||
const roleCards = await screen.findAllByTestId('role-card');
|
||||
const roleCards = await screen.findAllByRole('article', { name: /Role:/ });
|
||||
const rolesScope = within(roleCards[0]);
|
||||
expect(roleCards.length).toBe(1);
|
||||
expect(rolesScope.getByText('Instructor')).toBeInTheDocument();
|
||||
expect(rolesScope.getByRole('heading', { name: 'Instructor' })).toBeInTheDocument();
|
||||
expect(screen.getByText(/Can manage content/i)).toBeInTheDocument();
|
||||
expect(screen.getByText(/1 permissions/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -21,26 +21,27 @@ jest.mock('./AddNewTeamMemberModal', () => {
|
||||
isOpen, close, onSave, isLoading, formValues, handleChangeForm,
|
||||
}) => (
|
||||
isOpen ? (
|
||||
<div data-testid="add-team-member-modal">
|
||||
<button type="button" onClick={close} data-testid="close-modal">Close</button>
|
||||
<button type="button" onClick={onSave} data-testid="save-modal">Save</button>
|
||||
<div role="dialog" aria-label="Add New Team Member">
|
||||
<button type="button" onClick={close} aria-label="Close modal">Close</button>
|
||||
<button type="button" onClick={onSave} aria-label="Save team member">Save</button>
|
||||
<textarea
|
||||
name="users"
|
||||
value={formValues?.users || ''}
|
||||
onChange={handleChangeForm}
|
||||
data-testid="users-input"
|
||||
aria-label="Enter user emails or usernames"
|
||||
placeholder="Enter emails or usernames"
|
||||
/>
|
||||
<select
|
||||
name="role"
|
||||
value={formValues?.role || ''}
|
||||
onChange={handleChangeForm}
|
||||
data-testid="role-select"
|
||||
aria-label="Select role"
|
||||
>
|
||||
<option value="">Select role</option>
|
||||
<option value="admin">Admin</option>
|
||||
<option value="editor">Editor</option>
|
||||
</select>
|
||||
{isLoading && <div data-testid="loading-indicator">Loading...</div>}
|
||||
{isLoading && <div role="status" aria-label="Adding team member loader">Loading...</div>}
|
||||
</div>
|
||||
) : null
|
||||
);
|
||||
@@ -75,7 +76,7 @@ describe('AddNewTeamMemberTrigger', () => {
|
||||
const triggerButton = screen.getByRole('button', { name: /add new team member/i });
|
||||
await user.click(triggerButton);
|
||||
|
||||
expect(screen.getByTestId('add-team-member-modal')).toBeInTheDocument();
|
||||
expect(screen.getByRole('dialog', { name: 'Add New Team Member' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('closes modal when close button is clicked', async () => {
|
||||
@@ -85,12 +86,12 @@ describe('AddNewTeamMemberTrigger', () => {
|
||||
const triggerButton = screen.getByRole('button', { name: /add new team member/i });
|
||||
await user.click(triggerButton);
|
||||
|
||||
expect(screen.getByTestId('add-team-member-modal')).toBeInTheDocument();
|
||||
expect(screen.getByRole('dialog', { name: 'Add New Team Member' })).toBeInTheDocument();
|
||||
|
||||
const closeButton = screen.getByTestId('close-modal');
|
||||
const closeButton = screen.getByRole('button', { name: 'Close modal' });
|
||||
await user.click(closeButton);
|
||||
|
||||
expect(screen.queryByTestId('add-team-member-modal')).not.toBeInTheDocument();
|
||||
expect(screen.queryByRole('dialog', { name: 'Add New Team Member' })).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('calls addTeamMember with correct data when save is clicked', async () => {
|
||||
@@ -100,9 +101,9 @@ describe('AddNewTeamMemberTrigger', () => {
|
||||
const triggerButton = screen.getByRole('button', { name: /add new team member/i });
|
||||
await user.click(triggerButton);
|
||||
|
||||
const usersInput = screen.getByTestId('users-input');
|
||||
const roleSelect = screen.getByTestId('role-select');
|
||||
const saveButton = screen.getByTestId('save-modal');
|
||||
const usersInput = screen.getByRole('textbox', { name: 'Enter user emails or usernames' });
|
||||
const roleSelect = screen.getByRole('combobox', { name: 'Select role' });
|
||||
const saveButton = screen.getByRole('button', { name: 'Save team member' });
|
||||
|
||||
await user.type(usersInput, 'alice@example.com, bob@example.com');
|
||||
await user.selectOptions(roleSelect, 'editor');
|
||||
@@ -129,7 +130,7 @@ describe('AddNewTeamMemberTrigger', () => {
|
||||
const triggerButton = screen.getByRole('button', { name: /add new team member/i });
|
||||
await user.click(triggerButton);
|
||||
|
||||
const saveButton = screen.getByTestId('save-modal');
|
||||
const saveButton = screen.getByRole('button', { name: 'Save team member' });
|
||||
await user.click(saveButton);
|
||||
|
||||
// Simulate successful response with no errors
|
||||
@@ -143,7 +144,7 @@ describe('AddNewTeamMemberTrigger', () => {
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByTestId('add-team-member-modal')).not.toBeInTheDocument();
|
||||
expect(screen.queryByRole('dialog', { name: 'Add New Team Member' })).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
expect(screen.getByText('2 team members added successfully.')).toBeInTheDocument();
|
||||
@@ -156,7 +157,7 @@ describe('AddNewTeamMemberTrigger', () => {
|
||||
const triggerButton = screen.getByRole('button', { name: /add new team member/i });
|
||||
await user.click(triggerButton);
|
||||
|
||||
const saveButton = screen.getByTestId('save-modal');
|
||||
const saveButton = screen.getByRole('button', { name: 'Save team member' });
|
||||
await user.click(saveButton);
|
||||
|
||||
// Simulate partial success response
|
||||
@@ -176,7 +177,7 @@ describe('AddNewTeamMemberTrigger', () => {
|
||||
});
|
||||
|
||||
// Modal should remain open when there are errors
|
||||
expect(screen.getByTestId('add-team-member-modal')).toBeInTheDocument();
|
||||
expect(screen.getByRole('dialog', { name: 'Add New Team Member' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('displays only error toast when all additions fail', async () => {
|
||||
@@ -186,7 +187,7 @@ describe('AddNewTeamMemberTrigger', () => {
|
||||
const triggerButton = screen.getByRole('button', { name: /add new team member/i });
|
||||
await user.click(triggerButton);
|
||||
|
||||
const saveButton = screen.getByTestId('save-modal');
|
||||
const saveButton = screen.getByRole('button', { name: 'Save team member' });
|
||||
await user.click(saveButton);
|
||||
|
||||
// Simulate all failed response
|
||||
@@ -204,7 +205,7 @@ describe('AddNewTeamMemberTrigger', () => {
|
||||
});
|
||||
|
||||
// Modal should remain open when there are errors
|
||||
expect(screen.getByTestId('add-team-member-modal')).toBeInTheDocument();
|
||||
expect(screen.getByRole('dialog', { name: 'Add New Team Member' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('resets form values after successful addition with no errors', async () => {
|
||||
@@ -214,9 +215,9 @@ describe('AddNewTeamMemberTrigger', () => {
|
||||
const triggerButton = screen.getByRole('button', { name: /add new team member/i });
|
||||
await user.click(triggerButton);
|
||||
|
||||
const usersInput = screen.getByTestId('users-input');
|
||||
const roleSelect = screen.getByTestId('role-select');
|
||||
const saveButton = screen.getByTestId('save-modal');
|
||||
const usersInput = screen.getByRole('textbox', { name: 'Enter user emails or usernames' });
|
||||
const roleSelect = screen.getByRole('combobox', { name: 'Select role' });
|
||||
const saveButton = screen.getByRole('button', { name: 'Save team member' });
|
||||
|
||||
await user.type(usersInput, 'alice@example.com');
|
||||
await user.selectOptions(roleSelect, 'editor');
|
||||
@@ -232,8 +233,8 @@ describe('AddNewTeamMemberTrigger', () => {
|
||||
// Open modal again to check if form is reset
|
||||
await user.click(triggerButton);
|
||||
|
||||
const newUsersInput = screen.getByTestId('users-input');
|
||||
const newRoleSelect = screen.getByTestId('role-select');
|
||||
const newUsersInput = screen.getByRole('textbox', { name: 'Enter user emails or usernames' });
|
||||
const newRoleSelect = screen.getByRole('combobox', { name: 'Select role' });
|
||||
|
||||
expect(newUsersInput).toHaveValue('');
|
||||
expect(newRoleSelect).toHaveValue('');
|
||||
@@ -246,7 +247,7 @@ describe('AddNewTeamMemberTrigger', () => {
|
||||
const triggerButton = screen.getByRole('button', { name: /add new team member/i });
|
||||
await user.click(triggerButton);
|
||||
|
||||
const saveButton = screen.getByTestId('save-modal');
|
||||
const saveButton = screen.getByRole('button', { name: 'Save team member' });
|
||||
await user.click(saveButton);
|
||||
|
||||
// Simulate successful response
|
||||
@@ -289,7 +290,7 @@ describe('AddNewTeamMemberTrigger', () => {
|
||||
const triggerButton = screen.getByRole('button', { name: /add new team member/i });
|
||||
await user.click(triggerButton);
|
||||
|
||||
const saveButton = screen.getByTestId('save-modal');
|
||||
const saveButton = screen.getByRole('button', { name: 'Save team member' });
|
||||
await user.click(saveButton);
|
||||
|
||||
await waitFor(() => {
|
||||
@@ -351,16 +352,16 @@ describe('AddNewTeamMemberTrigger', () => {
|
||||
const triggerButton = screen.getByRole('button', { name: /add new team member/i });
|
||||
await user.click(triggerButton);
|
||||
|
||||
const userInput = screen.getByTestId('users-input');
|
||||
const roleSelect = screen.getByTestId('role-select');
|
||||
const userInput = screen.getByRole('textbox', { name: 'Enter user emails or usernames' });
|
||||
const roleSelect = screen.getByRole('combobox', { name: 'Select role' });
|
||||
await user.type(userInput, 'alice@example.com');
|
||||
await user.selectOptions(roleSelect, 'editor');
|
||||
|
||||
const saveButton = screen.getByTestId('save-modal');
|
||||
const saveButton = screen.getByRole('button', { name: 'Save team member' });
|
||||
await user.click(saveButton);
|
||||
|
||||
// should now reflect isPending = true
|
||||
const loadingIndicator = await screen.findByTestId('loading-indicator');
|
||||
const loadingIndicator = await screen.findByRole('status', { name: 'Adding team member loader' });
|
||||
expect(loadingIndicator).toBeInTheDocument();
|
||||
expect(loadingIndicator).toHaveTextContent('Loading...');
|
||||
|
||||
|
||||
@@ -26,9 +26,9 @@ jest.mock('./AssignNewRoleModal', () => {
|
||||
selectedRole,
|
||||
handleChangeSelectedRole,
|
||||
}: any) => (isOpen ? (
|
||||
<div data-testid="assign-new-role-modal">
|
||||
<div role="dialog" aria-label="Assign New Role">
|
||||
<h2>Add New Role</h2>
|
||||
<select data-testid="role-select" value={selectedRole} onChange={handleChangeSelectedRole}>
|
||||
<select value={selectedRole} onChange={handleChangeSelectedRole} aria-label="Select role">
|
||||
<option value="">Select a role</option>
|
||||
{roleOptions.map((role: any) => (
|
||||
<option key={role.role} value={role.role}>
|
||||
@@ -36,10 +36,10 @@ jest.mock('./AssignNewRoleModal', () => {
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<button type="button" onClick={onSave} disabled={isLoading} data-testid="save-button">
|
||||
<button type="button" onClick={onSave} disabled={isLoading} aria-label="Save role assignment">
|
||||
{isLoading ? 'Saving...' : 'Save'}
|
||||
</button>
|
||||
<button type="button" onClick={close} data-testid="cancel-button">
|
||||
<button type="button" onClick={close} aria-label="Cancel role assignment">
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
@@ -106,7 +106,7 @@ describe('AssignNewRoleTrigger', () => {
|
||||
it('does not show modal initially', () => {
|
||||
renderComponent();
|
||||
|
||||
expect(screen.queryByTestId('assign-new-role-modal')).not.toBeInTheDocument();
|
||||
expect(screen.queryByRole('dialog', { name: 'Assign New Role' })).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('does not show toast initially', () => {
|
||||
@@ -124,7 +124,7 @@ describe('AssignNewRoleTrigger', () => {
|
||||
const triggerButton = screen.getByRole('button', { name: /add new role/i });
|
||||
await user.click(triggerButton);
|
||||
|
||||
expect(screen.getByTestId('assign-new-role-modal')).toBeInTheDocument();
|
||||
expect(screen.getByRole('dialog', { name: 'Assign New Role' })).toBeInTheDocument();
|
||||
expect(screen.getByRole('heading', { name: /add new role/i })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -134,11 +134,11 @@ describe('AssignNewRoleTrigger', () => {
|
||||
|
||||
// Open modal
|
||||
await user.click(screen.getByRole('button', { name: /add new role/i }));
|
||||
expect(screen.getByTestId('assign-new-role-modal')).toBeInTheDocument();
|
||||
expect(screen.getByRole('dialog', { name: 'Assign New Role' })).toBeInTheDocument();
|
||||
|
||||
// Close modal
|
||||
await user.click(screen.getByTestId('cancel-button'));
|
||||
expect(screen.queryByTestId('assign-new-role-modal')).not.toBeInTheDocument();
|
||||
await user.click(screen.getByRole('button', { name: 'Cancel role assignment' }));
|
||||
expect(screen.queryByRole('dialog', { name: 'Assign New Role' })).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -149,7 +149,7 @@ describe('AssignNewRoleTrigger', () => {
|
||||
|
||||
await user.click(screen.getByRole('button', { name: /add new role/i }));
|
||||
|
||||
const roleSelect = screen.getByTestId('role-select');
|
||||
const roleSelect = screen.getByRole('combobox', { name: 'Select role' });
|
||||
await user.selectOptions(roleSelect, 'admin');
|
||||
|
||||
expect(roleSelect).toHaveValue('admin');
|
||||
@@ -163,11 +163,11 @@ describe('AssignNewRoleTrigger', () => {
|
||||
await user.click(screen.getByRole('button', { name: /add new role/i }));
|
||||
|
||||
// Select a role
|
||||
const roleSelect = screen.getByTestId('role-select');
|
||||
const roleSelect = screen.getByRole('combobox', { name: 'Select role' });
|
||||
await user.selectOptions(roleSelect, choosenRole);
|
||||
|
||||
// Click save
|
||||
await user.click(screen.getByTestId('save-button'));
|
||||
await user.click(screen.getByRole('button', { name: 'Save role assignment' }));
|
||||
|
||||
expect(mockMutate).toHaveBeenCalledWith(
|
||||
{
|
||||
@@ -191,15 +191,15 @@ describe('AssignNewRoleTrigger', () => {
|
||||
await user.click(screen.getByRole('button', { name: /add new role/i }));
|
||||
|
||||
// Select a role that user already has
|
||||
const roleSelect = screen.getByTestId('role-select');
|
||||
const roleSelect = screen.getByRole('combobox', { name: 'Select role' });
|
||||
await user.selectOptions(roleSelect, choosenRole);
|
||||
|
||||
await user.click(screen.getByTestId('save-button'));
|
||||
await user.click(screen.getByRole('button', { name: 'Save role assignment' }));
|
||||
|
||||
// Should not call assignTeamMembersRole
|
||||
expect(mockMutate).not.toHaveBeenCalled();
|
||||
// Modal should be closed
|
||||
expect(screen.queryByTestId('assign-new-role-modal')).not.toBeInTheDocument();
|
||||
expect(screen.queryByRole('dialog', { name: 'Assign New Role' })).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -215,7 +215,7 @@ describe('AssignNewRoleTrigger', () => {
|
||||
|
||||
await user.click(screen.getByRole('button', { name: /add new role/i }));
|
||||
|
||||
expect(screen.getByTestId('save-button')).toBeDisabled();
|
||||
expect(screen.getByRole('button', { name: 'Save role assignment' })).toBeDisabled();
|
||||
expect(screen.getByText('Saving...')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -227,10 +227,10 @@ describe('AssignNewRoleTrigger', () => {
|
||||
|
||||
await user.click(screen.getByRole('button', { name: /add new role/i }));
|
||||
|
||||
const roleSelect = screen.getByTestId('role-select');
|
||||
const roleSelect = screen.getByRole('combobox', { name: 'Select role' });
|
||||
await user.selectOptions(roleSelect, 'admin');
|
||||
|
||||
await user.click(screen.getByTestId('save-button'));
|
||||
await user.click(screen.getByRole('button', { name: 'Save role assignment' }));
|
||||
|
||||
// Simulate successful API call
|
||||
const onSuccessCallback = mockMutate.mock.calls[0][1].onSuccess;
|
||||
@@ -247,22 +247,22 @@ describe('AssignNewRoleTrigger', () => {
|
||||
|
||||
await user.click(screen.getByRole('button', { name: /add new role/i }));
|
||||
|
||||
const roleSelect = screen.getByTestId('role-select');
|
||||
const roleSelect = screen.getByRole('combobox', { name: 'Select role' });
|
||||
await user.selectOptions(roleSelect, 'admin');
|
||||
|
||||
await user.click(screen.getByTestId('save-button'));
|
||||
await user.click(screen.getByRole('button', { name: 'Save role assignment' }));
|
||||
|
||||
// Simulate successful API call
|
||||
const onSuccessCallback = mockMutate.mock.calls[0][1].onSuccess;
|
||||
onSuccessCallback({ errors: [] });
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByTestId('assign-new-role-modal')).not.toBeInTheDocument();
|
||||
expect(screen.queryByRole('dialog', { name: 'Assign New Role' })).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Open modal again to check if role is reset
|
||||
await user.click(screen.getByRole('button', { name: /add new role/i }));
|
||||
expect(screen.getByTestId('role-select')).toHaveValue('');
|
||||
expect(screen.getByRole('combobox', { name: 'Select role' })).toHaveValue('');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -273,15 +273,15 @@ describe('AssignNewRoleTrigger', () => {
|
||||
renderComponent();
|
||||
|
||||
await user.click(screen.getByRole('button', { name: /add new role/i }));
|
||||
await user.selectOptions(screen.getByTestId('role-select'), 'admin');
|
||||
await user.click(screen.getByTestId('save-button'));
|
||||
await user.selectOptions(screen.getByRole('combobox', { name: 'Select role' }), 'admin');
|
||||
await user.click(screen.getByRole('button', { name: 'Save role assignment' }));
|
||||
|
||||
const { onSuccess } = mockMutate.mock.calls[0][1];
|
||||
onSuccess({ errors: [{ error: 'role_assignment_error' }] });
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText(/Something went wrong/i)).toBeInTheDocument();
|
||||
expect(screen.getByTestId('role-select')).toHaveValue(''); // role reset
|
||||
expect(screen.getByRole('combobox', { name: 'Select role' })).toHaveValue(''); // role reset
|
||||
});
|
||||
});
|
||||
|
||||
@@ -306,8 +306,8 @@ describe('AssignNewRoleTrigger', () => {
|
||||
|
||||
// Open modal and select a role
|
||||
await user.click(screen.getByRole('button', { name: /add new role/i }));
|
||||
await user.selectOptions(screen.getByTestId('role-select'), 'admin');
|
||||
await user.click(screen.getByTestId('save-button'));
|
||||
await user.selectOptions(screen.getByRole('combobox', { name: 'Select role' }), 'admin');
|
||||
await user.click(screen.getByRole('button', { name: 'Save role assignment' }));
|
||||
|
||||
// Wait for the error toast to appear with a retry button
|
||||
await waitFor(() => {
|
||||
|
||||
@@ -7,10 +7,8 @@ import userEvent from '@testing-library/user-event';
|
||||
import TableControlBar from './TableControlBar';
|
||||
|
||||
jest.mock('./MultipleChoiceFilter', () => {
|
||||
// eslint-disable-next-line react/prop-types
|
||||
const MockMultipleChoiceFilter = (props) => (
|
||||
// eslint-disable-next-line react/prop-types
|
||||
<div data-testid="multiple-choice-filter" data-column-id={props.id || props.accessor}>
|
||||
const MockMultipleChoiceFilter = (props: { id?: string; accessor?: string }) => (
|
||||
<div role="group" aria-label={`Filter by ${props.id || props.accessor}`}>
|
||||
Multiple Choice Filter
|
||||
</div>
|
||||
);
|
||||
@@ -20,7 +18,7 @@ jest.mock('./MultipleChoiceFilter', () => {
|
||||
|
||||
jest.mock('./SortDropdown', () => {
|
||||
const MockSortDropdown = () => (
|
||||
<div data-testid="sort-dropdown">
|
||||
<div role="group" aria-label="Sort options">
|
||||
Sort Dropdown
|
||||
</div>
|
||||
);
|
||||
@@ -31,7 +29,7 @@ jest.mock('./SortDropdown', () => {
|
||||
jest.mock('./SearchFilter', () => {
|
||||
// eslint-disable-next-line react/prop-types
|
||||
const MockSearchFilter = (props) => (
|
||||
<div data-testid="search-filter">
|
||||
<div role="search" aria-label="Search filter">
|
||||
<input
|
||||
// eslint-disable-next-line react/prop-types
|
||||
placeholder={props.placeholder}
|
||||
@@ -39,7 +37,7 @@ jest.mock('./SearchFilter', () => {
|
||||
value={props.filterValue || ''}
|
||||
// eslint-disable-next-line react/prop-types
|
||||
onChange={(e) => props.setFilter(e.target.value)}
|
||||
data-testid="search-input"
|
||||
aria-label="Search input"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
@@ -74,7 +72,7 @@ describe('TableControlBar', () => {
|
||||
it('should render basic structure with SortDropdown and RowStatus', () => {
|
||||
renderWithContext();
|
||||
|
||||
expect(screen.getByTestId('sort-dropdown')).toBeInTheDocument();
|
||||
expect(screen.getByRole('group', { name: 'Sort options' })).toBeInTheDocument();
|
||||
const container = screen.getByText('Sort Dropdown').closest('.pgn__data-table-status-bar');
|
||||
expect(container).toHaveClass('pgn__data-table-status-bar', 'mb-3', 'flex-wrap');
|
||||
});
|
||||
@@ -131,9 +129,9 @@ describe('TableControlBar', () => {
|
||||
|
||||
renderWithContext(contextWithCheckboxColumn);
|
||||
|
||||
const multipleChoiceFilter = screen.getByTestId('multiple-choice-filter');
|
||||
const multipleChoiceFilter = screen.getByRole('group', { name: 'Filter by roles' });
|
||||
expect(multipleChoiceFilter).toBeInTheDocument();
|
||||
expect(multipleChoiceFilter).toHaveAttribute('data-column-id', 'roles');
|
||||
expect(screen.getByText('Multiple Choice Filter')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render SearchFilter for columns with TextFilter', () => {
|
||||
@@ -154,8 +152,8 @@ describe('TableControlBar', () => {
|
||||
|
||||
renderWithContext(contextWithTextColumn);
|
||||
|
||||
expect(screen.getByTestId('search-filter')).toBeInTheDocument();
|
||||
expect(screen.getByTestId('search-input')).toBeInTheDocument();
|
||||
expect(screen.getByRole('search', { name: 'Search filter' })).toBeInTheDocument();
|
||||
expect(screen.getByRole('textbox', { name: 'Search input' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should not render any filter for unsupported Filter types', () => {
|
||||
@@ -176,8 +174,8 @@ describe('TableControlBar', () => {
|
||||
renderWithContext(contextWithCustomFilter);
|
||||
|
||||
// Only SortDropdown should be present, no filter components
|
||||
expect(screen.getByTestId('sort-dropdown')).toBeInTheDocument();
|
||||
expect(screen.queryByTestId('search-filter')).not.toBeInTheDocument();
|
||||
expect(screen.queryByTestId('multiple-choice-filter')).not.toBeInTheDocument();
|
||||
expect(screen.getByRole('group', { name: 'Sort options' })).toBeInTheDocument();
|
||||
expect(screen.queryByRole('search', { name: 'Search filter' })).not.toBeInTheDocument();
|
||||
expect(screen.queryByRole('group', { name: /Filter by/ })).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -49,14 +49,12 @@ const TestComponent = () => {
|
||||
const context = useLibraryAuthZ();
|
||||
return (
|
||||
<div>
|
||||
<div data-testid="username">{context.username}</div>
|
||||
<div data-testid="libraryId">{context.libraryId}</div>
|
||||
<div data-testid="canManageTeam">{context.canManageTeam ? 'true' : 'false'}</div>
|
||||
<div data-testid="roles">{Array.isArray(context.roles) ? context.roles.length : 'undefined'}</div>
|
||||
<div data-testid="permissions">
|
||||
{Array.isArray(context.permissions) ? context.permissions.length : 'undefined'}
|
||||
</div>
|
||||
<div data-testid="resources">{Array.isArray(context.resources) ? context.resources.length : 'undefined'}</div>
|
||||
<div>Username: {context.username}</div>
|
||||
<div>Library ID: {context.libraryId}</div>
|
||||
<div>Can manage team: {context.canManageTeam ? 'Yes' : 'No'}</div>
|
||||
<div>Roles count: {Array.isArray(context.roles) ? context.roles.length : 'undefined'}</div>
|
||||
<div>Permissions count: {Array.isArray(context.permissions) ? context.permissions.length : 'undefined'}</div>
|
||||
<div>Resources count: {Array.isArray(context.resources) ? context.resources.length : 'undefined'}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -109,12 +107,12 @@ describe('LibraryAuthZProvider', () => {
|
||||
</LibraryAuthZProvider>,
|
||||
);
|
||||
|
||||
expect(screen.getByTestId('username')).toHaveTextContent('testuser');
|
||||
expect(screen.getByTestId('libraryId')).toHaveTextContent('lib123');
|
||||
expect(screen.getByTestId('canManageTeam')).toHaveTextContent('true');
|
||||
expect(Number(screen.getByTestId('roles').textContent)).not.toBeNaN();
|
||||
expect(Number(screen.getByTestId('permissions').textContent)).not.toBeNaN();
|
||||
expect(Number(screen.getByTestId('resources').textContent)).not.toBeNaN();
|
||||
expect(screen.getByText(/Username: testuser/)).toBeInTheDocument();
|
||||
expect(screen.getByText(/Library ID: lib123/)).toBeInTheDocument();
|
||||
expect(screen.getByText(/Can manage team: Yes/)).toBeInTheDocument();
|
||||
expect(screen.getByText(/Roles count: \d+/)).toBeInTheDocument();
|
||||
expect(screen.getByText(/Permissions count: \d+/)).toBeInTheDocument();
|
||||
expect(screen.getByText(/Resources count: \d+/)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('throws error when user lacks both view and manage permissions', () => {
|
||||
@@ -148,7 +146,7 @@ describe('LibraryAuthZProvider', () => {
|
||||
</LibraryAuthZProvider>,
|
||||
);
|
||||
|
||||
expect(screen.getByTestId('canManageTeam')).toHaveTextContent('false');
|
||||
expect(screen.getByText(/Can manage team: No/)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('throws error when libraryId is missing', () => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Spinner, Container } from '@openedx/paragon';
|
||||
|
||||
const LoadingPage = () => (
|
||||
<Container className="d-flex vh-100" data-testid="loading-page">
|
||||
<Container className="d-flex vh-100">
|
||||
<Spinner
|
||||
variant="primary"
|
||||
animation="border"
|
||||
|
||||
Reference in New Issue
Block a user