Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
42 changes: 36 additions & 6 deletions src/ProgramEnrollments/ProgramInspector/ProgramInspector.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import {
Alert, Col, Row, Button, Input,
} from '@openedx/paragon';
import { getSsoRecords } from '../../users/data/api';
import { getSsoRecords, getUser } from '../../users/data/api';
import EnrollmentDetails from './EnrollmentDetails';
import SingleSignOnRecordCard from '../../users/SingleSignOnRecordCard';
import {
Expand All @@ -26,6 +26,8 @@
const [externalUserKey, setExternalUserKey] = useState(params.get('external_user_key'));
const [clickEventCall, setClickEventCall] = useState(false);

const [query, setQuery] = useState(null);

const getOrgKeyList = () => (orgKeyList
? orgKeyList.map((data) => ({
value: data,
Expand All @@ -41,13 +43,13 @@
setSsoRecords([]);
navigate('/programs');
} else {
const newLink = `/programs?edx_user=${
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did we remove /programs again?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Earlier, we would navigate to this url. Now, we are only using it to store the "query" (backend api call) that we should make. I have refactored it a little. Hopefully it's clearer now. I also removed the ClickEvent state, as it wasn't being used anywhere.

const newLink = `?edx_user=${
username || ''
}&org_key=${activeOrgKey}&external_user_key=${externalUserKey || ''}`;
if (newLink === location.pathname + location.search) {
if (newLink === location.search) {
setClickEventCall(!clickEventCall);
} else {
navigate(newLink);
setQuery(newLink);
}
}
};
Expand All @@ -66,13 +68,41 @@
setError(response.error);
setActiveOrgKey(response.org_keys);
setLearnerProgramEnrollment(response.learner_program_enrollments);
const name = response?.learner_program_enrollments?.user?.username;
return name;
}).then((name) => {
if (name) {
getUser(name).then(
res => navigate(`?edx_user_id=${res.id}`),
);
}
}).catch(err => {
console.error(err);

Check warning on line 80 in src/ProgramEnrollments/ProgramInspector/ProgramInspector.jsx

View workflow job for this annotation

GitHub Actions / tests

Unexpected console statement
setError('An error occured while fetching user id');
navigate('/programs');

Check warning on line 82 in src/ProgramEnrollments/ProgramInspector/ProgramInspector.jsx

View check run for this annotation

Codecov / codecov/patch

src/ProgramEnrollments/ProgramInspector/ProgramInspector.jsx#L79-L82

Added lines #L79 - L82 were not covered by tests
});
}
};

useEffect(() => {
fetchInspectorData(location.search);
}, [location.search, clickEventCall]);
if (query) {
fetchInspectorData(query);
}
}, [query]);

useEffect(() => {
const userId = new URLSearchParams(location.search).get('edx_user_id');
if (userId) {
getUser(userId).then(res => {
setUsername(res.username);
setQuery(`?edx_user=${res.username}&org_key=${activeOrgKey}&external_user_key=${externalUserKey}`);
}).catch(err => {
console.error(err);

Check warning on line 100 in src/ProgramEnrollments/ProgramInspector/ProgramInspector.jsx

View workflow job for this annotation

GitHub Actions / tests

Unexpected console statement
setError('An error occured while fetching user id');
navigate('/programs');

Check warning on line 102 in src/ProgramEnrollments/ProgramInspector/ProgramInspector.jsx

View check run for this annotation

Codecov / codecov/patch

src/ProgramEnrollments/ProgramInspector/ProgramInspector.jsx#L96-L102

Added lines #L96 - L102 were not covered by tests
});
}
}, []);

useEffect(() => {
if (!orgKeyList) {
Expand Down
31 changes: 22 additions & 9 deletions src/ProgramEnrollments/ProgramInspector/ProgramInspector.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import {
programInspectorErrorResponse,
} from './data/test/programInspector';
import ssoRecordsData from '../../users/data/test/ssoRecords';
import * as ssoApi from '../../users/data/api';
import * as ssoAndUserApi from '../../users/data/api';
import samlProvidersResponseValues from './data/test/samlProviders';
import verifiedNameHistory from '../../users/data/test/verifiedNameHistory';
import UserSummaryData from '../../users/data/test/userSummary';

const mockedNavigator = jest.fn();

Expand All @@ -38,6 +39,7 @@ describe('Program Inspector', () => {
let samlMock;
let ssoMock;
let verifiedNameMock;
let getUserMock;

const data = {
username: 'verified',
Expand All @@ -47,14 +49,17 @@ describe('Program Inspector', () => {

beforeEach(() => {
ssoMock = jest
.spyOn(ssoApi, 'getSsoRecords')
.spyOn(ssoAndUserApi, 'getSsoRecords')
.mockImplementationOnce(() => Promise.resolve(ssoRecordsData));
samlMock = jest
.spyOn(api, 'getSAMLProviderList')
.mockImplementationOnce(() => Promise.resolve(samlProvidersResponseValues));
verifiedNameMock = jest
.spyOn(ssoApi, 'getVerifiedNameHistory')
.spyOn(ssoAndUserApi, 'getVerifiedNameHistory')
.mockImplementationOnce(() => Promise.resolve(verifiedNameHistory));
getUserMock = jest
.spyOn(ssoAndUserApi, 'getUser')
.mockImplementationOnce(() => Promise.resolve(UserSummaryData.userData));
jest.clearAllMocks();
});

Expand All @@ -68,6 +73,7 @@ describe('Program Inspector', () => {
samlMock.mockReset();
ssoMock.mockReset();
verifiedNameMock.mockReset();
getUserMock.mockReset();
});

it('default render', async () => {
Expand All @@ -86,6 +92,7 @@ describe('Program Inspector', () => {
apiMock = jest
.spyOn(api, 'getProgramEnrollmentsInspector')
.mockImplementationOnce(() => Promise.resolve(programInspectorSuccessResponse));

wrapper = mount(<ProgramEnrollmentsWrapper />);

wrapper.find("input[name='username']").simulate(
Expand All @@ -98,9 +105,12 @@ describe('Program Inspector', () => {
);
wrapper.find('button.btn-primary').simulate('click');

expect(mockedNavigator).toHaveBeenCalledWith(
`/programs?edx_user=${data.username}&org_key=${data.orgKey}&external_user_key=`,
);
await waitFor(() => {
expect(mockedNavigator).toHaveBeenCalledWith(
`?edx_user_id=${UserSummaryData.userData.id}`,
);
});

waitFor(() => {
expect(wrapper.find('.inspector-name-row p.h5').at(0).text()).toEqual(
'Username',
Expand Down Expand Up @@ -137,9 +147,12 @@ describe('Program Inspector', () => {
);
wrapper.find('button.btn-primary').simulate('click');

expect(mockedNavigator).toHaveBeenCalledWith(
`/programs?edx_user=&org_key=${data.orgKey}&external_user_key=${data.externalKey}`,
);
await waitFor(() => {
expect(mockedNavigator).toHaveBeenCalledWith(
`?edx_user_id=${UserSummaryData.userData.id}`,
);
});

waitFor(() => {
expect(wrapper.find('.inspector-name-row p.h5').at(0).text()).toEqual(
'Username',
Expand Down
33 changes: 9 additions & 24 deletions src/users/UserPage.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { camelCaseObject } from '@edx/frontend-platform';
import React, {
useCallback, useContext, useEffect, useState, useLayoutEffect,
useCallback, useContext, useEffect, useState,
} from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import PageLoading from '../components/common/PageLoading';
Expand All @@ -11,7 +11,7 @@
import { getAllUserData } from './data/api';
import UserSearch from './UserSearch';
import LearnerInformation from './LearnerInformation';
import { LEARNER_INFO_TAB, TAB_PATH_MAP } from '../SupportToolsTab/constants';
import { TAB_PATH_MAP } from '../SupportToolsTab/constants';
import CancelRetirement from './account-actions/CancelRetirement';

// Supports urls such as /users/?username={username}, /users/?email={email} and /users/?lms_user_id={lms_user_id}
Expand Down Expand Up @@ -45,19 +45,13 @@
}
}

function getUpdatedURL(value) {
const updatedHistory = `${TAB_PATH_MAP['learner-information']}/?PARAM_NAME=${value}`;
let identifierType = '';
function getUpdatedURL(result) {
const lmsId = result?.user?.id;

Check warning on line 49 in src/users/UserPage.jsx

View check run for this annotation

Codecov / codecov/patch

src/users/UserPage.jsx#L48-L49

Added lines #L48 - L49 were not covered by tests

if (isEmail(value)) {
identifierType = 'email';
} else if (isValidLMSUserID(value)) {
identifierType = 'lms_user_id';
} else if (isValidUsername(value)) {
identifierType = 'username';
if (lmsId) {
return `${TAB_PATH_MAP['learner-information']}/?lms_user_id=${lmsId}`;

Check warning on line 52 in src/users/UserPage.jsx

View check run for this annotation

Codecov / codecov/patch

src/users/UserPage.jsx#L52

Added line #L52 was not covered by tests
}

return updatedHistory.replace('PARAM_NAME', identifierType);
return `${TAB_PATH_MAP['learner-information']}`;

Check warning on line 54 in src/users/UserPage.jsx

View check run for this annotation

Codecov / codecov/patch

src/users/UserPage.jsx#L54

Added line #L54 was not covered by tests
}

function processSearchResult(searchValue, result) {
Expand All @@ -69,7 +63,7 @@
navigate(`${TAB_PATH_MAP['learner-information']}`, { replace: true });
document.title = 'Support Tools | edX';
} else {
pushHistoryIfChanged(getUpdatedURL(searchValue));
pushHistoryIfChanged(getUpdatedURL(result));

Check warning on line 66 in src/users/UserPage.jsx

View check run for this annotation

Codecov / codecov/patch

src/users/UserPage.jsx#L66

Added line #L66 was not covered by tests
document.title = `Support Tools | edX | ${searchValue}`;
}

Expand Down Expand Up @@ -137,16 +131,7 @@
} else if (params.get('lms_user_id') && params.get('lms_user_id') !== userIdentifier) {
handleFetchSearchResults(params.get('lms_user_id'));
}
}, [params.get('username'), params.get('email'), params.get('lms_user_id')]);

// To change the url with appropriate query param if query param info is not present in URL
useLayoutEffect(() => {
if (userIdentifier
&& location.pathname.indexOf(TAB_PATH_MAP[LEARNER_INFO_TAB]) !== -1
&& !(params.get('email') || params.get('username') || params.get('lms_user_id'))) {
pushHistoryIfChanged(getUpdatedURL(userIdentifier));
}
});
}, []);

return (
<main className="mt-3 mb-5">
Expand Down