Skip to content
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
55 changes: 0 additions & 55 deletions src/containers/CoursesPanel/__snapshots__/index.test.jsx.snap

This file was deleted.

67 changes: 51 additions & 16 deletions src/containers/CoursesPanel/index.test.jsx
Original file line number Diff line number Diff line change
@@ -1,58 +1,93 @@
import { shallow } from '@edx/react-unit-test-utils';

import { render, screen } from '@testing-library/react';
import { IntlProvider } from '@edx/frontend-platform/i18n';
import { FilterKeys } from 'data/constants/app';
import { reduxHooks } from 'hooks';

import messagesNoCourses from 'containers/CoursesPanel/NoCoursesView/messages';
import { useCourseListData } from './hooks';
import CoursesPanel from '.';
import messages from './messages';

const courseSearchUrl = '/course-search-url';

jest.mock('hooks', () => ({
reduxHooks: { useHasCourses: jest.fn() },
reduxHooks: {
useHasCourses: jest.fn(),
usePlatformSettingsData: jest.fn(() => ({
courseSearchUrl,
})),
},
}));

jest.mock('./hooks', () => ({
useCourseListData: jest.fn(),
}));

jest.mock('containers/CourseCard', () => 'CourseCard');
jest.mock('containers/CourseCard', () => jest.fn(() => <div>CourseCard</div>));
jest.mock('containers/CourseFilterControls', () => ({
ActiveCourseFilters: 'ActiveCourseFilters',
CourseFilterControls: 'CourseFilterControls',
ActiveCourseFilters: jest.fn(() => <div>ActiveCourseFilters</div>),
CourseFilterControls: jest.fn(() => <div>CourseFilterControls</div>),
}));

jest.mock('@openedx/frontend-plugin-framework', () => ({
PluginSlot: 'PluginSlot',
}));
jest.mock('./CourseList', () => 'CourseList');

jest.unmock('@edx/frontend-platform/i18n');
jest.unmock('@openedx/paragon');
jest.unmock('react');

const filters = Object.values(FilterKeys);

reduxHooks.useHasCourses.mockReturnValue(true);

describe('CoursesPanel', () => {
const defaultCourseListData = {
filterOptions: {},
filterOptions: { filters, handleRemoveFilter: jest.fn() },
numPages: 1,
setPageNumber: jest.fn().mockName('setPageNumber'),
showFilters: false,
visibleList: [],
};

const createWrapper = (courseListData) => {
useCourseListData.mockReturnValueOnce({
useCourseListData.mockReturnValue({
...defaultCourseListData,
...courseListData,
});
return shallow(<CoursesPanel />);
return render(<IntlProvider locale="en"><CoursesPanel /></IntlProvider>);
};

describe('no courses', () => {
test('snapshot', () => {
it('should render no courses view slot', () => {
reduxHooks.useHasCourses.mockReturnValue(false);
const wrapper = createWrapper();
expect(wrapper.snapshot).toMatchSnapshot();
createWrapper();
const imgNoCourses = screen.getByRole('img', { name: messagesNoCourses.bannerAlt.defaultMessage });
expect(imgNoCourses).toBeInTheDocument();
const courseCard = screen.queryByText('CourseCard');
expect(courseCard).toBeNull();
});
});
describe('with courses', () => {
test('snapshot', () => {
it('should render courselist', () => {
const visibleList = [{ cardId: 'foo' }, { cardId: 'bar' }, { cardId: 'baz' }];
reduxHooks.useHasCourses.mockReturnValue(true);
createWrapper({ visibleList });
const courseCards = screen.getAllByText('CourseCard');
expect(courseCards.length).toEqual(visibleList.length);
});
it('displays course filter controls', () => {
reduxHooks.useHasCourses.mockReturnValue(true);
createWrapper();
expect(screen.getByText('CourseFilterControls')).toBeInTheDocument();
});

it('displays course list slot when courses exist', () => {
reduxHooks.useHasCourses.mockReturnValue(true);
const wrapper = createWrapper();
expect(wrapper.snapshot).toMatchSnapshot();
const visibleList = [{ cardId: 'foo' }, { cardId: 'bar' }, { cardId: 'baz' }];
createWrapper({ visibleList });
const heading = screen.getByText(messages.myCourses.defaultMessage);
expect(heading).toBeInTheDocument();
});
});
});
95 changes: 44 additions & 51 deletions src/containers/Dashboard/DashboardLayout.test.jsx
Original file line number Diff line number Diff line change
@@ -1,65 +1,71 @@
import React from 'react';
import { shallow } from '@edx/react-unit-test-utils';
import { Col, Row } from '@openedx/paragon';
import { render, screen } from '@testing-library/react';
import { IntlProvider } from '@edx/frontend-platform/i18n';

import hooks from './hooks';
import DashboardLayout, { columnConfig } from './DashboardLayout';
import DashboardLayout from './DashboardLayout';

jest.mock('./hooks', () => ({
useDashboardLayoutData: jest.fn(),
}));

jest.mock('@openedx/frontend-plugin-framework', () => ({
PluginSlot: 'PluginSlot',
}));

jest.unmock('@edx/frontend-platform/i18n');
jest.unmock('@openedx/paragon');
jest.unmock('react');

const hookProps = {
isCollapsed: true,
sidebarShowing: false,
setSidebarShowing: jest.fn().mockName('hooks.setSidebarShowing'),
};
hooks.useDashboardLayoutData.mockReturnValue(hookProps);

const children = 'test-children';
const children = <div>test children</div>;

let el;
describe('DashboardLayout', () => {
beforeEach(() => {
jest.clearAllMocks();
el = shallow(<DashboardLayout>{children}</DashboardLayout>);
render(<IntlProvider locale="en"><DashboardLayout>{children}</DashboardLayout></IntlProvider>);
});

const testColumns = () => {
it('loads courseList and sidebar column layout', () => {
const columns = el.instance.findByType(Row)[0].findByType(Col);
Object.keys(columnConfig.sidebar).forEach(size => {
expect(columns[1].props[size]).toEqual(columnConfig.sidebar[size]);
});
it('loads courseList and sidebar column layout with corresponding children', () => {
const courseChildren = screen.getByText('test children');
const courseListCol = courseChildren.parentElement;
const sidebarCol = courseListCol.nextSibling;
expect(courseListCol).toHaveClass('course-list-column');
expect(sidebarCol).toHaveClass('sidebar-column');
});
it('displays children in first column', () => {
const columns = el.instance.findByType(Row)[0].findByType(Col);
expect(columns[0].children).not.toHaveLength(0);
const courseChildren = screen.getByText('test children');
const courseListCol = courseChildren.parentElement;
expect(courseChildren).toBeInTheDocument();
expect(courseListCol).toHaveClass('course-list-column');
});
it('displays WidgetSidebarSlot in second column', () => {
const columns = el.instance.findByType(Row)[0].findByType(Col);
expect(columns[1].findByType('WidgetSidebarSlot')).toHaveLength(1);
const courseListCol = screen.getByText('test children').parentElement;
const sidebarCol = courseListCol.nextSibling;
expect(sidebarCol).toHaveClass('sidebar-column');
expect(sidebarCol.children[0]).toHaveAttribute('id', 'org.openedx.frontend.learner_dashboard.widget_sidebar.v1');
});
};
const testSidebarLayout = () => {
const testSidebarLayout = ({ isCollapsed }) => {
it('displays withSidebar width for course list column', () => {
const columns = el.instance.findByType(Row)[0].findByType(Col);
Object.keys(columnConfig.courseList.withSidebar).forEach(size => {
expect(columns[0].props[size]).toEqual(columnConfig.courseList.withSidebar[size]);
});
const courseListCol = screen.getByText('test children').parentElement;
expect(courseListCol).toHaveClass('col-xl-8');
const sidebarCol = courseListCol.nextSibling;
expect(sidebarCol).toHaveClass('sidebar-column', !isCollapsed && 'not-collapsed');
});
};
const testNoSidebarLayout = () => {
const testNoSidebarLayout = ({ isCollapsed }) => {
it('displays noSidebar width for course list column', () => {
const columns = el.instance.findByType(Row)[0].findByType(Col);
Object.keys(columnConfig.courseList.noSidebar).forEach(size => {
expect(columns[0].props[size]).toEqual(columnConfig.courseList.noSidebar[size]);
});
});
};
const testSnapshot = () => {
test('snapshot', () => {
expect(el.snapshot).toMatchSnapshot();
const courseListCol = screen.getByText('test children').parentElement;
expect(courseListCol).toHaveClass('col-xl-12');
const sidebarCol = courseListCol.nextSibling;
expect(sidebarCol).toHaveClass('sidebar-column', !isCollapsed && 'not-collapsed');
});
};
describe('collapsed', () => {
Expand All @@ -68,27 +74,18 @@ describe('DashboardLayout', () => {
hooks.useDashboardLayoutData.mockReturnValueOnce({ ...hookProps, sidebarShowing: true });
});
testColumns();
testSnapshot();
testSidebarLayout();
testSidebarLayout({ isCollapsed: true });
});
describe('sidebar not showing', () => {
beforeEach(() => {
hooks.useDashboardLayoutData.mockReturnValueOnce({ ...hookProps });
});
testColumns();
testSnapshot();
testNoSidebarLayout();
});
it('does not show spacer component above widget sidebar', () => {
const columns = el.instance.findByType(Col);
expect(columns[1].findByType('h2').length).toEqual(0);
testNoSidebarLayout({ isCollapsed: true });
});
});

describe('not collapsed', () => {
const testWidgetSpacing = () => {
it('shows not-collapsed class on widget sidebar', () => {
const columns = el.instance.findByType(Col);
expect(columns[1].props.className).toContain('not-collapsed');
});
};
describe('sidebar showing', () => {
beforeEach(() => {
hooks.useDashboardLayoutData.mockReturnValueOnce({
Expand All @@ -98,18 +95,14 @@ describe('DashboardLayout', () => {
});
});
testColumns();
testSnapshot();
testSidebarLayout();
testWidgetSpacing();
testSidebarLayout({ isCollapsed: false });
});
describe('sidebar not showing', () => {
beforeEach(() => {
hooks.useDashboardLayoutData.mockReturnValueOnce({ ...hookProps, isCollapsed: false });
});
testColumns();
testSnapshot();
testNoSidebarLayout();
testWidgetSpacing();
testNoSidebarLayout({ isCollapsed: false });
});
});
});
19 changes: 9 additions & 10 deletions src/containers/Dashboard/LoadingView.test.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { shallow } from '@edx/react-unit-test-utils';
import { Spinner } from '@openedx/paragon';
import { render, screen } from '@testing-library/react';

import hooks from './hooks';
import LoadingView from './LoadingView';
Expand All @@ -8,16 +7,16 @@ jest.mock('./hooks', () => ({
useDashboardMessages: jest.fn(),
}));

jest.unmock('@edx/frontend-platform/i18n');
jest.unmock('@openedx/paragon');
jest.unmock('react');

const spinnerScreenReaderText = 'test-sr-text';
describe('LoadingView', () => {
beforeEach(() => {
hooks.useDashboardMessages.mockReturnValueOnce({ spinnerScreenReaderText });
});
test('snapshot', () => {
expect(shallow(<LoadingView />).snapshot).toMatchSnapshot();
});
it('renders spinner component with associated screen reader text', () => {
const wrapper = shallow(<LoadingView />);
expect(wrapper.instance.findByType(Spinner)[0].props.screenReaderText).toEqual(spinnerScreenReaderText);
hooks.useDashboardMessages.mockReturnValueOnce({ spinnerScreenReaderText });
render(<LoadingView />);
const loader = screen.getByRole('status');
expect(loader.children[0].innerHTML).toBe(spinnerScreenReaderText);
});
});
Loading