digidem / digidem/comapeo-core-react-native

Sentry: integration test for native captureEventJson / captureEnvelopeBase64 round-trip

Open
#67 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

priority: P3 sentry testing
Dominant language
Kotlin
Stars
1
Forks
0
Avg merge
8h 24m
Merged PRs (30d)
9

Description

Context

Phase 10 of the Sentry integration landed in #63: @sentry/node envelopes are forwarded to the native side via the control socket, deserialised, and captured through the native SDK so they ride sentry-android / sentry-cocoa's offline transport (plan-doc §5.7).

The PR added unit tests for:

  • envelopeToFrame routing (Node) — see backend/lib/sentry-frame.test.mjs.
  • ControlFrame.parse for the two new variants (Android + iOS) — see [ControlFrame test files].

What's NOT covered: the native-side happy-path capture — given a control-socket frame, that SentryFgsBridge.captureEventJson / SentryNativeBridge.captureEventJson actually deserialise the JSON into a SentryEvent AND that the resulting capture lands in the SDK's outbox. The current ControlFrame tests stop at "frame parsed into the right variant"; they don't link a real SDK or exercise the capture path.

Why it matters

Two failure modes that the current tests would miss:

  1. Deserialiser breakage. If sentry-android's SentryEvent.Deserializer or sentry-cocoa's SentryEventDecoder change their input contract — accepted JSON shape, mandatory fields, encoding — our forwarding silently drops events. The SentryEventDecoderSpiTest added in #63 catches sentry-cocoa renaming/removing the symbol, but not changing what it accepts.
  2. Wire-protocol drift. If @sentry/node's event JSON shape changes (a new mandatory field, a renamed field) and the native decoder requires it, again silent drop.

A short integration test that produces a known-good event JSON via @sentry/node's actual serializer, hands it to the bridge's captureEventJson, and asserts the event ended up in the SDK's envelope cache would catch both.

Scope

Android

A JVM unit test (using Robolectric if needed for Android Context, or a fake Hub if not) that:

  1. Initialises a sentry-android SDK with a fake DSN and a transport stub that records every envelope handed to it.
  2. Calls SentryFgsBridgeImpl.captureEventJson(payloadJson) with a JSON event built either by hand or by calling @sentry/node's serializer in a sibling Node test and embedding the result as a fixture.
  3. Asserts the transport stub received exactly one envelope, whose event item has the expected event_id / exception.values[0].value / level / tags.
iOS

An XCTest in the example app's test target (apps/example/tests/ios/) that:

  1. Initialises sentry-cocoa with a stub transport (SentryHttpTransport replacement via SentryOptions.transport) that records envelopes.
  2. Calls SentryNativeBridge.captureEventJson(_:) with a known event JSON.
  3. Asserts the stub received the envelope and the event item decoded correctly.

iOS additionally needs to verify captureEnvelopeBase64 because that path uses PrivateSentrySDKOnly.envelope(with:) + captureEnvelope: — different code path from the event decoder.

Optional: pair the test with a Node-side fixture generator

To keep the fixture honest (i.e. matches what @sentry/node actually emits), add a Node script (or extend backend/lib/sentry-frame.test.mjs) that:

  1. Initialises @sentry/node with a stub transport that captures the envelope.
  2. Calls Sentry.captureException(new Error("...")).
  3. Extracts the single event-item payload from the captured envelope.
  4. Writes it as a fixture file (backend/test/fixtures/sentry-event-error.json) that both the Android and iOS tests load.

That way the native fixtures stay in sync with whatever shape @sentry/node is emitting.

Acceptance criteria

  • Android: gradle :comapeo-core-react-native:testDebugUnitTest (or androidTest if Robolectric is overkill) includes a test that fails if SentryFgsBridgeImpl.captureEventJson doesn't produce a single envelope containing the expected event.
  • iOS: the example-app test target includes a test that fails if SentryNativeBridge.captureEventJson(_:) doesn't produce a captured envelope.
  • Test fixtures should be derivable from @sentry/node's actual output (not hand-rolled) so they catch upstream shape drift.

Related

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with backend/lib/sentry-frame.test.mjs and the bridge entry points SentryFgsBridgeImpl.captureEventJson, SentryNativeBridge.captureEventJson, and captureEnvelopeBase64. Review the existing apps/example/tests/ios/SentryEventDecoderSpiTest.swift and run the specified Gradle test command. Done means Android and iOS tests capture and validate one expected envelope, using fixtures derived from @sentry/node output.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, kotlin, swift
Domain
mobile-dev, observability, testing-qa
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.