Skip to content

Commit df79861

Browse files
authored
fix: unit preview in course outline sidebar (#2940)
1 parent 24e1c73 commit df79861

3 files changed

Lines changed: 31 additions & 29 deletions

File tree

src/course-unit/unit-sidebar/UnitSidebarContext.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,11 @@ export const UnitSidebarProvider = ({
9494
);
9595
};
9696

97-
export function useUnitSidebarContext(): UnitSidebarContextData {
97+
export function useUnitSidebarContext(raiseError?: true): UnitSidebarContextData;
98+
export function useUnitSidebarContext(raiseError?: boolean): UnitSidebarContextData | undefined;
99+
export function useUnitSidebarContext(raiseError: boolean = true): UnitSidebarContextData | undefined {
98100
const ctx = useContext(UnitSidebarContext);
99-
if (ctx === undefined) {
101+
if (ctx === undefined && raiseError) {
100102
/* istanbul ignore next */
101103
throw new Error('useUnitSidebarContext() was used in a component without a <UnitSidebarProvider> ancestor.');
102104
}

src/course-unit/xblock-container-iframe/index.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ const XBlockContainerIframe: FC<XBlockContainerIframeProps> = ({
5858
const {
5959
setCurrentPageKey,
6060
setSelectedComponentId,
61-
} = useUnitSidebarContext();
61+
} = useUnitSidebarContext(!readonly) || {};
6262

6363
// Useful to reload iframe
6464
const [iframeKey, setIframeKey] = useState(0);
@@ -138,7 +138,7 @@ const XBlockContainerIframe: FC<XBlockContainerIframeProps> = ({
138138
const onDeleteSubmit = async () => {
139139
if (deleteXBlockId) {
140140
await unitXBlockActions.handleDelete(deleteXBlockId);
141-
setSelectedComponentId(undefined);
141+
setSelectedComponentId?.(undefined);
142142
closeDeleteModal();
143143
}
144144
};
@@ -192,7 +192,7 @@ const XBlockContainerIframe: FC<XBlockContainerIframeProps> = ({
192192

193193
const handleOpenManageTagsModal = (id: string) => {
194194
if (isUnitPageNewDesignEnabled()) {
195-
setCurrentPageKey('align', id);
195+
setCurrentPageKey?.('align', id);
196196
sendMessageToIframe(messageTypes.selectXblock, { locator: id });
197197
} else {
198198
// Legacy manage tags modal
@@ -219,7 +219,7 @@ const XBlockContainerIframe: FC<XBlockContainerIframeProps> = ({
219219
};
220220

221221
const handleXBlockSelected = (id) => {
222-
setCurrentPageKey('info', id);
222+
setCurrentPageKey?.('info', id);
223223
};
224224

225225
const messageHandlers = useMessageHandlers({

src/data/apiHooks.test.tsx

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -29,20 +29,20 @@ describe('useWaffleFlags', () => {
2929
axiosMock.onGet(getApiWaffleFlagsUrl()).reply(() => promise);
3030

3131
render(<FlagComponent />);
32-
expect(screen.getByLabelText('isLoading')).toHaveTextContent('loading');
33-
expect(screen.getByLabelText('isError')).toHaveTextContent('false');
32+
expect(await screen.findByLabelText('isLoading')).toHaveTextContent('loading');
33+
expect(await screen.findByLabelText('isError')).toHaveTextContent('false');
3434
// The default should be enabled, even before we hear back from the server:
35-
expect(screen.getByLabelText('useNewCourseOutlinePage')).toHaveTextContent('enabled');
35+
expect(await screen.findByLabelText('useNewCourseOutlinePage')).toHaveTextContent('enabled');
3636

3737
// Then, the server responds with a new value:
3838
resolveResponse([200, { useNewCourseOutlinePage: false }]);
3939

4040
// Now, we're no longer loading and we have the new value:
41-
await waitFor(() => {
42-
expect(screen.getByLabelText('isLoading')).toHaveTextContent('false');
41+
await waitFor(async () => {
42+
expect(await screen.findByLabelText('isLoading')).toHaveTextContent('false');
4343
});
44-
expect(screen.getByLabelText('isError')).toHaveTextContent('false');
45-
expect(screen.getByLabelText('useNewCourseOutlinePage')).toHaveTextContent('disabled');
44+
expect(await screen.findByLabelText('isError')).toHaveTextContent('false');
45+
expect(await screen.findByLabelText('useNewCourseOutlinePage')).toHaveTextContent('disabled');
4646
});
4747

4848
it('uses the default values if there\'s an error', async () => {
@@ -53,20 +53,20 @@ describe('useWaffleFlags', () => {
5353
axiosMock.onGet(getApiWaffleFlagsUrl()).reply(() => promise);
5454

5555
render(<FlagComponent />);
56-
expect(screen.getByLabelText('isLoading')).toHaveTextContent('loading');
57-
expect(screen.getByLabelText('isError')).toHaveTextContent('false');
56+
expect(await screen.findByLabelText('isLoading')).toHaveTextContent('loading');
57+
expect(await screen.findByLabelText('isError')).toHaveTextContent('false');
5858
// The default should be enabled, even before we hear back from the server:
59-
expect(screen.getByLabelText('useNewCourseOutlinePage')).toHaveTextContent('enabled');
59+
expect(await screen.findByLabelText('useNewCourseOutlinePage')).toHaveTextContent('enabled');
6060

6161
// Then, the server responds with an error
6262
resolveResponse([500, {}]);
6363

6464
// Now, we're no longer loading, we have an error state, and we still have the default value:
65-
await waitFor(() => {
66-
expect(screen.getByLabelText('isLoading')).toHaveTextContent('false');
65+
await waitFor(async () => {
66+
expect(await screen.findByLabelText('isLoading')).toHaveTextContent('false');
6767
});
68-
expect(screen.getByLabelText('isError')).toHaveTextContent('error');
69-
expect(screen.getByLabelText('useNewCourseOutlinePage')).toHaveTextContent('enabled');
68+
expect(await screen.findByLabelText('isError')).toHaveTextContent('error');
69+
expect(await screen.findByLabelText('useNewCourseOutlinePage')).toHaveTextContent('enabled');
7070
});
7171

7272
it('uses the global flag values while loading the course-specific flags', async () => {
@@ -81,26 +81,26 @@ describe('useWaffleFlags', () => {
8181

8282
// Check the global flag:
8383
render(<FlagComponent />);
84-
await waitFor(() => {
84+
await waitFor(async () => {
8585
// Once it loads the flags from the server, the global 'false' value will override the default 'true':
86-
expect(screen.getByLabelText('useNewCourseOutlinePage')).toHaveTextContent('disabled');
86+
expect(await screen.findByLabelText('useNewCourseOutlinePage')).toHaveTextContent('disabled');
8787
});
8888

8989
// Now check the course-specific flag:
9090
cleanup();
9191
render(<FlagComponent courseId={courseId} />);
9292

9393
// Now, the course-specific value is loading but in the meantime we use the global default:
94-
expect(screen.getByLabelText('isLoading')).toHaveTextContent('loading');
95-
expect(screen.getByLabelText('isError')).toHaveTextContent('false');
96-
expect(screen.getByLabelText('useNewCourseOutlinePage')).toHaveTextContent('disabled');
94+
expect(await screen.findByLabelText('isLoading')).toHaveTextContent('loading');
95+
expect(await screen.findByLabelText('isError')).toHaveTextContent('false');
96+
expect(await screen.findByLabelText('useNewCourseOutlinePage')).toHaveTextContent('disabled');
9797

9898
// Now the server responds: the course-specific flag is ON:
9999
resolveResponse([200, { useNewCourseOutlinePage: true }]);
100-
await waitFor(() => {
101-
expect(screen.getByLabelText('isLoading')).toHaveTextContent('false');
100+
await waitFor(async () => {
101+
expect(await screen.findByLabelText('isLoading')).toHaveTextContent('false');
102102
});
103-
expect(screen.getByLabelText('isError')).toHaveTextContent('false');
104-
expect(screen.getByLabelText('useNewCourseOutlinePage')).toHaveTextContent('enabled');
103+
expect(await screen.findByLabelText('isError')).toHaveTextContent('false');
104+
expect(await screen.findByLabelText('useNewCourseOutlinePage')).toHaveTextContent('enabled');
105105
});
106106
});

0 commit comments

Comments
 (0)