Skip to content

Commit 9a3ca65

Browse files
feat(sdk): Add in_foreground to event app context (#2826)
1 parent 2ccadb5 commit 9a3ca65

File tree

3 files changed

+66
-1
lines changed

3 files changed

+66
-1
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
### Features
6+
7+
- Add App Context `in_foreground` ([#2826](https://github.com/getsentry/sentry-react-native/pull/2826))
8+
39
## 5.0.0
410

511
The React Native SDK version 5 supports both Legacy (from RN 0.65 and above) and New Architecture (from RN 0.69 and above) as well as the new React Native Gradle Plugin (introduced in RN 0.71). For detailed [migration guide visit our docs](https://docs.sentry.io/platforms/react-native/migration/#from-4x-to-5x).

src/js/integrations/devicecontext.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* eslint-disable complexity */
22
import type { Event, EventProcessor, Hub, Integration } from '@sentry/types';
33
import { logger, severityLevelFromString } from '@sentry/utils';
4+
import { AppState } from 'react-native';
45

56
import { breadcrumbFromObject } from '../breadcrumb';
67
import type { NativeDeviceContextsResponse } from '../NativeRNSentry';
@@ -47,7 +48,14 @@ export class DeviceContext implements Integration {
4748
event.user = nativeUser;
4849
}
4950

50-
const nativeContext = native.context;
51+
let nativeContext = native.context;
52+
if (AppState.currentState !== 'unknown') {
53+
nativeContext = nativeContext || {};
54+
nativeContext.app = {
55+
...nativeContext.app,
56+
in_foreground: AppState.currentState === 'active',
57+
}
58+
}
5159
if (nativeContext) {
5260
event.contexts = { ...nativeContext, ...event.contexts };
5361
}

test/integrations/devicecontext.test.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,14 @@ import { DeviceContext } from '../../src/js/integrations';
55
import type { NativeDeviceContextsResponse } from '../../src/js/NativeRNSentry';
66
import { NATIVE } from '../../src/js/wrapper';
77

8+
let mockCurrentAppState: string = 'unknown';
9+
810
jest.mock('../../src/js/wrapper');
11+
jest.mock('react-native', () => ({
12+
AppState: new Proxy({}, { get: () => mockCurrentAppState }),
13+
NativeModules: {},
14+
Platform: {},
15+
}));
916

1017
describe('Device Context Integration', () => {
1118
let integration: DeviceContext;
@@ -122,6 +129,50 @@ describe('Device Context Integration', () => {
122129
});
123130
});
124131

132+
it('adds in_foreground false to native app contexts', async () => {
133+
mockCurrentAppState = 'background';
134+
const { processedEvent } = await executeIntegrationWith({
135+
nativeContexts: { context: { app: { native: 'value' } } },
136+
});
137+
expect(processedEvent).toStrictEqual({
138+
contexts: {
139+
app: {
140+
native: 'value',
141+
in_foreground: false,
142+
},
143+
},
144+
});
145+
});
146+
147+
it('adds in_foreground to native app contexts', async () => {
148+
mockCurrentAppState = 'active';
149+
const { processedEvent } = await executeIntegrationWith({
150+
nativeContexts: { context: { app: { native: 'value' } } },
151+
});
152+
expect(processedEvent).toStrictEqual({
153+
contexts: {
154+
app: {
155+
native: 'value',
156+
in_foreground: true,
157+
},
158+
},
159+
});
160+
});
161+
162+
it('do not add in_foreground if unknown', async () => {
163+
mockCurrentAppState = 'unknown';
164+
const { processedEvent } = await executeIntegrationWith({
165+
nativeContexts: { context: { app: { native: 'value' } } },
166+
});
167+
expect(processedEvent).toStrictEqual({
168+
contexts: {
169+
app: {
170+
native: 'value',
171+
},
172+
},
173+
});
174+
});
175+
125176
async function executeIntegrationWith({ nativeContexts, mockEvent }: {
126177
nativeContexts: Record<string, unknown>;
127178
mockEvent?: Event;

0 commit comments

Comments
 (0)