diff --git a/src/course-home/data/redux.test.js b/src/course-home/data/redux.test.js
index ad226a6e..700535d6 100644
--- a/src/course-home/data/redux.test.js
+++ b/src/course-home/data/redux.test.js
@@ -8,8 +8,6 @@ import * as thunks from './thunks';
import executeThunk from '../../utils';
-import './__factories__';
-import '../../courseware/data/__factories__/courseMetadata.factory';
import initializeMockApp from '../../setupTest';
import initializeStore from '../../store';
diff --git a/src/courseware/CoursewareContainer.test.jsx b/src/courseware/CoursewareContainer.test.jsx
index 1aa1c183..81c480f9 100644
--- a/src/courseware/CoursewareContainer.test.jsx
+++ b/src/courseware/CoursewareContainer.test.jsx
@@ -14,7 +14,6 @@ import tabMessages from '../tab-page/messages';
import initializeMockApp from '../setupTest';
import CoursewareContainer from './CoursewareContainer';
-import './data/__factories__';
import buildSimpleCourseBlocks from './data/__factories__/courseBlocks.factory';
import initializeStore from '../store';
diff --git a/src/courseware/course/sequence/Sequence.test.jsx b/src/courseware/course/sequence/Sequence.test.jsx
index a452f91c..5c6108d3 100644
--- a/src/courseware/course/sequence/Sequence.test.jsx
+++ b/src/courseware/course/sequence/Sequence.test.jsx
@@ -1,32 +1,67 @@
import React from 'react';
-import { cloneDeep } from 'lodash';
+import { Factory } from 'rosie';
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
import {
- initialState, loadUnit, render, screen, testUnits, fireEvent, waitFor,
+ loadUnit, render, screen, fireEvent, waitFor, initializeTestStore,
} from '../../../setupTest';
import Sequence from './Sequence';
+import { fetchSequenceFailure } from '../../data/slice';
jest.mock('@edx/frontend-platform/analytics');
describe('Sequence', () => {
- const mockData = {
- unitId: '3',
- sequenceId: '1',
- courseId: '1',
- unitNavigationHandler: () => {},
- nextSequenceHandler: () => {},
- previousSequenceHandler: () => {},
- intl: {},
- };
+ let mockData;
+ const courseMetadata = Factory.build('courseMetadata');
+ const unitBlocks = Array.from({ length: 3 }).map(() => Factory.build(
+ 'block',
+ { type: 'vertical' },
+ { courseId: courseMetadata.id },
+ ));
+
+ beforeAll(async () => {
+ const store = await initializeTestStore({ courseMetadata, unitBlocks });
+ const { courseware } = store.getState();
+ mockData = {
+ unitId: unitBlocks[0].id,
+ sequenceId: courseware.sequenceId,
+ courseId: courseware.courseId,
+ unitNavigationHandler: () => {},
+ nextSequenceHandler: () => {},
+ previousSequenceHandler: () => {},
+ };
+ });
+
+ it('renders correctly without data', async () => {
+ const testStore = await initializeTestStore({ excludeFetchCourse: true, excludeFetchSequence: true }, false);
+ render(, { store: testStore });
- it('renders correctly without data', () => {
- render(, { initialState: {} });
expect(screen.getByText('There is no content here.')).toBeInTheDocument();
expect(screen.queryByRole('button')).not.toBeInTheDocument();
});
it('renders correctly for gated content', async () => {
- const { container } = render();
+ const sequenceBlock = [Factory.build(
+ 'block',
+ { type: 'sequential', children: [unitBlocks.map(block => block.id)] },
+ { courseId: courseMetadata.id },
+ )];
+ const gatedContent = {
+ gated: true,
+ prereq_id: `${sequenceBlock[0].id}-prereq`,
+ prereq_section_name: `${sequenceBlock[0].display_name}-prereq`,
+ gated_section_name: sequenceBlock[0].display_name,
+ };
+ const sequenceMetadata = [Factory.build(
+ 'sequenceMetadata',
+ { courseId: courseMetadata.id, gated_content: gatedContent },
+ { unitBlocks, sequenceBlock: sequenceBlock[0] },
+ )];
+ const testStore = await initializeTestStore({ unitBlocks, sequenceBlock, sequenceMetadata }, false);
+ const { container } = render(
+ ,
+ { store: testStore },
+ );
+
expect(screen.getByText('Loading locked content messaging...')).toBeInTheDocument();
// Only `Previous`, `Next` and `Bookmark` buttons.
expect(screen.getAllByRole('button').length).toEqual(3);
@@ -39,10 +74,10 @@ describe('Sequence', () => {
expect(screen.queryByText('Loading locked content messaging...')).not.toBeInTheDocument();
});
- it('displays error message on sequence load failure', () => {
- const testState = cloneDeep(initialState);
- testState.courseware.sequenceStatus = 'failed';
- render(, { initialState: testState });
+ it('displays error message on sequence load failure', async () => {
+ const testStore = await initializeTestStore({ excludeFetchCourse: true, excludeFetchSequence: true }, false);
+ testStore.dispatch(fetchSequenceFailure({ sequenceId: mockData.sequenceId }));
+ render(, { store: testStore });
expect(screen.getByText('There was an error loading this course.')).toBeInTheDocument();
});
@@ -51,7 +86,7 @@ describe('Sequence', () => {
render();
expect(screen.getByText('Loading learning sequence...')).toBeInTheDocument();
// Renders navigation buttons plus one button for each unit.
- expect(screen.getAllByRole('button').length).toEqual(3 + testUnits.length);
+ expect(screen.getAllByRole('button')).toHaveLength(3 + unitBlocks.length);
loadUnit();
await waitFor(() => expect(screen.queryByText('Loading learning sequence...')).not.toBeInTheDocument());
@@ -60,21 +95,41 @@ describe('Sequence', () => {
});
describe('sequence and unit navigation buttons', () => {
- it('navigates to the previous sequence if the unit is the first in the sequence', async () => {
+ let testStore;
+ const sequenceBlock = [Factory.build(
+ 'block',
+ { type: 'sequential', children: [unitBlocks.map(block => block.id)] },
+ { courseId: courseMetadata.id },
+ ), Factory.build(
+ 'block',
+ { type: 'sequential', children: [unitBlocks.map(block => block.id)] },
+ { courseId: courseMetadata.id },
+ )];
+
+ beforeAll(async () => {
+ testStore = await initializeTestStore({ courseMetadata, unitBlocks, sequenceBlock }, false);
+ });
+
+ beforeEach(() => {
sendTrackEvent.mockClear();
- const unitId = '1';
- const sequenceId = '2';
- const previousSequenceHandler = jest.fn();
- render();
+ });
+
+ it('navigates to the previous sequence if the unit is the first in the sequence', async () => {
+ const testData = {
+ ...mockData,
+ sequenceId: sequenceBlock[1].id,
+ previousSequenceHandler: jest.fn(),
+ };
+ render(, { store: testStore });
const sequencePreviousButton = screen.getByRole('button', { name: /previous/i });
fireEvent.click(sequencePreviousButton);
- expect(previousSequenceHandler).toHaveBeenCalledTimes(1);
+ expect(testData.previousSequenceHandler).toHaveBeenCalledTimes(1);
expect(sendTrackEvent).toHaveBeenCalledTimes(1);
expect(sendTrackEvent).toHaveBeenCalledWith('edx.ui.lms.sequence.previous_selected', {
- current_tab: Number(unitId),
- id: unitId,
- tab_count: testUnits.length,
+ current_tab: 1,
+ id: testData.unitId,
+ tab_count: unitBlocks.length,
widget_placement: 'top',
});
@@ -83,30 +138,32 @@ describe('Sequence', () => {
const unitPreviousButton = screen.getAllByRole('button', { name: /previous/i })
.filter(button => button !== sequencePreviousButton)[0];
fireEvent.click(unitPreviousButton);
- expect(previousSequenceHandler).toHaveBeenCalledTimes(2);
+ expect(testData.previousSequenceHandler).toHaveBeenCalledTimes(2);
expect(sendTrackEvent).toHaveBeenCalledTimes(2);
expect(sendTrackEvent).toHaveBeenNthCalledWith(2, 'edx.ui.lms.sequence.previous_selected', {
- current_tab: Number(unitId),
- id: unitId,
- tab_count: testUnits.length,
+ current_tab: 1,
+ id: testData.unitId,
+ tab_count: unitBlocks.length,
widget_placement: 'bottom',
});
});
it('navigates to the next sequence if the unit is the last in the sequence', async () => {
- sendTrackEvent.mockClear();
- const unitId = String(testUnits.length);
- const sequenceId = '1';
- const nextSequenceHandler = jest.fn();
- render();
+ const testData = {
+ ...mockData,
+ unitId: unitBlocks[unitBlocks.length - 1].id,
+ sequenceId: sequenceBlock[0].id,
+ nextSequenceHandler: jest.fn(),
+ };
+ render(, { store: testStore });
const sequenceNextButton = screen.getByRole('button', { name: /next/i });
fireEvent.click(sequenceNextButton);
- expect(nextSequenceHandler).toHaveBeenCalledTimes(1);
+ expect(testData.nextSequenceHandler).toHaveBeenCalledTimes(1);
expect(sendTrackEvent).toHaveBeenCalledWith('edx.ui.lms.sequence.next_selected', {
- current_tab: Number(unitId),
- id: unitId,
- tab_count: testUnits.length,
+ current_tab: unitBlocks.length,
+ id: testData.unitId,
+ tab_count: unitBlocks.length,
widget_placement: 'top',
});
@@ -115,141 +172,167 @@ describe('Sequence', () => {
const unitNextButton = screen.getAllByRole('button', { name: /next/i })
.filter(button => button !== sequenceNextButton)[0];
fireEvent.click(unitNextButton);
- expect(nextSequenceHandler).toHaveBeenCalledTimes(2);
+ expect(testData.nextSequenceHandler).toHaveBeenCalledTimes(2);
expect(sendTrackEvent).toHaveBeenCalledTimes(2);
expect(sendTrackEvent).toHaveBeenNthCalledWith(2, 'edx.ui.lms.sequence.next_selected', {
- current_tab: Number(unitId),
- id: unitId,
- tab_count: testUnits.length,
+ current_tab: unitBlocks.length,
+ id: testData.unitId,
+ tab_count: unitBlocks.length,
widget_placement: 'bottom',
});
});
it('navigates to the previous/next unit if the unit is not in the corner of the sequence', () => {
- sendTrackEvent.mockClear();
- const unitNavigationHandler = jest.fn();
- const previousSequenceHandler = jest.fn();
- const nextSequenceHandler = jest.fn();
- render();
+ const unitNumber = 1;
+ const testData = {
+ ...mockData,
+ unitId: unitBlocks[unitNumber].id,
+ sequenceId: sequenceBlock[0].id,
+ unitNavigationHandler: jest.fn(),
+ previousSequenceHandler: jest.fn(),
+ nextSequenceHandler: jest.fn(),
+ };
+ render(, { store: testStore });
fireEvent.click(screen.getByRole('button', { name: /previous/i }));
- expect(previousSequenceHandler).not.toHaveBeenCalled();
- expect(unitNavigationHandler).toHaveBeenCalledWith(String(Number(mockData.unitId) - 1));
+ expect(testData.previousSequenceHandler).not.toHaveBeenCalled();
+ expect(testData.unitNavigationHandler).toHaveBeenCalledWith(unitBlocks[unitNumber - 1].id);
fireEvent.click(screen.getByRole('button', { name: /next/i }));
- expect(nextSequenceHandler).not.toHaveBeenCalled();
+ expect(testData.nextSequenceHandler).not.toHaveBeenCalled();
// As `previousSequenceHandler` and `nextSequenceHandler` are mocked, we aren't really changing the position here.
// Therefore the next unit will still be `the initial one + 1`.
- expect(unitNavigationHandler).toHaveBeenNthCalledWith(2, String(Number(mockData.unitId) + 1));
+ expect(testData.unitNavigationHandler).toHaveBeenNthCalledWith(2, unitBlocks[unitNumber + 1].id);
expect(sendTrackEvent).toHaveBeenCalledTimes(2);
});
it('handles the `Previous` buttons for the first unit in the first sequence', async () => {
- sendTrackEvent.mockClear();
- const unitNavigationHandler = jest.fn();
- const previousSequenceHandler = jest.fn();
- const unitId = '1';
- render();
+ const testData = {
+ ...mockData,
+ unitId: unitBlocks[0].id,
+ sequenceId: sequenceBlock[0].id,
+ unitNavigationHandler: jest.fn(),
+ previousSequenceHandler: jest.fn(),
+ };
+ render(, { store: testStore });
loadUnit();
await waitFor(() => expect(screen.queryByText('Loading learning sequence...')).not.toBeInTheDocument());
screen.getAllByRole('button', { name: /previous/i }).forEach(button => fireEvent.click(button));
- expect(previousSequenceHandler).not.toHaveBeenCalled();
- expect(unitNavigationHandler).not.toHaveBeenCalled();
+ expect(testData.previousSequenceHandler).not.toHaveBeenCalled();
+ expect(testData.unitNavigationHandler).not.toHaveBeenCalled();
expect(sendTrackEvent).not.toHaveBeenCalled();
});
it('handles the `Next` buttons for the last unit in the last sequence', async () => {
- sendTrackEvent.mockClear();
- const unitNavigationHandler = jest.fn();
- const nextSequenceHandler = jest.fn();
- const unitId = String(testUnits.length);
- const sequenceId = String(Object.keys(initialState.models.sequences).length);
- render();
+ const testData = {
+ ...mockData,
+ unitId: unitBlocks[unitBlocks.length - 1].id,
+ sequenceId: sequenceBlock[sequenceBlock.length - 1].id,
+ unitNavigationHandler: jest.fn(),
+ nextSequenceHandler: jest.fn(),
+ };
+ render(, { store: testStore });
loadUnit();
await waitFor(() => expect(screen.queryByText('Loading learning sequence...')).not.toBeInTheDocument());
screen.getAllByRole('button', { name: /next/i }).forEach(button => fireEvent.click(button));
- expect(nextSequenceHandler).toHaveBeenCalledTimes(1);
- expect(unitNavigationHandler).not.toHaveBeenCalled();
- expect(sendTrackEvent).toHaveBeenCalledWith('edx.ui.lms.sequence.next_selected', {
- current_tab: Number(unitId),
- id: unitId,
- tab_count: testUnits.length,
- widget_placement: 'top',
- });
+ expect(testData.nextSequenceHandler).not.toHaveBeenCalled();
+ expect(testData.unitNavigationHandler).not.toHaveBeenCalled();
+ expect(sendTrackEvent).not.toHaveBeenCalled();
});
it('handles the navigation buttons for empty sequence', async () => {
- sendTrackEvent.mockClear();
- const testState = cloneDeep(initialState);
- testState.models.sequences['1'].unitIds = [];
+ const testSequenceBlock = [Factory.build(
+ 'block',
+ { type: 'sequential', children: [unitBlocks.map(block => block.id)] },
+ { courseId: courseMetadata.id },
+ ), Factory.build(
+ 'block',
+ { type: 'sequential', children: [] },
+ { courseId: courseMetadata.id },
+ ), Factory.build(
+ 'block',
+ { type: 'sequential', children: [unitBlocks.map(block => block.id)] },
+ { courseId: courseMetadata.id },
+ )];
+ const testSequenceMetadata = testSequenceBlock.map(block => Factory.build(
+ 'sequenceMetadata',
+ { courseId: courseMetadata.id },
+ { unitBlocks: block.children.length ? unitBlocks : [], sequenceBlock: block },
+ ));
+ const innerTestStore = await initializeTestStore({
+ courseMetadata, unitBlocks, sequenceBlock: testSequenceBlock, sequenceMetadata: testSequenceMetadata,
+ }, false);
+ const testData = {
+ ...mockData,
+ unitId: unitBlocks[0].id,
+ sequenceId: testSequenceBlock[1].id,
+ unitNavigationHandler: jest.fn(),
+ previousSequenceHandler: jest.fn(),
+ nextSequenceHandler: jest.fn(),
+ };
- const unitNavigationHandler = jest.fn();
- const previousSequenceHandler = jest.fn();
- const nextSequenceHandler = jest.fn();
- render(, { initialState: testState });
+ render(, { store: innerTestStore });
loadUnit();
await waitFor(() => expect(screen.queryByText('Loading learning sequence...')).not.toBeInTheDocument());
screen.getAllByRole('button', { name: /previous/i }).forEach(button => fireEvent.click(button));
- expect(previousSequenceHandler).toHaveBeenCalledTimes(2);
- expect(unitNavigationHandler).not.toHaveBeenCalled();
+ expect(testData.previousSequenceHandler).toHaveBeenCalledTimes(2);
+ expect(testData.unitNavigationHandler).not.toHaveBeenCalled();
screen.getAllByRole('button', { name: /next/i }).forEach(button => fireEvent.click(button));
- expect(nextSequenceHandler).toHaveBeenCalledTimes(2);
- expect(unitNavigationHandler).not.toHaveBeenCalled();
+ expect(testData.nextSequenceHandler).toHaveBeenCalledTimes(2);
+ expect(testData.unitNavigationHandler).not.toHaveBeenCalled();
expect(sendTrackEvent).toHaveBeenNthCalledWith(1, 'edx.ui.lms.sequence.previous_selected', {
current_tab: 1,
- id: mockData.unitId,
+ id: testData.unitId,
tab_count: 0,
widget_placement: 'top',
});
expect(sendTrackEvent).toHaveBeenNthCalledWith(2, 'edx.ui.lms.sequence.previous_selected', {
current_tab: 1,
- id: mockData.unitId,
+ id: testData.unitId,
tab_count: 0,
widget_placement: 'bottom',
});
expect(sendTrackEvent).toHaveBeenNthCalledWith(3, 'edx.ui.lms.sequence.next_selected', {
current_tab: 1,
- id: mockData.unitId,
+ id: testData.unitId,
tab_count: 0,
widget_placement: 'top',
});
expect(sendTrackEvent).toHaveBeenNthCalledWith(4, 'edx.ui.lms.sequence.next_selected', {
current_tab: 1,
- id: mockData.unitId,
+ id: testData.unitId,
tab_count: 0,
widget_placement: 'bottom',
});
});
it('handles unit navigation button', () => {
- sendTrackEvent.mockClear();
- const unitNavigationHandler = jest.fn();
- const targetUnit = '4';
- render();
+ const currentTabNumber = 1;
+ const targetUnitNumber = 2;
+ const targetUnit = unitBlocks[targetUnitNumber - 1];
+ const testData = {
+ ...mockData,
+ unitId: unitBlocks[currentTabNumber - 1].id,
+ sequenceId: sequenceBlock[0].id,
+ unitNavigationHandler: jest.fn(),
+ };
+ render(, { store: testStore });
- fireEvent.click(screen.getByRole('button', { name: targetUnit }));
- expect(unitNavigationHandler).toHaveBeenCalledWith(targetUnit);
+ fireEvent.click(screen.getByRole('button', { name: targetUnit.display_name }));
+ expect(testData.unitNavigationHandler).toHaveBeenCalledWith(targetUnit.id);
expect(sendTrackEvent).toHaveBeenCalledWith('edx.ui.lms.sequence.tab_selected', {
- current_tab: Number(mockData.unitId),
- id: mockData.unitId,
- target_tab: Number(targetUnit),
- tab_count: testUnits.length,
+ current_tab: currentTabNumber,
+ id: testData.unitId,
+ target_tab: targetUnitNumber,
+ tab_count: unitBlocks.length,
widget_placement: 'top',
});
});
diff --git a/src/courseware/course/sequence/SequenceContent.test.jsx b/src/courseware/course/sequence/SequenceContent.test.jsx
index a26521b1..23c60a27 100644
--- a/src/courseware/course/sequence/SequenceContent.test.jsx
+++ b/src/courseware/course/sequence/SequenceContent.test.jsx
@@ -1,36 +1,44 @@
import React from 'react';
-import { initialState, render, screen } from '../../../setupTest';
+import { initializeTestStore, render, screen } from '../../../setupTest';
import SequenceContent from './SequenceContent';
describe('Sequence Content', () => {
- const mockData = {
- gated: false,
- courseId: '1',
- sequenceId: '1',
- unitId: '1',
- unitLoadedHandler: () => {},
- intl: {},
- };
+ let mockData;
+ let store;
+
+ beforeAll(async () => {
+ store = await initializeTestStore();
+ const { models, courseware } = store.getState();
+ mockData = {
+ gated: false,
+ courseId: courseware.courseId,
+ sequenceId: courseware.sequenceId,
+ unitId: models.sequences[courseware.sequenceId].unitIds[0],
+ unitLoadedHandler: () => {},
+ };
+ });
it('displays loading message', () => {
- render(, { initialState });
+ render();
expect(screen.getByText('Loading learning sequence...')).toBeInTheDocument();
});
it('displays messages for the locked content', async () => {
- const { container } = render(, { initialState });
- expect(screen.getByText('Loading locked content messaging...')).toBeInTheDocument();
+ const { gatedContent } = store.getState().models.sequences[mockData.sequenceId];
+ const { container } = render();
+ expect(screen.getByText('Loading locked content messaging...')).toBeInTheDocument();
expect(await screen.findByText('Content Locked')).toBeInTheDocument();
- expect(screen.getByText('test-sequence')).toBeInTheDocument();
expect(screen.queryByText('Loading locked content messaging...')).not.toBeInTheDocument();
expect(container.querySelector('svg')).toHaveClass('fa-lock');
- expect(screen.getByText(/You must complete the prerequisite/)).toBeInTheDocument();
+ expect(screen.getByText(
+ `You must complete the prerequisite: '${gatedContent.gatedSectionName}' to access this content.`,
+ )).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'Go To Prerequisite Section' })).toBeInTheDocument();
});
it('displays message for no content', () => {
- render(, { initialState });
+ render();
expect(screen.getByText('There is no content here.')).toBeInTheDocument();
});
});
diff --git a/src/courseware/course/sequence/Unit.test.jsx b/src/courseware/course/sequence/Unit.test.jsx
index 16c23c11..6f65251a 100644
--- a/src/courseware/course/sequence/Unit.test.jsx
+++ b/src/courseware/course/sequence/Unit.test.jsx
@@ -1,50 +1,66 @@
import React from 'react';
-import { cloneDeep } from 'lodash';
+import { Factory } from 'rosie';
import {
- initialState, loadUnit, messageEvent, render, screen, waitFor,
+ initializeTestStore, loadUnit, messageEvent, render, screen, waitFor,
} from '../../../setupTest';
import Unit from './Unit';
describe('Unit', () => {
- const mockData = {
- id: '3',
- courseId: '1',
- intl: {},
- };
+ let mockData;
+ const courseMetadata = Factory.build(
+ 'courseMetadata',
+ { content_type_gating_enabled: true },
+ );
+ const unitBlocks = [Factory.build(
+ 'block',
+ { type: 'problem' },
+ { courseId: courseMetadata.id },
+ ), Factory.build(
+ 'block',
+ { type: 'vertical', graded: true, bookmarked: true },
+ { courseId: courseMetadata.id },
+ )];
+ const [unit, gradedUnit] = unitBlocks;
+
+ beforeAll(async () => {
+ await initializeTestStore({ courseMetadata, unitBlocks });
+ mockData = {
+ id: unit.id,
+ courseId: courseMetadata.id,
+ };
+ });
it('renders correctly', () => {
- render(, { initialState });
+ render();
expect(screen.getByText('Loading learning sequence...')).toBeInTheDocument();
- expect(screen.getByTitle(mockData.id)).toHaveAttribute('height', String(0));
- expect(screen.getByTitle(mockData.id)).toHaveAttribute(
+ const renderedUnit = screen.getByTitle(unit.display_name);
+ expect(renderedUnit).toHaveAttribute('height', String(0));
+ expect(renderedUnit).toHaveAttribute(
'src', `http://localhost:18000/xblock/${mockData.id}?show_title=0&show_bookmark_button=0`,
);
});
it('renders proper message for gated content', () => {
- // Clone initialState.
- const testState = cloneDeep(initialState);
- testState.models.units[mockData.id].graded = true;
- render(, { initialState: testState });
+ render();
- expect(screen.getByText('Loading locked content messaging...')).toBeInTheDocument();
expect(screen.getByText('Loading learning sequence...')).toBeInTheDocument();
+ expect(screen.getByText('Loading locked content messaging...')).toBeInTheDocument();
});
it('handles receiving MessageEvent', async () => {
- render(, { initialState });
+ render();
loadUnit();
// Loading message is gone now.
await waitFor(() => expect(screen.queryByText('Loading learning sequence...')).not.toBeInTheDocument());
// Iframe's height is set via message.
- expect(screen.getByTitle(mockData.id)).toHaveAttribute('height', String(messageEvent.payload.height));
+ expect(screen.getByTitle(unit.display_name)).toHaveAttribute('height', String(messageEvent.payload.height));
});
it('calls onLoaded after receiving MessageEvent', async () => {
const onLoaded = jest.fn();
- render(, { initialState });
+ render();
loadUnit();
await waitFor(() => expect(onLoaded).toHaveBeenCalledTimes(1));
@@ -54,24 +70,24 @@ describe('Unit', () => {
const onLoaded = jest.fn();
// Clone message and set different height.
const testMessageWithOtherHeight = { ...messageEvent, payload: { height: 200 } };
- render(, { initialState });
+ render();
loadUnit();
- await waitFor(() => expect(screen.getByTitle(mockData.id)).toHaveAttribute('height', String(messageEvent.payload.height)));
+ await waitFor(() => expect(screen.getByTitle(unit.display_name)).toHaveAttribute('height', String(messageEvent.payload.height)));
window.postMessage(testMessageWithOtherHeight, '*');
- await waitFor(() => expect(screen.getByTitle(mockData.id)).toHaveAttribute('height', String(testMessageWithOtherHeight.payload.height)));
+ await waitFor(() => expect(screen.getByTitle(unit.display_name)).toHaveAttribute('height', String(testMessageWithOtherHeight.payload.height)));
expect(onLoaded).toHaveBeenCalledTimes(1);
});
it('ignores MessageEvent with unhandled type', async () => {
// Clone message and set different type.
const testMessageWithUnhandledType = { ...messageEvent, type: 'wrong type' };
- render(, { initialState });
+ render();
window.postMessage(testMessageWithUnhandledType, '*');
// HACK: We don't have a function we could reliably await here, so this test relies on the timeout of `waitFor`.
await expect(waitFor(
- () => expect(screen.getByTitle(mockData.id)).toHaveAttribute('height', String(testMessageWithUnhandledType.payload.height)),
+ () => expect(screen.getByTitle(unit.display_name)).toHaveAttribute('height', String(testMessageWithUnhandledType.payload.height)),
{ timeout: 100 },
)).rejects.toThrowError(/Expected the element to have attribute/);
});
diff --git a/src/courseware/course/sequence/sequence-navigation/SequenceNavigation.jsx b/src/courseware/course/sequence/sequence-navigation/SequenceNavigation.jsx
index 44ab4f70..c5d38cb8 100644
--- a/src/courseware/course/sequence/sequence-navigation/SequenceNavigation.jsx
+++ b/src/courseware/course/sequence/sequence-navigation/SequenceNavigation.jsx
@@ -11,6 +11,7 @@ import UnitButton from './UnitButton';
import SequenceNavigationTabs from './SequenceNavigationTabs';
import { useSequenceNavigationMetadata } from './hooks';
import { useModel } from '../../../../generic/model-store';
+import { LOADED } from '../../../data/slice';
export default function SequenceNavigation({
unitId,
@@ -22,8 +23,10 @@ export default function SequenceNavigation({
}) {
const sequence = useModel('sequences', sequenceId);
const { isFirstUnit, isLastUnit } = useSequenceNavigationMetadata(sequenceId, unitId);
- const isLocked = sequence.gatedContent !== undefined && sequence.gatedContent.gated;
const sequenceStatus = useSelector(state => state.courseware.sequenceStatus);
+ const isLocked = sequenceStatus === LOADED ? (
+ sequence.gatedContent !== undefined && sequence.gatedContent.gated
+ ) : undefined;
const renderUnitButtons = () => {
if (isLocked) {
@@ -46,7 +49,7 @@ export default function SequenceNavigation({
);
};
- return sequenceStatus === 'loaded' && (
+ return sequenceStatus === LOADED && (