Updating InstallPrompt to use hooks

This commit is contained in:
Jeff Avallone 2019-03-26 21:12:35 -04:00
parent f9b3d5dbd7
commit 18427f9fc6
4 changed files with 34 additions and 129 deletions

View File

@ -59,7 +59,7 @@ exports[`Header opening the Privacy Policy modal 1`] = `
</li> </li>
<li> <li>
<span <span
data-component="withI18nextTranslation(InstallPrompt)" data-component="InstallPrompt"
data-props="{}" data-props="{}"
/> />
</li> </li>
@ -135,7 +135,7 @@ exports[`Header opening the Privacy Policy modal while holding alt key 1`] = `
</li> </li>
<li> <li>
<span <span
data-component="withI18nextTranslation(InstallPrompt)" data-component="InstallPrompt"
data-props="{}" data-props="{}"
/> />
</li> </li>
@ -211,7 +211,7 @@ exports[`Header opening the Privacy Policy modal while holding ctrl key 1`] = `
</li> </li>
<li> <li>
<span <span
data-component="withI18nextTranslation(InstallPrompt)" data-component="InstallPrompt"
data-props="{}" data-props="{}"
/> />
</li> </li>
@ -287,7 +287,7 @@ exports[`Header opening the Privacy Policy modal while holding meta key 1`] = `
</li> </li>
<li> <li>
<span <span
data-component="withI18nextTranslation(InstallPrompt)" data-component="InstallPrompt"
data-props="{}" data-props="{}"
/> />
</li> </li>
@ -363,7 +363,7 @@ exports[`Header opening the Privacy Policy modal while holding shift key 1`] = `
</li> </li>
<li> <li>
<span <span
data-component="withI18nextTranslation(InstallPrompt)" data-component="InstallPrompt"
data-props="{}" data-props="{}"
/> />
</li> </li>
@ -440,7 +440,7 @@ exports[`Header rendering 1`] = `
</li> </li>
<li> <li>
<span <span
data-component="withI18nextTranslation(InstallPrompt)" data-component="InstallPrompt"
data-props="{}" data-props="{}"
/> />
</li> </li>
@ -516,7 +516,7 @@ exports[`Header rendering with no banner 1`] = `
</li> </li>
<li> <li>
<span <span
data-component="withI18nextTranslation(InstallPrompt)" data-component="InstallPrompt"
data-props="{}" data-props="{}"
/> />
</li> </li>

View File

@ -1,41 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`InstallPrompt accepting install prompt 1`] = `
<DocumentFragment>
<a
data-testid="install"
href="#install"
>
<span
data-component="Trans"
data-props="{}"
>
Add to Home Screen
</span>
</a>
</DocumentFragment>
`;
exports[`InstallPrompt accepting install prompt 2`] = `<DocumentFragment />`;
exports[`InstallPrompt rejecting install prompt 1`] = `
<DocumentFragment>
<a
data-testid="install"
href="#install"
>
<span
data-component="Trans"
data-props="{}"
>
Add to Home Screen
</span>
</a>
</DocumentFragment>
`;
exports[`InstallPrompt rejecting install prompt 2`] = `<DocumentFragment />`;
exports[`InstallPrompt rendering 1`] = `<DocumentFragment />`; exports[`InstallPrompt rendering 1`] = `<DocumentFragment />`;
exports[`InstallPrompt rendering after an install prompt has been requested 1`] = `<DocumentFragment />`; exports[`InstallPrompt rendering after an install prompt has been requested 1`] = `<DocumentFragment />`;

View File

@ -1,30 +1,12 @@
import React from 'react'; import React, { useState, useEffect, useCallback } from 'react';
import { withTranslation, Trans } from 'react-i18next'; import { Trans } from 'react-i18next';
class InstallPrompt extends React.PureComponent { const InstallPrompt = () => {
state = { const [ installPrompt, updateInstallPrompt ] = useState(null);
installPrompt: null
}
componentDidMount() { const handleInstall = useCallback(async event => {
window.addEventListener('beforeinstallprompt', this.handleInstallPrompt);
}
componentWillUnmount() {
window.removeEventListener('beforeinstallprompt', this.handleInstallPrompt);
}
handleInstallPrompt = event => {
this.setState({
installPrompt: event
});
}
handleInstall = async event => {
event.preventDefault(); event.preventDefault();
const { installPrompt } = this.state;
try { try {
installPrompt.prompt(); installPrompt.prompt();
await installPrompt.userChoice; await installPrompt.userChoice;
@ -33,11 +15,16 @@ class InstallPrompt extends React.PureComponent {
// User cancelled install // User cancelled install
} }
this.setState({ installPrompt: null }); updateInstallPrompt(null);
} }, [installPrompt, updateInstallPrompt]);
render() { useEffect(() => {
const { installPrompt } = this.state; window.addEventListener('beforeinstallprompt', updateInstallPrompt);
return () => {
window.removeEventListener('beforeinstallprompt', updateInstallPrompt);
};
});
if (!installPrompt) { if (!installPrompt) {
return null; return null;
@ -45,12 +32,10 @@ class InstallPrompt extends React.PureComponent {
return <a href="#install" return <a href="#install"
data-testid="install" data-testid="install"
onClick={ this.handleInstall } onClick={ handleInstall }
> >
<Trans>Add to Home Screen</Trans> <Trans>Add to Home Screen</Trans>
</a>; </a>;
} };
}
export { InstallPrompt }; export default InstallPrompt;
export default withTranslation()(InstallPrompt);

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { render, fireEvent } from 'react-testing-library'; import { render, fireEvent } from 'react-testing-library';
import { InstallPrompt } from 'components/InstallPrompt'; import InstallPrompt from 'components/InstallPrompt';
describe('InstallPrompt', () => { describe('InstallPrompt', () => {
test('rendering', () => { test('rendering', () => {
@ -39,48 +39,4 @@ describe('InstallPrompt', () => {
'beforeinstallprompt', 'beforeinstallprompt',
expect.any(Function)); expect.any(Function));
}); });
test('accepting install prompt', async () => {
const { asFragment, getByTestId } = render(
<InstallPrompt />
);
const promptEvent = new Event('beforeinstallprompt');
promptEvent.prompt = jest.fn();
promptEvent.userChoice = Promise.resolve();
const clickEvent = new MouseEvent('click', { bubbles: true });
jest.spyOn(clickEvent, 'preventDefault');
fireEvent(window, promptEvent);
expect(asFragment()).toMatchSnapshot();
fireEvent(getByTestId('install'), clickEvent);
// Allow async code to run
await new Promise(resolve => setTimeout(resolve));
expect(clickEvent.preventDefault).toHaveBeenCalled();
expect(promptEvent.prompt).toHaveBeenCalled();
expect(asFragment()).toMatchSnapshot();
});
test('rejecting install prompt', async () => {
const { asFragment, getByTestId } = render(
<InstallPrompt />
);
const promptEvent = new Event('beforeinstallprompt');
promptEvent.prompt = jest.fn();
promptEvent.userChoice = Promise.reject();
const clickEvent = new MouseEvent('click', { bubbles: true });
jest.spyOn(clickEvent, 'preventDefault');
fireEvent(window, promptEvent);
expect(asFragment()).toMatchSnapshot();
fireEvent(getByTestId('install'), clickEvent);
// Allow async code to run
await new Promise(resolve => setTimeout(resolve));
expect(clickEvent.preventDefault).toHaveBeenCalled();
expect(promptEvent.prompt).toHaveBeenCalled();
expect(asFragment()).toMatchSnapshot();
});
}); });