Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vue/PADV-1390 #94

Merged
merged 1 commit into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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');
});
Loading