Skip to content

Commit b0c02c9

Browse files
committed
test: add some missing tests
1 parent f1683f6 commit b0c02c9

4 files changed

Lines changed: 396 additions & 4 deletions

File tree

src/authz-module/components/AuthZTitle.test.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,32 @@ describe('AuthZTitle', () => {
5959
expect(onClick).toHaveBeenCalled();
6060
});
6161
});
62+
63+
it('renders action buttons with icons', () => {
64+
const mockIcon = () => <span data-testid="mock-icon">Icon</span>;
65+
const onClick = jest.fn();
66+
const actions = [
67+
{ label: 'Save', icon: mockIcon, onClick },
68+
];
69+
70+
render(<AuthZTitle {...defaultProps} actions={actions} />);
71+
72+
const button = screen.getByRole('button', { name: 'Icon Save' });
73+
expect(button).toBeInTheDocument();
74+
expect(screen.getByTestId('mock-icon')).toBeInTheDocument();
75+
});
76+
77+
it('renders ReactNode actions alongside button actions', () => {
78+
const onClick = jest.fn();
79+
const customAction = <div data-testid="custom-action">Custom Action</div>;
80+
const actions = [
81+
{ label: 'Save', onClick },
82+
customAction,
83+
];
84+
85+
render(<AuthZTitle {...defaultProps} actions={actions} />);
86+
87+
expect(screen.getByRole('button', { name: 'Save' })).toBeInTheDocument();
88+
expect(screen.getByTestId('custom-action')).toBeInTheDocument();
89+
});
6290
});

src/authz-module/data/hooks.test.tsx

Lines changed: 129 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ import { ReactNode } from 'react';
22
import { act, renderHook, waitFor } from '@testing-library/react';
33
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
44
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
5-
import { useLibrary, useTeamMembers } from './hooks';
5+
import {
6+
useLibrary, useTeamMembers, useAddTeamMember, useTeamRoles,
7+
} from './hooks';
68

79
jest.mock('@edx/frontend-platform/auth', () => ({
810
getAuthenticatedHttpClient: jest.fn(),
@@ -30,6 +32,24 @@ const mockLibrary = {
3032
slug: 'test-library',
3133
};
3234

35+
const mockTeamRoles = [
36+
{
37+
id: 'admin',
38+
name: 'Administrator',
39+
description: 'Full access to the library',
40+
},
41+
{
42+
id: 'author',
43+
name: 'Author',
44+
description: 'Can create and edit content',
45+
},
46+
{
47+
id: 'collaborator',
48+
name: 'Collaborator',
49+
description: 'Can view and comment on content',
50+
},
51+
];
52+
3353
const createWrapper = () => {
3454
const queryClient = new QueryClient({
3555
defaultOptions: {
@@ -113,13 +133,119 @@ describe('useLibrary', () => {
113133

114134
const wrapper = createWrapper();
115135
try {
116-
act(()=>{
136+
act(() => {
117137
renderHook(() => useLibrary('lib123'), { wrapper });
118-
})
138+
});
119139
} catch (e) {
120140
expect(e).toEqual(new Error('Not found'));
121141
}
122142

123143
expect(getAuthenticatedHttpClient).toHaveBeenCalled();
124144
});
125145
});
146+
147+
describe('useAddTeamMember', () => {
148+
beforeEach(() => {
149+
jest.clearAllMocks();
150+
});
151+
152+
it('successfully adds team members', async () => {
153+
const mockResponse = {
154+
completed: [
155+
{
156+
user: 'jdoe',
157+
status: 'role_added',
158+
},
159+
{
160+
161+
status: 'already_has_role',
162+
},
163+
],
164+
errors: [],
165+
};
166+
167+
getAuthenticatedHttpClient.mockReturnValue({
168+
put: jest.fn().mockResolvedValue({ data: mockResponse }),
169+
});
170+
171+
const { result } = renderHook(() => useAddTeamMember(), {
172+
wrapper: createWrapper(),
173+
});
174+
175+
const addTeamMemberData = {
176+
scope: 'lib:123',
177+
users: ['jdoe'],
178+
role: 'author',
179+
};
180+
181+
await act(async () => {
182+
result.current.mutate({ data: addTeamMemberData });
183+
});
184+
185+
await waitFor(() => expect(result.current.isSuccess).toBe(true));
186+
187+
expect(getAuthenticatedHttpClient).toHaveBeenCalled();
188+
expect(result.current.data).toEqual(mockResponse);
189+
});
190+
191+
it('handles error when adding team members fails', async () => {
192+
getAuthenticatedHttpClient.mockReturnValue({
193+
put: jest.fn().mockRejectedValue(new Error('Failed to add members')),
194+
});
195+
196+
const { result } = renderHook(() => useAddTeamMember(), {
197+
wrapper: createWrapper(),
198+
});
199+
200+
const addTeamMemberData = {
201+
scope: 'lib:123',
202+
users: ['jdoe'],
203+
role: 'author',
204+
};
205+
206+
await act(async () => {
207+
result.current.mutate({ data: addTeamMemberData });
208+
});
209+
210+
await waitFor(() => expect(result.current.isError).toBe(true));
211+
212+
expect(getAuthenticatedHttpClient).toHaveBeenCalled();
213+
expect(result.current.error).toEqual(new Error('Failed to add members'));
214+
});
215+
});
216+
217+
describe('useTeamRoles', () => {
218+
beforeEach(() => {
219+
jest.clearAllMocks();
220+
});
221+
222+
it('returns team roles when API call succeeds', async () => {
223+
getAuthenticatedHttpClient.mockReturnValue({
224+
get: jest.fn().mockResolvedValue({ data: mockTeamRoles }),
225+
});
226+
227+
const { result } = renderHook(() => useTeamRoles('lib:123'), {
228+
wrapper: createWrapper(),
229+
});
230+
231+
await waitFor(() => expect(result.current.data).toEqual(mockTeamRoles));
232+
233+
expect(getAuthenticatedHttpClient).toHaveBeenCalled();
234+
});
235+
236+
it('throws on error when API call fails', () => {
237+
getAuthenticatedHttpClient.mockReturnValue({
238+
get: jest.fn().mockRejectedValue(new Error('Failed to fetch roles')),
239+
});
240+
241+
try {
242+
act(() => {
243+
renderHook(() => useTeamRoles('lib:123'), { wrapper: createWrapper() });
244+
});
245+
} catch (e) {
246+
expect(e).toEqual(new Error('Failed to fetch roles'));
247+
}
248+
249+
expect(getAuthenticatedHttpClient).toHaveBeenCalled();
250+
});
251+
});

0 commit comments

Comments
 (0)