forked from firefox-devtools/profiler
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ErrorBoundary.test.js
98 lines (85 loc) · 3.43 KB
/
ErrorBoundary.test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// @flow
import * as React from 'react';
import { stripIndent } from 'common-tags';
import { render } from 'firefox-profiler/test/fixtures/testing-library';
import {
NonLocalizedErrorBoundary,
LocalizedErrorBoundary,
} from '../../components/app/ErrorBoundary';
import { withAnalyticsMock } from '../fixtures/mocks/analytics';
describe('app/NonLocalizedErrorBoundary', function () {
const childComponentText = 'This is a child component';
const friendlyErrorMessage = 'Oops, there was an error';
const technicalErrorMessage = 'This is an error.';
const ThrowingComponent = () => {
throw new Error(technicalErrorMessage);
};
function setupComponent(childComponent) {
const spy = jest.spyOn(console, 'error').mockImplementation(() => {});
const results = render(
<NonLocalizedErrorBoundary message={friendlyErrorMessage}>
{childComponent}
</NonLocalizedErrorBoundary>
);
return { spy, ...results };
}
it('matches the snapshot', () => {
const { container } = setupComponent(<ThrowingComponent />);
expect(container.firstChild).toMatchSnapshot();
});
it('shows the component children when there is no error', () => {
const { getByText } = setupComponent(childComponentText);
expect(getByText(childComponentText)).toBeInTheDocument();
});
it('shows the error message children when the component throws error', () => {
const { getByText } = setupComponent(<ThrowingComponent />);
expect(getByText(new RegExp(friendlyErrorMessage))).toBeInTheDocument();
});
it('surfaces the error via console.error', () => {
setupComponent(<ThrowingComponent />);
expect(console.error).toHaveBeenCalled();
});
it('reports errors to the analytics', () => {
withAnalyticsMock(() => {
setupComponent(<ThrowingComponent />);
expect(self.ga).toHaveBeenCalledWith('send', 'exception', {
exDescription: expect.stringMatching(
// This regexp looks a bit scary, but all it does is avoiding
// matching on things that depends on the environment (like path
// names) and path separators (unixes use `/` but windows uses `\`).
new RegExp(stripIndent`
Error: This is an error\\.
at ThrowingComponent \\(.*[/\\\\]ErrorBoundary.test.js:.*\\)
at ErrorBoundaryInternal \\(.*[/\\\\]ErrorBoundary.js:.*\\)
at NonLocalizedErrorBoundary
at LocalizationProvider \\(.*[/\\\\]@fluent[/\\\\]react[/\\\\]index.js:.*\\)
`)
),
exFatal: true,
});
});
});
});
describe('app/LocalizedErrorBoundary', function () {
const friendlyErrorMessage = 'Oops, there was an error';
const technicalErrorMessage = 'This is an error.';
const ThrowingComponent = () => {
throw new Error(technicalErrorMessage);
};
function setupComponent(childComponent) {
const spy = jest.spyOn(console, 'error').mockImplementation(() => {});
const results = render(
<LocalizedErrorBoundary message={friendlyErrorMessage}>
{childComponent}
</LocalizedErrorBoundary>
);
return { spy, ...results };
}
it('matches the snapshot', () => {
setupComponent(<ThrowingComponent />);
expect(document.body).toMatchSnapshot();
});
});