Skip to content

Commit 4ae9d3c

Browse files
test: replacing snapshot tests with RTL tests part 16 (#2252)
1 parent 3673c5f commit 4ae9d3c

File tree

2 files changed

+27
-38
lines changed

2 files changed

+27
-38
lines changed

src/generic/hooks/tests/hooks.test.tsx

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
11
import React from 'react';
22
import { getConfig } from '@edx/frontend-platform';
33
import { act, renderHook } from '@testing-library/react';
4-
import { useKeyedState } from '@edx/react-unit-test-utils';
54
import { logError } from '@edx/frontend-platform/logging';
6-
import { iframeMessageTypes, iframeStateKeys } from '../../../constants';
7-
import { useIframeBehavior } from '../useIframeBehavior';
5+
import { iframeMessageTypes } from '../../../constants';
6+
import { useIframeBehavior, iframeBehaviorState } from '../useIframeBehavior';
87
import { useLoadBearingHook } from '../useLoadBearingHook';
98

109
jest.useFakeTimers();
1110

12-
jest.mock('@edx/react-unit-test-utils', () => ({
13-
useKeyedState: jest.fn(),
14-
}));
15-
1611
jest.mock('@edx/frontend-platform/logging', () => ({
1712
logError: jest.fn(),
1813
}));
@@ -27,20 +22,10 @@ describe('useIframeBehavior', () => {
2722
const iframeRef = { current: { contentWindow: null } as HTMLIFrameElement };
2823

2924
beforeEach(() => {
30-
(useKeyedState as jest.Mock).mockImplementation((key, initialValue) => {
31-
switch (key) {
32-
case iframeStateKeys.iframeHeight:
33-
return [0, setIframeHeight];
34-
case iframeStateKeys.hasLoaded:
35-
return [false, setHasLoaded];
36-
case iframeStateKeys.showError:
37-
return [false, setShowError];
38-
case iframeStateKeys.windowTopOffset:
39-
return [null, setWindowTopOffset];
40-
default:
41-
return [initialValue, jest.fn()];
42-
}
43-
});
25+
jest.spyOn(iframeBehaviorState, 'iframeHeight').mockImplementation(() => [0, setIframeHeight]);
26+
jest.spyOn(iframeBehaviorState, 'hasLoaded').mockImplementation(() => [false, setHasLoaded]);
27+
jest.spyOn(iframeBehaviorState, 'showError').mockImplementation(() => [false, setShowError]);
28+
jest.spyOn(iframeBehaviorState, 'windowTopOffset').mockImplementation(() => [null, setWindowTopOffset]);
4429

4530
window.scrollTo = jest.fn((x: number | ScrollToOptions, y?: number): void => {
4631
const scrollY = typeof x === 'number' ? y : (x as ScrollToOptions).top || 0;
@@ -58,14 +43,7 @@ describe('useIframeBehavior', () => {
5843

5944
it('scrolls to previous position on video fullscreen exit', () => {
6045
const mockWindowTopOffset = 100;
61-
62-
(useKeyedState as jest.Mock).mockImplementation((key) => {
63-
if (key === iframeStateKeys.windowTopOffset) {
64-
return [mockWindowTopOffset, setWindowTopOffset];
65-
}
66-
return [null, jest.fn()];
67-
});
68-
46+
jest.spyOn(iframeBehaviorState, 'windowTopOffset').mockImplementation(() => [mockWindowTopOffset, setWindowTopOffset]);
6947
renderHook(() => useIframeBehavior({ id, iframeUrl, iframeRef }));
7048

7149
const message = {

src/generic/hooks/useIframeBehavior.tsx

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
1-
import { useCallback, useEffect } from 'react';
1+
import { useCallback, useEffect, useState } from 'react';
22
import { logError } from '@edx/frontend-platform/logging';
3-
// eslint-disable-next-line import/no-extraneous-dependencies
4-
import { useKeyedState } from '@edx/react-unit-test-utils';
5-
3+
import StrictDict from '@src/editors/utils/StrictDict';
64
import { useLoadBearingHook } from './useLoadBearingHook';
7-
import { iframeStateKeys, iframeMessageTypes } from '../../constants';
5+
import { iframeMessageTypes } from '../../constants';
86
import { UseIFrameBehaviorReturnTypes, UseIFrameBehaviorTypes } from '../types';
97
import { useEventListener } from './useEventListener';
108

9+
/**
10+
* Internal state hooks for useIFrameBehavior.
11+
* Defined and exported here so they can be mocked/manipulated in tests.
12+
*/
13+
export const iframeBehaviorState = StrictDict({
14+
/* eslint-disable react-hooks/rules-of-hooks */
15+
iframeHeight: (val) => useState<number>(val),
16+
hasLoaded: (val) => useState<boolean>(val),
17+
showError: (val) => useState<boolean>(val),
18+
windowTopOffset: (val) => useState<number | null>(val),
19+
/* eslint-enable react-hooks/rules-of-hooks */
20+
});
21+
1122
/**
1223
* Custom hook to manage iframe behavior.
1324
*
@@ -31,10 +42,10 @@ export const useIframeBehavior = ({
3142
// Do not remove this hook. See function description.
3243
useLoadBearingHook(id);
3344

34-
const [iframeHeight, setIframeHeight] = useKeyedState<number>(iframeStateKeys.iframeHeight, 0);
35-
const [hasLoaded, setHasLoaded] = useKeyedState<boolean>(iframeStateKeys.hasLoaded, false);
36-
const [showError, setShowError] = useKeyedState<boolean>(iframeStateKeys.showError, false);
37-
const [windowTopOffset, setWindowTopOffset] = useKeyedState<number | null>(iframeStateKeys.windowTopOffset, null);
45+
const [iframeHeight, setIframeHeight] = iframeBehaviorState.iframeHeight(0);
46+
const [hasLoaded, setHasLoaded] = iframeBehaviorState.hasLoaded(false);
47+
const [showError, setShowError] = iframeBehaviorState.showError(false);
48+
const [windowTopOffset, setWindowTopOffset] = iframeBehaviorState.windowTopOffset(null);
3849

3950
const receiveMessage = useCallback((event: MessageEvent) => {
4051
if (!iframeRef.current || event.source !== iframeRef.current.contentWindow) {

0 commit comments

Comments
 (0)