Skip to content

Commit

Permalink
fix: all test cases affected by react router upgrade
Browse files Browse the repository at this point in the history
  • Loading branch information
Syed-Ali-Abbas-Zaidi committed Jun 12, 2023
1 parent 781c96b commit f6e587c
Show file tree
Hide file tree
Showing 26 changed files with 279 additions and 223 deletions.
17 changes: 11 additions & 6 deletions src/course-home/dates-tab/DatesTab.test.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { Route } from 'react-router';
import { Routes, Route } from 'react-router-dom';
import MockAdapter from 'axios-mock-adapter';
import { Factory } from 'rosie';
import { getConfig, history } from '@edx/frontend-platform';
Expand Down Expand Up @@ -32,11 +32,16 @@ describe('DatesTab', () => {
component = (
<AppProvider store={store}>
<UserMessagesProvider>
<Route path="/course/:courseId/dates">
<TabContainer tab="dates" fetch={fetchDatesTab} slice="courseHome">
<DatesTab />
</TabContainer>
</Route>
<Routes>
<Route
path="/course/:courseId/dates"
element={(
<TabContainer tab="dates" fetch={fetchDatesTab} slice="courseHome">
<DatesTab />
</TabContainer>
)}
/>
</Routes>
</UserMessagesProvider>
</AppProvider>
);
Expand Down
17 changes: 11 additions & 6 deletions src/course-home/discussion-tab/DiscussionTab.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { AppProvider } from '@edx/frontend-platform/react';
import { render } from '@testing-library/react';
import MockAdapter from 'axios-mock-adapter';
import React from 'react';
import { Route } from 'react-router';
import { Route, Routes } from 'react-router-dom';
import { Factory } from 'rosie';
import { UserMessagesProvider } from '../../generic/user-messages';
import {
Expand All @@ -30,11 +30,16 @@ describe('DiscussionTab', () => {
component = (
<AppProvider store={store}>
<UserMessagesProvider>
<Route path="/course/:courseId/discussion">
<TabContainer tab="discussion" fetch={fetchDiscussionTab} slice="courseHome">
<DiscussionTab />
</TabContainer>
</Route>
<Routes>
<Route
path="/course/:courseId/discussion"
element={(
<TabContainer tab="discussion" fetch={fetchDiscussionTab} slice="courseHome">
<DiscussionTab />
</TabContainer>
)}
/>
</Routes>
</UserMessagesProvider>
</AppProvider>
);
Expand Down
15 changes: 10 additions & 5 deletions src/course-home/goal-unsubscribe/GoalUnsubscribe.test.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React from 'react';
import { Route } from 'react-router';
import {
MemoryRouter, Route, Routes,
} from 'react-router-dom';
import MockAdapter from 'axios-mock-adapter';
import { getConfig, history } from '@edx/frontend-platform';
import { getConfig } from '@edx/frontend-platform';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import { AppProvider } from '@edx/frontend-platform/react';
import { render, screen } from '@testing-library/react';
Expand All @@ -24,13 +26,16 @@ describe('GoalUnsubscribe', () => {
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
store = initializeStore();
component = (
<AppProvider store={store}>
<AppProvider store={store} wrapWithRouter={false}>
<UserMessagesProvider>
<Route path="/goal-unsubscribe/:token" component={GoalUnsubscribe} />
<MemoryRouter initialEntries={['/goal-unsubscribe/TOKEN']}>
<Routes>
<Route path="/goal-unsubscribe/:token" element={<GoalUnsubscribe />} />
</Routes>
</MemoryRouter>
</UserMessagesProvider>
</AppProvider>
);
history.push('/goal-unsubscribe/TOKEN'); // so we can pull token from url
});

it('starts with a spinner', () => {
Expand Down
29 changes: 15 additions & 14 deletions src/courseware/CoursewareContainer.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ import { waitForElementToBeRemoved, fireEvent } from '@testing-library/dom';
import '@testing-library/jest-dom/extend-expect';
import { render, screen } from '@testing-library/react';
import React from 'react';
import { Route, Switch } from 'react-router';
import {
BrowserRouter, MemoryRouter, Route, Routes,
} from 'react-router-dom';
import { Factory } from 'rosie';
import MockAdapter from 'axios-mock-adapter';

import { UserMessagesProvider } from '../generic/user-messages';
import tabMessages from '../tab-page/messages';
import { initializeMockApp, waitFor } from '../setupTest';
import { DECODE_ROUTES } from '../constants';

import CoursewareContainer from './CoursewareContainer';
import { buildSimpleCourseBlocks, buildBinaryCourseBlocks } from '../shared/data/__factories__/courseBlocks.factory';
Expand Down Expand Up @@ -80,18 +83,16 @@ describe('CoursewareContainer', () => {
store = initializeStore();

component = (
<AppProvider store={store}>
<AppProvider store={store} wrapWithRouter={false}>
<UserMessagesProvider>
<Switch>
<Route
path={[
'/course/:courseId/:sequenceId/:unitId',
'/course/:courseId/:sequenceId',
'/course/:courseId',
]}
component={CoursewareContainer}
/>
</Switch>
<Routes>
{DECODE_ROUTES.COURSEWARE.map((route) => (
<Route
path={route}
element={<CoursewareContainer />}
/>
))}
</Routes>
</UserMessagesProvider>
</AppProvider>
);
Expand Down Expand Up @@ -151,7 +152,7 @@ describe('CoursewareContainer', () => {
}

async function loadContainer() {
const { container } = render(component);
const { container } = render(<BrowserRouter>{component}</BrowserRouter>);
// Wait for the page spinner to be removed, such that we can wait for our main
// content to load before making any assertions.
await waitForElementToBeRemoved(screen.getByRole('status'));
Expand All @@ -160,7 +161,7 @@ describe('CoursewareContainer', () => {

it('should initialize to show a spinner', () => {
history.push('/course/abc123');
render(component);
render(<MemoryRouter initialEntries={['/course/abc123']}>{component}</MemoryRouter>);

const spinner = screen.getByRole('status');

Expand Down
23 changes: 4 additions & 19 deletions src/courseware/CoursewareRedirectLandingPage.test.jsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
import React from 'react';
import { Router } from 'react-router';
import { createMemoryHistory } from 'history';
import { MemoryRouter as Router } from 'react-router-dom';
import { render, initializeMockApp } from '../setupTest';
import CoursewareRedirectLandingPage from './CoursewareRedirectLandingPage';

const redirectUrl = jest.fn();

jest.mock('@edx/frontend-platform/analytics');

jest.mock('react-router', () => ({
...jest.requireActual('react-router'),
useRouteMatch: () => ({
path: '/redirect',
}),
}));
jest.mock('../decode-page-route', () => jest.fn(({ children }) => <div>{children}</div>));

describe('CoursewareRedirectLandingPage', () => {
beforeEach(async () => {
Expand All @@ -23,12 +16,8 @@ describe('CoursewareRedirectLandingPage', () => {
});

it('Redirects to correct consent URL', () => {
const history = createMemoryHistory({
initialEntries: ['/redirect/consent/?consentPath=%2Fgrant_data_sharing_consent'],
});

render(
<Router history={history}>
<Router initialEntries={['/consent/?consentPath=%2Fgrant_data_sharing_consent']}>
<CoursewareRedirectLandingPage />
</Router>,
);
Expand All @@ -37,12 +26,8 @@ describe('CoursewareRedirectLandingPage', () => {
});

it('Redirects to correct consent URL', () => {
const history = createMemoryHistory({
initialEntries: ['/redirect/home/course-v1:edX+DemoX+Demo_Course'],
});

render(
<Router history={history}>
<Router initialEntries={['/home/course-v1:edX+DemoX+Demo_Course']}>
<CoursewareRedirectLandingPage />
</Router>,
);
Expand Down
26 changes: 13 additions & 13 deletions src/courseware/course/Course.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@ describe('Course', () => {
if (storageValue !== null) {
localStorage.setItem('showDiscussionSidebar', storageValue);
}
await render(<Course {...mockData} />, { store: testStore });
await render(<Course {...mockData} />, { store: testStore, wrapWithRouter: true });
};

it('loads learning sequence', async () => {
render(<Course {...mockData} />);
render(<Course {...mockData} />, { wrapWithRouter: true });
expect(screen.getByRole('navigation', { name: 'breadcrumb' })).toBeInTheDocument();
expect(await screen.findByText('Loading learning sequence...')).toBeInTheDocument();

Expand Down Expand Up @@ -105,7 +105,7 @@ describe('Course', () => {
};
// Set up LocalStorage for testing.
handleNextSectionCelebration(sequenceId, sequenceId, testData.unitId);
render(<Course {...testData} />, { store: testStore });
render(<Course {...testData} />, { store: testStore, wrapWithRouter: true });

const firstSectionCelebrationModal = screen.getByRole('dialog');
expect(firstSectionCelebrationModal).toBeInTheDocument();
Expand All @@ -123,7 +123,7 @@ describe('Course', () => {
sequenceId,
unitId: Object.values(models.units)[0].id,
};
render(<Course {...testData} />, { store: testStore });
render(<Course {...testData} />, { store: testStore, wrapWithRouter: true });

const weeklyGoalCelebrationModal = screen.getByRole('dialog');
expect(weeklyGoalCelebrationModal).toBeInTheDocument();
Expand All @@ -132,7 +132,7 @@ describe('Course', () => {

it('displays notification trigger and toggles active class on click', async () => {
localStorage.setItem('showDiscussionSidebar', false);
render(<Course {...mockData} />);
render(<Course {...mockData} />, { wrapWithRouter: true });

const notificationTrigger = screen.getByRole('button', { name: /Show notification tray/i });
expect(notificationTrigger).toBeInTheDocument();
Expand All @@ -144,7 +144,7 @@ describe('Course', () => {
it('handles click to open/close notification tray', async () => {
sessionStorage.clear();
localStorage.setItem('showDiscussionSidebar', false);
render(<Course {...mockData} />);
render(<Course {...mockData} />, { wrapWithRouter: true });
expect(sessionStorage.getItem(`notificationTrayStatus.${mockData.courseId}`)).toBe('"open"');
const notificationShowButton = await screen.findByRole('button', { name: /Show notification tray/i });
expect(screen.queryByRole('region', { name: /notification tray/i })).not.toHaveClass('d-none');
Expand All @@ -155,7 +155,7 @@ describe('Course', () => {

it('handles reload persisting notification tray status', async () => {
sessionStorage.clear();
render(<Course {...mockData} />);
render(<Course {...mockData} />, { wrapWithRouter: true });
const notificationShowButton = await screen.findByRole('button', { name: /Show notification tray/i });
fireEvent.click(notificationShowButton);
expect(sessionStorage.getItem(`notificationTrayStatus.${mockData.courseId}`)).toBe('"closed"');
Expand All @@ -180,7 +180,7 @@ describe('Course', () => {
// set sessionStorage for a different course before rendering Course
sessionStorage.setItem(`notificationTrayStatus.${courseMetadataSecondCourse.id}`, '"open"');

render(<Course {...mockData} />);
render(<Course {...mockData} />, { wrapWithRouter: true });
expect(sessionStorage.getItem(`notificationTrayStatus.${mockData.courseId}`)).toBe('"open"');
const notificationShowButton = await screen.findByRole('button', { name: /Show notification tray/i });
fireEvent.click(notificationShowButton);
Expand Down Expand Up @@ -208,7 +208,7 @@ describe('Course', () => {
sequenceId,
unitId: Object.values(models.units)[1].id, // Corner cases are already covered in `Sequence` tests.
};
render(<Course {...testData} />, { store: testStore });
render(<Course {...testData} />, { store: testStore, wrapWithRouter: true });

loadUnit();
await waitFor(() => expect(screen.queryByText('Loading learning sequence...')).not.toBeInTheDocument());
Expand Down Expand Up @@ -268,7 +268,7 @@ describe('Course', () => {
previousSequenceHandler,
unitNavigationHandler,
};
render(<Course {...testData} />, { store: testStore });
render(<Course {...testData} />, { store: testStore, wrapWithRouter: true });

loadUnit();
await waitFor(() => expect(screen.queryByText('Loading learning sequence...')).not.toBeInTheDocument());
Expand Down Expand Up @@ -297,7 +297,7 @@ describe('Course', () => {
courseId: courseMetadata.id,
sequenceId: sequenceBlocks[0].id,
};
render(<Course {...testData} />, { store: testStore });
render(<Course {...testData} />, { store: testStore, wrapWithRouter: true });
await waitFor(() => expect(screen.getByText('Some random banner text to display.')).toBeInTheDocument());
});

Expand Down Expand Up @@ -331,7 +331,7 @@ describe('Course', () => {
courseId: testCourseMetadata.id,
sequenceId: sequenceBlocks[0].id,
};
render(<Course {...testData} />, { store: testStore });
render(<Course {...testData} />, { store: testStore, wrapWithRouter: true });
await waitFor(() => expect(screen.getByText('Your score is 100%. You have passed the entrance exam.')).toBeInTheDocument());
});

Expand Down Expand Up @@ -365,7 +365,7 @@ describe('Course', () => {
courseId: testCourseMetadata.id,
sequenceId: sequenceBlocks[0].id,
};
render(<Course {...testData} />, { store: testStore });
render(<Course {...testData} />, { store: testStore, wrapWithRouter: true });
await waitFor(() => expect(screen.getByText('To access course materials, you must score 70% or higher on this exam. Your current score is 30%.')).toBeInTheDocument());
});
});
Expand Down
1 change: 1 addition & 0 deletions src/courseware/course/CourseBreadcrumbs.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ const CourseBreadcrumbs = ({
<Link
className="flex-shrink-0 text-primary"
to={`/course/${courseId}/home`}
replace
>
<FontAwesomeIcon icon={faHome} className="mr-2" />
<FormattedMessage
Expand Down
8 changes: 7 additions & 1 deletion src/courseware/course/CourseBreadcrumbs.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ jest.mock('react-redux', () => ({
Provider: ({ children }) => children,
useSelector: () => 'loaded',
}));
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
Link: jest.fn().mockImplementation(({ to, children }) => (
<a href={to}>{children}</a>
)),
}));

useModels.mockImplementation((name) => {
if (name === 'sections') {
Expand Down Expand Up @@ -115,7 +121,7 @@ describe('CourseBreadcrumbs', () => {
sequenceId="block-v1:edX+DemoX+Demo_Course+type@sequential+block@basic_questions"
isStaff
/>
</BrowserRouter>,
</BrowserRouter>
</IntlProvider>,
);
it('renders course breadcrumbs as expected', async () => {
Expand Down
6 changes: 4 additions & 2 deletions src/courseware/course/JumpNavMenuItem.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React from 'react';
import PropTypes from 'prop-types';
import { history } from '@edx/frontend-platform';
import { MenuItem } from '@edx/paragon';

import {
sendTrackingLogEvent,
sendTrackEvent,
} from '@edx/frontend-platform/analytics';
import { useNavigate } from 'react-router-dom';

const JumpNavMenuItem = ({
title,
Expand All @@ -16,6 +16,8 @@ const JumpNavMenuItem = ({
sequences,
isDefault,
}) => {
const navigate = useNavigate();

function logEvent(targetUrl) {
const eventName = 'edx.ui.lms.jump_nav.selected';
const payload = {
Expand All @@ -37,7 +39,7 @@ const JumpNavMenuItem = ({
function handleClick() {
const url = destinationUrl();
logEvent(url);
history.push(url);
navigate(url);
}

return (
Expand Down
Loading

0 comments on commit f6e587c

Please sign in to comment.