feat: make maquerade stateful

feat: implement loading screen

chore: update selector test

chore: fiter/sort padding

chore: update fail masquerade state

chore: update unit test

chore: Update src/containers/MasqueradeBar/index.jsx

Co-authored-by: Ben Warzeski <bwarzeski@edx.org>

chore: update test

Co-authored-by: Ben Warzeski <bwarzeski@edx.org>

chore: update snapshot
This commit is contained in:
Leangseu Kim
2022-09-30 12:09:45 -04:00
committed by leangseu-edx
parent 7f210e7483
commit 84446fe5cd
19 changed files with 220 additions and 78 deletions

View File

@@ -1,5 +1,17 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`CourseList snapshots renders loading 1`] = `
<div
className="course-list-loading"
>
<Spinner
animation="border"
className="mie-3"
screenReaderText="loading"
/>
</div>
`;
exports[`CourseList snapshots with filters 1`] = `
<div
className="course-list-container"

View File

@@ -6,6 +6,7 @@ import { useCheckboxSetValues } from '@edx/paragon';
import { StrictDict } from 'utils';
import { actions, hooks as appHooks } from 'data/redux';
import { ListPageSize, SortKeys } from 'data/constants/app';
import { RequestKeys } from 'data/constants/requests';
import * as module from './hooks';
@@ -27,6 +28,8 @@ export const useCourseListData = () => {
});
const handleRemoveFilter = (filter) => () => setFilters.remove(filter);
const setPageNumber = (value) => dispatch(actions.app.setPageNumber(value));
const initIsPending = appHooks.useIsPendingRequest(RequestKeys.initialize);
return {
pageNumber,
numPages,
@@ -40,6 +43,7 @@ export const useCourseListData = () => {
handleRemoveFilter,
},
showFilters: filters.length > 0,
initIsPending,
};
};

View File

@@ -15,6 +15,7 @@ jest.mock('data/redux', () => ({
hooks: {
useCurrentCourseList: jest.fn(),
usePageNumber: jest.fn(() => 23),
useIsPendingRequest: jest.fn(),
},
}));
@@ -34,6 +35,11 @@ const testCheckboxSetValues = [testFilters, testSetFilters];
describe('CourseList hooks', () => {
let out;
appHooks.useCurrentCourseList.mockReturnValue(testListData);
appHooks.useIsPendingRequest.mockReturnValue(false);
paragon.useCheckboxSetValues.mockImplementation(() => testCheckboxSetValues);
describe('state values', () => {
state.testGetter(state.keys.sortBy);
jest.clearAllMocks();
@@ -44,8 +50,6 @@ describe('CourseList hooks', () => {
beforeEach(() => {
state.mock();
state.mockVal(state.keys.sortBy, testSortBy);
paragon.useCheckboxSetValues.mockImplementationOnce(() => testCheckboxSetValues);
appHooks.useCurrentCourseList.mockReturnValueOnce(testListData);
out = hooks.useCourseListData();
});
describe('behavior', () => {
@@ -72,12 +76,17 @@ describe('CourseList hooks', () => {
test('showFilters is true iff filters is not empty', () => {
expect(out.showFilters).toEqual(true);
state.mockVal(state.keys.sortBy, testSortBy);
appHooks.useCurrentCourseList.mockReturnValueOnce(testListData);
paragon.useCheckboxSetValues.mockReturnValueOnce([[], testSetFilters]);
out = hooks.useCourseListData();
// checkbox values default to returning a list, and were only overridden once.
// Thus this time, the values for the list should be empty.
// don't show filter when list is empty.
expect(out.showFilters).toEqual(false);
});
test('initIsPending loads from useIsPendingRequest', () => {
expect(out.initIsPending).toEqual(false);
appHooks.useIsPendingRequest.mockReturnValueOnce(true);
out = hooks.useCourseListData();
expect(out.initIsPending).toEqual(true);
});
describe('filterOptions', () => {
test('sortBy and setSortBy are connected to the state value', () => {
expect(out.filterOptions.sortBy).toEqual(testSortBy);

View File

@@ -1,9 +1,12 @@
import React from 'react';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Pagination } from '@edx/paragon';
import { Pagination, Spinner } from '@edx/paragon';
import { ActiveCourseFilters, CourseFilterControls } from 'containers/CourseFilterControls';
import {
ActiveCourseFilters,
CourseFilterControls,
} from 'containers/CourseFilterControls';
import CourseCard from 'containers/CourseCard';
import { useCourseListData } from './hooks';
@@ -20,21 +23,21 @@ export const CourseList = () => {
numPages,
showFilters,
visibleList,
initIsPending,
} = useCourseListData();
return (
return initIsPending ? (
<div className="course-list-loading">
<Spinner animation="border" className="mie-3" screenReaderText="loading" />
</div>
) : (
<div className="course-list-container">
<div id="course-list-heading-container">
<h2 className="my-3">
{formatMessage(messages.myCourses)}
</h2>
<div
id="course-filter-controls-container"
className="text-right"
>
<h2 className="my-3">{formatMessage(messages.myCourses)}</h2>
<div id="course-filter-controls-container" className="text-right">
<CourseFilterControls {...filterOptions} />
</div>
</div>
{ showFilters && (
{showFilters && (
<div id="course-list-active-filters-container">
<ActiveCourseFilters {...filterOptions} />
</div>
@@ -43,7 +46,7 @@ export const CourseList = () => {
{visibleList.map(({ cardId }) => (
<CourseCard key={cardId} cardId={cardId} />
))}
{(numPages > 1) && (
{numPages > 1 && (
<Pagination
variant="secondary"
paginationLabel="Course List"
@@ -57,7 +60,6 @@ export const CourseList = () => {
);
};
CourseList.propTypes = {
};
CourseList.propTypes = {};
export default CourseList;

View File

@@ -2,3 +2,10 @@
display: flex;
justify-content: space-between;
}
.course-list-loading {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
}

View File

@@ -20,6 +20,7 @@ describe('CourseList', () => {
setPageNumber: jest.fn().mockName('setPageNumber'),
showFilters: false,
visibleList: [],
initIsPending: false,
};
const createWrapper = (courseListData) => {
useCourseListData.mockReturnValueOnce({
@@ -30,6 +31,10 @@ describe('CourseList', () => {
};
describe('snapshots', () => {
it('renders loading', () => {
const wrapper = createWrapper({ initIsPending: true });
expect(wrapper).toMatchSnapshot();
});
test('with no filters', () => {
const wrapper = createWrapper();
expect(wrapper).toMatchSnapshot();