Skip to content

Commit

Permalink
fix contentwarning to not show in prerendering (#2375)
Browse files Browse the repository at this point in the history
* fix contentwarning to not show in prerendering

* 👕

* 👕
  • Loading branch information
TomWoodward authored Nov 5, 2024
1 parent ef9e4a0 commit 7dc5239
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 20 deletions.
74 changes: 60 additions & 14 deletions src/app/content/components/ContentWarning.spec.tsx
Original file line number Diff line number Diff line change
@@ -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(<ContentWarning book={dummyBook} />);
let React: ReturnType<typeof reactAndFriends>['React']; // tslint:disable-line:variable-name
let ContentWarningDynamic: ComponentType<any>; // tslint:disable-line:variable-name

describe('in browser', () => {
let renderToDom: ReturnType<typeof reactAndFriends>['renderToDom'];
let ReactDOMTestUtils: ReturnType<typeof reactAndFriends>['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(<ContentWarningDynamic book={dummyBook} />);

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(<ContentWarningDynamic book={dummyBook} />);
expect(() => component.unmount()).not.toThrow();
});
});
});
14 changes: 8 additions & 6 deletions src/app/content/components/ContentWarning.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,24 +70,26 @@ function WarningDivWithTrap({

const useDismiss = (book: Book) => {
const cookieKey = `content-warning-${book.id}`;
const [dismissed, setDismissed] = React.useState<string>(Cookies.get(cookieKey) || 'false');
const [isShown, setIsShown] = React.useState<boolean>(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;
}

Expand Down
1 change: 1 addition & 0 deletions src/test/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'),
Expand Down

0 comments on commit 7dc5239

Please sign in to comment.