Skip to content

Commit 50dbaee

Browse files
committed
fix: solve coverage issues
1 parent 3db2ce7 commit 50dbaee

3 files changed

Lines changed: 188 additions & 0 deletions

File tree

src/authz/hooks.test.ts

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { renderHook } from '@testing-library/react';
2+
import { useUserPermissions } from '@src/authz/data/apiHooks';
3+
import { mockWaffleFlags } from '@src/data/apiHooks.mock';
4+
import { useUserPermissionsWithAuthzCourse } from './hooks';
5+
import { COURSE_PERMISSIONS } from './constants';
6+
7+
jest.mock('@src/authz/data/apiHooks', () => ({
8+
useUserPermissions: jest.fn(),
9+
}));
10+
11+
const courseId = 'course-v1:org+course+run';
12+
const permissions = {
13+
canView: { action: COURSE_PERMISSIONS.VIEW_GRADING_SETTINGS, scope: courseId },
14+
canEdit: { action: COURSE_PERMISSIONS.EDIT_GRADING_SETTINGS, scope: courseId },
15+
};
16+
17+
describe('useUserPermissionsWithAuthzCourse', () => {
18+
beforeEach(() => {
19+
jest.clearAllMocks();
20+
jest.mocked(useUserPermissions).mockReturnValue({
21+
isLoading: false,
22+
data: undefined,
23+
} as unknown as ReturnType<typeof useUserPermissions>);
24+
});
25+
26+
it('defaults all permissions to true when authz is disabled', () => {
27+
mockWaffleFlags({ enableAuthzCourseAuthoring: false });
28+
29+
const { result } = renderHook(() => useUserPermissionsWithAuthzCourse(courseId, permissions));
30+
31+
expect(result.current.isLoading).toBe(false);
32+
expect(result.current.isAuthzEnabled).toBe(false);
33+
expect(result.current.permissions.canView).toBe(true);
34+
expect(result.current.permissions.canEdit).toBe(true);
35+
});
36+
37+
it('returns actual permission values when authz is enabled and permissions are loaded', () => {
38+
mockWaffleFlags({ enableAuthzCourseAuthoring: true });
39+
jest.mocked(useUserPermissions).mockReturnValue({
40+
isLoading: false,
41+
data: { canView: true, canEdit: false },
42+
} as unknown as ReturnType<typeof useUserPermissions>);
43+
44+
const { result } = renderHook(() => useUserPermissionsWithAuthzCourse(courseId, permissions));
45+
46+
expect(result.current.isLoading).toBe(false);
47+
expect(result.current.isAuthzEnabled).toBe(true);
48+
expect(result.current.permissions.canView).toBe(true);
49+
expect(result.current.permissions.canEdit).toBe(false);
50+
});
51+
52+
it('returns isLoading=true and empty permissions while authz permissions are loading', () => {
53+
mockWaffleFlags({ enableAuthzCourseAuthoring: true });
54+
jest.mocked(useUserPermissions).mockReturnValue({
55+
isLoading: true,
56+
data: undefined,
57+
} as unknown as ReturnType<typeof useUserPermissions>);
58+
59+
const { result } = renderHook(() => useUserPermissionsWithAuthzCourse(courseId, permissions));
60+
61+
expect(result.current.isLoading).toBe(true);
62+
expect(result.current.isAuthzEnabled).toBe(true);
63+
expect(result.current.permissions).toEqual({});
64+
});
65+
66+
it('falls back to false for permissions absent from server response when authz is enabled', () => {
67+
mockWaffleFlags({ enableAuthzCourseAuthoring: true });
68+
jest.mocked(useUserPermissions).mockReturnValue({
69+
isLoading: false,
70+
data: {},
71+
} as unknown as ReturnType<typeof useUserPermissions>);
72+
73+
const { result } = renderHook(() => useUserPermissionsWithAuthzCourse(courseId, permissions));
74+
75+
expect(result.current.permissions.canView).toBe(false);
76+
expect(result.current.permissions.canEdit).toBe(false);
77+
});
78+
});

src/grading-settings/assignment-section/AssignmentSection.test.jsx

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { render, waitFor, fireEvent } from '@testing-library/react';
33
import { IntlProvider } from '@edx/frontend-platform/i18n';
44

55
import AssignmentSection from '.';
6+
import AssignmentItem from './assignments/AssignmentItem';
7+
import AssignmentTypeName from './assignments/AssignmentTypeName';
68
import messages from './messages';
79

810
const testObj = {};
@@ -108,6 +110,45 @@ describe('<AssignmentSection />', () => {
108110
expect(getByText(messages.totalNumberErrorMessage.defaultMessage)).toBeInTheDocument();
109111
});
110112
});
113+
it('should disable all inputs and delete button when isEditable is false', async () => {
114+
const { getAllByRole, getByText } = render(<RootWrapper isEditable={false} />);
115+
await waitFor(() => {
116+
const inputs = getAllByRole('textbox').concat(getAllByRole('spinbutton'));
117+
inputs.forEach((input) => expect(input).toBeDisabled());
118+
const deleteBtn = getByText(messages.assignmentDeleteButton.defaultMessage).closest('button');
119+
expect(deleteBtn).toBeDisabled();
120+
});
121+
});
122+
123+
it('renders AssignmentItem with default disabled=false when prop is omitted', () => {
124+
const { getByTestId } = render(
125+
<IntlProvider locale="en">
126+
<ul>
127+
<AssignmentItem
128+
title="Test"
129+
descriptions="Test description"
130+
type="text"
131+
name="shortLabel"
132+
className="test-class"
133+
onChange={jest.fn()}
134+
/>
135+
</ul>
136+
</IntlProvider>,
137+
);
138+
expect(getByTestId('assignment-shortLabel-input')).not.toBeDisabled();
139+
});
140+
141+
it('renders AssignmentTypeName with default disabled=false when prop is omitted', () => {
142+
const { getByTestId } = render(
143+
<IntlProvider locale="en">
144+
<ul>
145+
<AssignmentTypeName value="Homework" onChange={jest.fn()} />
146+
</ul>
147+
</IntlProvider>,
148+
);
149+
expect(getByTestId('assignment-type-name-input')).not.toBeDisabled();
150+
});
151+
111152
it('checking correct error msg if total weight have negative number', async () => {
112153
const { getByText, getByTestId } = render(<RootWrapper />);
113154
await waitFor(() => {

src/grading-settings/grading-scale/GradingScale.test.jsx

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { initializeMockApp } from '@edx/frontend-platform';
44
import { render, waitFor, fireEvent } from '@testing-library/react';
55

66
import GradingScale from './GradingScale';
7+
import GradingScaleHandle from './components/GradingScaleHandle';
8+
import GradingScaleSegment from './components/GradingScaleSegment.tsx';
79

810
const gradeCutoffs = { A: 0.9, B: 0.8, C: 0.7 };
911

@@ -122,6 +124,73 @@ describe('<GradingScale />', () => {
122124
});
123125
});
124126

127+
it('renders GradingScaleHandle with default isEditable=true when prop is omitted', () => {
128+
const gradingSegments = [
129+
{ current: 90, previous: 0 },
130+
{ current: 100, previous: 90 },
131+
];
132+
const { container } = render(
133+
<GradingScaleHandle
134+
idx={0}
135+
value={90}
136+
gradingSegments={gradingSegments}
137+
getHandleProps={() => ({})}
138+
/>,
139+
);
140+
const btn = container.querySelector('.grading-scale-segment-btn-resize');
141+
expect(btn).toBeInTheDocument();
142+
expect(btn).not.toBeDisabled();
143+
});
144+
145+
it('renders GradingScaleSegment with default isEditable=true when prop is omitted', async () => {
146+
const gradingSegments = [
147+
{ current: 100, previous: 0 },
148+
{ current: 50, previous: 0 },
149+
{ current: 30, previous: 0 },
150+
];
151+
const { getAllByTestId } = render(
152+
<IntlProvider locale="en" messages={{}}>
153+
<GradingScaleSegment
154+
idx={1}
155+
value={50}
156+
getSegmentProps={() => ({})}
157+
handleLetterChange={jest.fn()}
158+
letters={['A', 'B', 'C']}
159+
gradingSegments={gradingSegments}
160+
removeGradingSegment={jest.fn()}
161+
/>
162+
</IntlProvider>,
163+
);
164+
await waitFor(() => {
165+
getAllByTestId('grading-scale-segment-input').forEach((input) => expect(input).not.toBeDisabled());
166+
});
167+
});
168+
169+
it('should disable inputs and buttons when isEditable is false', async () => {
170+
const { getAllByTestId, queryAllByTestId } = render(
171+
<IntlProvider locale="en" messages={{}}>
172+
<GradingScale
173+
gradeCutoffs={gradeCutoffs}
174+
gradeLetters={gradeLetters}
175+
sortedGrades={sortedGrades}
176+
resetDataRef={{ current: false }}
177+
showSavePrompt={jest.fn()}
178+
setShowSuccessAlert={jest.fn()}
179+
setGradingData={jest.fn()}
180+
setOverrideInternetConnectionAlert={jest.fn()}
181+
setEligibleGrade={jest.fn()}
182+
isEditable={false}
183+
/>
184+
</IntlProvider>,
185+
);
186+
await waitFor(() => {
187+
const segmentInputs = getAllByTestId('grading-scale-segment-input');
188+
segmentInputs.forEach((input) => expect(input).toBeDisabled());
189+
const removeButtons = queryAllByTestId('grading-scale-btn-remove');
190+
removeButtons.forEach((btn) => expect(btn).toBeDisabled());
191+
});
192+
});
193+
125194
it('should render GradingScale component with more than 5 grades', async () => {
126195
const { getAllByTestId } = render(
127196
<IntlProvider locale="en" messages={{}}>

0 commit comments

Comments
 (0)