diff --git a/src/app/content/components/ContentWarning.spec.tsx b/src/app/content/components/ContentWarning.spec.tsx
index edb93b435e..57889aec04 100644
--- a/src/app/content/components/ContentWarning.spec.tsx
+++ b/src/app/content/components/ContentWarning.spec.tsx
@@ -1,28 +1,74 @@
-import React from 'react';
-import { renderToDom } from '../../../test/reactutils';
-import ContentWarning from './ContentWarning';
-import { act } from 'react-dom/test-utils';
-import ReactTestUtils from 'react-dom/test-utils';
import { book as archiveBook } from '../../../test/mocks/archiveLoader';
+import type rendererType from 'react-test-renderer';
+import type { ComponentType } from 'react';
import { mockCmsBook } from '../../../test/mocks/osWebLoader';
+import { reactAndFriends, resetModules } from '../../../test/utils';
import { formatBookData } from '../utils';
+
const dummyBook = {
...formatBookData(archiveBook, mockCmsBook),
content_warning_text: 'some warning text',
};
describe('ContentWarning', () => {
- it('renders warning modal', async() => {
- renderToDom();
+ let React: ReturnType['React']; // tslint:disable-line:variable-name
+ let ContentWarningDynamic: ComponentType; // tslint:disable-line:variable-name
+
+ describe('in browser', () => {
+ let renderToDom: ReturnType['renderToDom'];
+ let ReactDOMTestUtils: ReturnType['ReactDOMTestUtils']; // tslint:disable-line:variable-name
+
+ beforeEach(() => {
+ resetModules();
+ jest.doMock('react', () => {
+ const react = (jest as any).requireActual('react');
+ return { ...react, useEffect: react.useLayoutEffect };
+ });
+
+ ({React, renderToDom, ReactDOMTestUtils} = reactAndFriends());
+
+ ContentWarningDynamic = require('./ContentWarning').default;
+ });
+
+ it('renders warning modal and hides it after clicking', async() => {
+ renderToDom();
+
+ const b = document!.querySelector('button');
+
+ expect(b).toBeTruthy();
+ // Exercises the when-focus-is-already-in-the-modal branch
+ b!.focus();
+
+ ReactDOMTestUtils.act(() => ReactDOMTestUtils.Simulate.click(b!));
+
+ expect(document!.querySelector('button')).toBeFalsy();
+ });
+ });
+
+ describe('outside the browser', () => {
+ const windowBackup = window;
+ const documentBackup = document;
+
+ let renderer: typeof rendererType;
+
+ beforeEach(() => {
+ delete (global as any).window;
+ delete (global as any).document;
+ resetModules();
+ ({React, renderer} = reactAndFriends());
+
+ ContentWarningDynamic = require('./ContentWarning').default;
+ });
- const root = document?.body;
- const b = root?.querySelector('button');
+ afterEach(() => {
+ (global as any).window = windowBackup;
+ (global as any).document = documentBackup;
+ });
- expect(b).toBeTruthy();
- // Exercises the when-focus-is-already-in-the-modal branch
- b!.focus();
- act(() => ReactTestUtils.Simulate.click(b!));
- expect(root?.querySelector('button')).toBeFalsy();
+ it('mounts and unmounts without a dom', () => {
+ const component = renderer.create();
+ expect(() => component.unmount()).not.toThrow();
+ });
});
});
diff --git a/src/app/content/components/ContentWarning.tsx b/src/app/content/components/ContentWarning.tsx
index 59491f713c..1cd6333e01 100644
--- a/src/app/content/components/ContentWarning.tsx
+++ b/src/app/content/components/ContentWarning.tsx
@@ -70,24 +70,26 @@ function WarningDivWithTrap({
const useDismiss = (book: Book) => {
const cookieKey = `content-warning-${book.id}`;
- const [dismissed, setDismissed] = React.useState(Cookies.get(cookieKey) || 'false');
+ const [isShown, setIsShown] = React.useState(false);
React.useEffect(() => {
- setDismissed(Cookies.get(cookieKey) || 'false');
+ if (typeof window !== 'undefined') {
+ setIsShown(Cookies.get(cookieKey) !== 'true');
+ }
}, [cookieKey]);
const dismiss = React.useCallback(() => {
Cookies.set(cookieKey, 'true', { expires: 28 });
- setDismissed('true');
+ setIsShown(false);
}, [cookieKey]);
- return tuple(dismissed === 'true', dismiss);
+ return tuple(isShown, dismiss);
};
export default function ContentWarning({ book }: { book: Book }) {
- const [dismissed, dismiss] = useDismiss(book);
+ const [isShown, dismiss] = useDismiss(book);
- if (!hasOSWebData(book) || !book.content_warning_text || dismissed) {
+ if (!hasOSWebData(book) || !book.content_warning_text || !isShown) {
return null;
}
diff --git a/src/test/utils.ts b/src/test/utils.ts
index b6394113f3..45735a69c6 100644
--- a/src/test/utils.ts
+++ b/src/test/utils.ts
@@ -19,6 +19,7 @@ export const reactAndFriends = () => {
Provider: require('react-redux').Provider,
React: require('react'),
ReactDOM: require('react-dom') as typeof import ('react-dom'),
+ ReactDOMTestUtils: require('react-dom/test-utils') as typeof import ('react-dom/test-utils'),
Services: require('../app/context/Services'),
TestContainer: require('./TestContainer').default,
_jestStyledComponents: require('jest-styled-components'),