Skip to content

Commit 65eb721

Browse files
committed
Update tests
1 parent 45bc67e commit 65eb721

File tree

1 file changed

+51
-14
lines changed

1 file changed

+51
-14
lines changed

packages/crashlytics/src/react/index.test.tsx

Lines changed: 51 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,31 @@ import { MemoryRouter, Route } from 'react-router-dom';
3030
use(sinonChai);
3131
use(chaiAsPromised);
3232

33+
class TestErrorBoundary extends React.Component<
34+
{ children: React.ReactNode },
35+
{ error: Error | null }
36+
> {
37+
constructor(props: { children: React.ReactNode }) {
38+
super(props);
39+
this.state = { error: null };
40+
}
41+
42+
static getDerivedStateFromError(error: Error): { error: Error } {
43+
return { error };
44+
}
45+
46+
componentDidCatch(error: Error): void {
47+
// We can also log here if needed
48+
}
49+
50+
render(): React.ReactNode {
51+
if (this.state.error) {
52+
return null;
53+
}
54+
return this.props.children;
55+
}
56+
}
57+
3358
describe('FirebaseCrashlytics', () => {
3459
let getCrashlyticsStub: sinon.SinonStub;
3560
let recordErrorStub: sinon.SinonStub;
@@ -82,18 +107,21 @@ describe('FirebaseCrashlytics', () => {
82107
throw new Error('render error');
83108
};
84109

85-
it('captures render errors in routes', () => {
110+
it('captures render errors in routes and re-throws them', () => {
86111
// Stub console.error to avoid React error logging in test output
87112
const consoleErrorStub = stub(console, 'error');
88113

89-
render(
90-
<MemoryRouter>
91-
<CrashlyticsRoutes firebaseApp={fakeApp}>
92-
<Route path="/" element={<ThrowingComponent />} />
93-
</CrashlyticsRoutes>
94-
</MemoryRouter>
114+
const { container } = render(
115+
<TestErrorBoundary>
116+
<MemoryRouter>
117+
<CrashlyticsRoutes firebaseApp={fakeApp}>
118+
<Route path="/" element={<ThrowingComponent />} />
119+
</CrashlyticsRoutes>
120+
</MemoryRouter>
121+
</TestErrorBoundary>
95122
);
96123

124+
// Verify the error was recorded
97125
expect(getCrashlyticsStub).to.have.been.calledWith(fakeApp);
98126
expect(recordErrorStub).to.have.been.calledWith(
99127
fakeCrashlytics,
@@ -103,18 +131,24 @@ describe('FirebaseCrashlytics', () => {
103131
sinon.match({ route: '/' })
104132
);
105133

134+
// Verify the error was caught by our TestErrorBoundary (meaning it was re-thrown)
135+
// Since TestErrorBoundary returns null on error, container should be empty
136+
expect(container.firstChild).to.be.null;
137+
106138
consoleErrorStub.restore();
107139
});
108140

109-
it('captures parameterized route pattern', () => {
141+
it('captures parameterized route pattern and re-throws', () => {
110142
const consoleErrorStub = stub(console, 'error');
111143

112-
render(
113-
<MemoryRouter initialEntries={['/users/123']}>
114-
<CrashlyticsRoutes firebaseApp={fakeApp}>
115-
<Route path="/users/:id" element={<ThrowingComponent />} />
116-
</CrashlyticsRoutes>
117-
</MemoryRouter>
144+
const { container } = render(
145+
<TestErrorBoundary>
146+
<MemoryRouter initialEntries={['/users/123']}>
147+
<CrashlyticsRoutes firebaseApp={fakeApp}>
148+
<Route path="/users/:id" element={<ThrowingComponent />} />
149+
</CrashlyticsRoutes>
150+
</MemoryRouter>
151+
</TestErrorBoundary>
118152
);
119153

120154
expect(getCrashlyticsStub).to.have.been.calledWith(fakeApp);
@@ -126,6 +160,9 @@ describe('FirebaseCrashlytics', () => {
126160
sinon.match({ route: '/users/:id' })
127161
);
128162

163+
// Verify re-throw
164+
expect(container.firstChild).to.be.null;
165+
129166
consoleErrorStub.restore();
130167
});
131168
});

0 commit comments

Comments
 (0)