Skip to content

Commit

Permalink
feat: staff endpoint in view class buttons
Browse files Browse the repository at this point in the history
  • Loading branch information
01001110J committed Jun 18, 2024
1 parent 725e403 commit 762879c
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 11 deletions.
6 changes: 3 additions & 3 deletions src/features/Classes/Class/ClassPage/Actions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {
} from '@edx/paragon';
import { MoreVert } from '@edx/paragon/icons';

import { setAssignStaffRole } from 'helpers';

import AddClass from 'features/Courses/AddClass';
import EnrollStudent from 'features/Classes/EnrollStudent';

Expand Down Expand Up @@ -47,9 +49,7 @@ const Actions = ({ previousPage }) => {
</Button>
<Button
as="a"
href={classLink}
target="_blank"
rel="noopener noreferrer"
onClick={() => setAssignStaffRole(classLink, classId)}
className="text-decoration-none text-white button-view-class mr-3"
>
<i className="fa-solid fa-arrow-up-right-from-square mr-2 mb-1" />
Expand Down
6 changes: 2 additions & 4 deletions src/features/Classes/ClassesTable/columns.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { getConfig } from '@edx/frontend-platform';

import AddClass from 'features/Courses/AddClass';

import { formatUTCDate } from 'helpers';
import { formatUTCDate, setAssignStaffRole } from 'helpers';

const columns = [
{
Expand Down Expand Up @@ -107,9 +107,7 @@ const columns = [
Edit Class
</Dropdown.Item>
<Dropdown.Item
href={`${getConfig().LEARNING_MICROFRONTEND_URL}/course/${classId}/home`}
target="_blank"
rel="noreferrer"
onClick={() => setAssignStaffRole(`${getConfig().LEARNING_MICROFRONTEND_URL}/course/${classId}/home`, classId)}
className="text-truncate text-decoration-none custom-text-black"
>
<i className="fa-solid fa-arrow-up-right-from-square mr-2 mb-1" />
Expand Down
4 changes: 2 additions & 2 deletions src/features/Courses/CourseDetailTable/columns.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Badge } from 'react-paragon-topaz';
import { MoreHoriz } from '@edx/paragon/icons';
import { getConfig } from '@edx/frontend-platform';

import { formatUTCDate } from 'helpers';
import { formatUTCDate, setAssignStaffRole } from 'helpers';

import AddClass from 'features/Courses/AddClass';

Expand Down Expand Up @@ -121,9 +121,9 @@ const columns = [
/>
<Dropdown.Menu>
<Dropdown.Item
href={`${getConfig().LEARNING_MICROFRONTEND_URL}/course/${classId}/home`}
target="_blank"
rel="noreferrer"
onClick={() => setAssignStaffRole(`${getConfig().LEARNING_MICROFRONTEND_URL}/course/${classId}/home`, classId)}
className="text-truncate text-decoration-none custom-text-black"
>
<i className="fa-regular fa-eye mr-2 mb-1" />
Expand Down
25 changes: 24 additions & 1 deletion src/features/Main/data/_test_/api.test.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
import { getInstitutionName } from 'features/Main/data/api';
import { getInstitutionName, assignStaffRole } from 'features/Main/data/api';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';

jest.mock('@edx/frontend-platform/auth', () => ({
getAuthenticatedHttpClient: jest.fn(),
}));

jest.mock('@edx/frontend-platform', () => ({
getConfig: jest.fn(() => ({
LMS_BASE_URL: 'http://localhost:18000',
COURSE_OPERATIONS_API_V2_BASE_URL: 'http://localhost:18000/pearson_course_operation/api/v2',
})),
}));

describe('getInstitutionName', () => {
test('should call getAuthenticatedHttpClient with the correct parameters', () => {
const httpClientMock = {
Expand All @@ -18,3 +25,19 @@ describe('getInstitutionName', () => {
expect(httpClientMock.get).toHaveBeenCalledTimes(1);
});
});

describe('assignStaffRole', () => {
test('Should call getAuthenticatedHttpClient with the correct parameters', () => {
const httpClientMock = {
post: jest.fn(),
};

getAuthenticatedHttpClient.mockReturnValue(httpClientMock);

assignStaffRole('example+123');
const data = new FormData();
data.append('class_id', 'example+123');

expect(httpClientMock.post).toHaveBeenCalledWith('http://localhost:18000/pearson_course_operation/api/v2/assign-staff/', data);
});
});
20 changes: 20 additions & 0 deletions src/features/Main/data/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,26 @@ function getInstitutionName() {
);
}

/**
* Assigns a staff role to a class.
*
* This function makes an authenticated HTTP request to the COURSE_OPERATIONS_API_V2
* to assign a staff role to the specified class ID.
*
* @param {string} classId - The ID of the class to which the staff role will be assigned.
* @returns {Promise} A promise that resolves with the HTTP response of the request.
*/
function assignStaffRole(classId) {
const formData = new FormData();
formData.append('class_id', classId);

return getAuthenticatedHttpClient().post(
`${getConfig().COURSE_OPERATIONS_API_V2_BASE_URL}/assign-staff/`,
formData,
);
}

export {
getInstitutionName,
assignStaffRole,
};
62 changes: 61 additions & 1 deletion src/helpers/__test__/index.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,21 @@
import { formatDateRange, formatUTCDate, getInitials } from 'helpers';
import { logError } from '@edx/frontend-platform/logging';

import {
formatDateRange,
formatUTCDate,
getInitials,
setAssignStaffRole,
} from 'helpers';

import { assignStaffRole } from 'features/Main/data/api';

jest.mock('@edx/frontend-platform/logging', () => ({
logError: jest.fn(),
}));

jest.mock('features/Main/data/api', () => ({
assignStaffRole: jest.fn(),
}));

describe('formatDateRange', () => {
test('Should return "-" when startDate is not provided', () => {
Expand Down Expand Up @@ -60,3 +77,46 @@ describe('getInitials', () => {
expect(getInitials('Mary-Jane Watson')).toBe('MW');
});
});

describe('setAssignStaffRole', () => {
const originalWindowOpen = window.open;

beforeAll(() => {
window.open = jest.fn();
});

afterAll(() => {
window.open = originalWindowOpen;
});

beforeEach(() => {
jest.clearAllMocks();
});

test('Should open a new window with the correct URL on success', async () => {
assignStaffRole.mockResolvedValueOnce();

const url = 'http://example.com';
const classId = '12345';

await setAssignStaffRole(url, classId);

expect(assignStaffRole).toHaveBeenCalledWith(classId);
expect(logError).not.toHaveBeenCalled();
expect(window.open).toHaveBeenCalledWith(url, '_blank', 'noopener,noreferrer');
});

test('Should log an error and open a new window with the correct URL on failure', async () => {
const error = new Error('Assignment failed');
assignStaffRole.mockRejectedValueOnce(error);

const url = 'http://example.com';
const classId = '12345';

await setAssignStaffRole(url, classId);

expect(assignStaffRole).toHaveBeenCalledWith(classId);
expect(logError).toHaveBeenCalledWith(error);
expect(window.open).toHaveBeenCalledWith(url, '_blank', 'noopener,noreferrer');
});
});
16 changes: 16 additions & 0 deletions src/helpers/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { format } from 'date-fns';
import { logError } from '@edx/frontend-platform/logging';

import { assignStaffRole } from 'features/Main/data/api';

/**
* Format a UTC date
Expand Down Expand Up @@ -102,3 +105,16 @@ export const getInitials = (name) => {

return name.trim().split(/\s+/).map(word => word.charAt(0).toUpperCase()).join('');
};

/**
* Assigns a staff role to a class and then opens a new window or tab with a specific URL.
*
* @param {string} url - The URL to open in a new window or tab after assigning the role.
* @param {string} classId - The ID of the class to which the staff role will be assigned.
*
* @returns {Promise} - The promise returned by the assignStaffRole function, which resolves once
* the role assignment is complete.
*/
export const setAssignStaffRole = (url, classId) => assignStaffRole(classId).catch(logError).finally(() => {
window.open(url, '_blank', 'noopener,noreferrer');
});

0 comments on commit 762879c

Please sign in to comment.