Skip to content

Commit c10f417

Browse files
fix(expo-context): All values should be lowercase (#4809)
1 parent 8120f0c commit c10f417

File tree

3 files changed

+72
-11
lines changed

3 files changed

+72
-11
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
### Fixes
1212

1313
- Expo Updates Context is passed to native after native init to be available for crashes ([#4808](https://github.com/getsentry/sentry-react-native/pull/4808))
14+
- Expo Updates Context values should all be lowercase ([#4809](https://github.com/getsentry/sentry-react-native/pull/4809))
1415

1516
### Dependencies
1617

packages/core/src/js/integrations/expocontext.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,10 @@ export const expoContextIntegration = (): Integration => {
7070
};
7171
};
7272

73-
function getExpoUpdatesContext(): ExpoUpdatesContext {
73+
/**
74+
* @internal Exposed for testing purposes
75+
*/
76+
export function getExpoUpdatesContext(): ExpoUpdatesContext {
7477
const expoUpdates = getExpoUpdates();
7578
if (!expoUpdates) {
7679
return {
@@ -85,19 +88,19 @@ function getExpoUpdatesContext(): ExpoUpdatesContext {
8588
is_using_embedded_assets: !!expoUpdates.isUsingEmbeddedAssets,
8689
};
8790

88-
if (typeof expoUpdates.updateId === 'string') {
89-
updatesContext.update_id = expoUpdates.updateId;
91+
if (typeof expoUpdates.updateId === 'string' && expoUpdates.updateId) {
92+
updatesContext.update_id = expoUpdates.updateId.toLowerCase();
9093
}
91-
if (typeof expoUpdates.channel === 'string') {
92-
updatesContext.channel = expoUpdates.channel;
94+
if (typeof expoUpdates.channel === 'string' && expoUpdates.channel) {
95+
updatesContext.channel = expoUpdates.channel.toLowerCase();
9396
}
94-
if (typeof expoUpdates.runtimeVersion === 'string') {
95-
updatesContext.runtime_version = expoUpdates.runtimeVersion;
97+
if (typeof expoUpdates.runtimeVersion === 'string' && expoUpdates.runtimeVersion) {
98+
updatesContext.runtime_version = expoUpdates.runtimeVersion.toLowerCase();
9699
}
97-
if (typeof expoUpdates.checkAutomatically === 'string') {
98-
updatesContext.check_automatically = expoUpdates.checkAutomatically;
100+
if (typeof expoUpdates.checkAutomatically === 'string' && expoUpdates.checkAutomatically) {
101+
updatesContext.check_automatically = expoUpdates.checkAutomatically.toLowerCase();
99102
}
100-
if (typeof expoUpdates.emergencyLaunchReason === 'string') {
103+
if (typeof expoUpdates.emergencyLaunchReason === 'string' && expoUpdates.emergencyLaunchReason) {
101104
updatesContext.emergency_launch_reason = expoUpdates.emergencyLaunchReason;
102105
}
103106
if (typeof expoUpdates.launchDuration === 'number') {

packages/core/test/integrations/expocontext.test.ts

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { type Client, type Event, getCurrentScope, getGlobalScope, getIsolationScope } from '@sentry/core';
22

3-
import { expoContextIntegration, OTA_UPDATES_CONTEXT_KEY } from '../../src/js/integrations/expocontext';
3+
import {
4+
expoContextIntegration,
5+
getExpoUpdatesContext,
6+
OTA_UPDATES_CONTEXT_KEY,
7+
} from '../../src/js/integrations/expocontext';
48
import * as environment from '../../src/js/utils/environment';
59
import type { ExpoUpdates } from '../../src/js/utils/expoglobalobject';
610
import { getExpoDevice } from '../../src/js/utils/expomodules';
@@ -311,6 +315,59 @@ describe('Expo Context Integration', () => {
311315
});
312316
});
313317

318+
describe('getExpoUpdatesContext', () => {
319+
it('does not return empty values', () => {
320+
jest.spyOn(expoModules, 'getExpoUpdates').mockReturnValue({
321+
isEnabled: false,
322+
isEmbeddedLaunch: false,
323+
isEmergencyLaunch: false,
324+
isUsingEmbeddedAssets: false,
325+
updateId: '',
326+
channel: '',
327+
runtimeVersion: '',
328+
checkAutomatically: '',
329+
emergencyLaunchReason: '',
330+
launchDuration: 0,
331+
createdAt: new Date('2021-01-01T00:00:00.000Z'),
332+
});
333+
334+
const expoUpdates = getExpoUpdatesContext();
335+
336+
expect(expoUpdates).toStrictEqual({
337+
is_enabled: false,
338+
is_embedded_launch: false,
339+
is_emergency_launch: false,
340+
is_using_embedded_assets: false,
341+
launch_duration: 0,
342+
created_at: '2021-01-01T00:00:00.000Z',
343+
});
344+
});
345+
346+
it('lowercases all string values', () => {
347+
jest.spyOn(expoModules, 'getExpoUpdates').mockReturnValue({
348+
updateId: 'UPPERCASE-123',
349+
channel: 'UPPERCASE-123',
350+
runtimeVersion: 'UPPERCASE-123',
351+
checkAutomatically: 'UPPERCASE-123',
352+
emergencyLaunchReason: 'This is a description of the reason.',
353+
createdAt: new Date('2021-01-01T00:00:00.000Z'),
354+
});
355+
356+
const expoUpdates = getExpoUpdatesContext();
357+
358+
expect(expoUpdates).toEqual(
359+
expect.objectContaining({
360+
update_id: 'uppercase-123',
361+
channel: 'uppercase-123',
362+
runtime_version: 'uppercase-123',
363+
check_automatically: 'uppercase-123',
364+
emergency_launch_reason: 'This is a description of the reason.', // Description should be kept as is
365+
created_at: '2021-01-01T00:00:00.000Z', // Date should keep ISO string format
366+
}),
367+
);
368+
});
369+
});
370+
314371
function executeIntegrationFor(mockedEvent: Event): Event {
315372
return expoContextIntegration().processEvent!(mockedEvent, {}, {} as Client) as Event;
316373
}

0 commit comments

Comments
 (0)