@@ -4,8 +4,11 @@ import type { Scope, Span } from '@sentry/core';
44import * as SentryCore from '@sentry/core' ;
55import {
66 _INTERNAL_setSpanForScope ,
7+ Client ,
8+ createTransport ,
79 getDefaultCurrentScope ,
810 getDefaultIsolationScope ,
11+ resolvedSyncPromise ,
912 setAsyncContextStrategy ,
1013} from '@sentry/core' ;
1114import { afterAll , afterEach , beforeAll , beforeEach , describe , expect , it , type MockInstance , vi } from 'vitest' ;
@@ -17,7 +20,28 @@ interface TestStore {
1720 isolationScope : Scope ;
1821}
1922
20- // `bindTracingChannelToSpan` only binds (and `setupOnce` only subscribes via
23+ class TestClient extends Client < any > {
24+ public constructor ( options : any ) {
25+ super ( options ) ;
26+ }
27+ public eventFromException ( ) : PromiseLike < any > {
28+ return resolvedSyncPromise ( { } ) ;
29+ }
30+ public eventFromMessage ( ) : PromiseLike < any > {
31+ return resolvedSyncPromise ( { } ) ;
32+ }
33+ }
34+
35+ function createTestClient ( ) : Client {
36+ return new TestClient ( {
37+ dsn : 'https://username@domain/123' ,
38+ integrations : [ ] ,
39+ transport : ( ) => createTransport ( { recordDroppedEvent : ( ) => undefined } , ( ) => resolvedSyncPromise ( { } ) ) ,
40+ stackParser : ( ) => [ ] ,
41+ } ) ;
42+ }
43+
44+ // `bindTracingChannelToSpan` only binds (and `setup` only subscribes via
2145// `waitForTracingChannelBinding`) when an async-context strategy exposes a
2246// `getTracingChannelBinding`. Install a minimal one so the channel
2347// subscriptions actually register in this unit-test context (no SDK `init`).
@@ -61,6 +85,15 @@ function installTestAsyncContextStrategy(): void {
6185 } ) ;
6286}
6387
88+ // Channel subscribers only register once orchestrion reports a matching module
89+ // as injected (`invokeOrchestrionInstrumentation`). Emit that event after
90+ // `setup` so subscriptions land synchronously under the test strategy above.
91+ function setupPostgresChannelIntegration ( options ?: { ignoreConnectSpans ?: boolean } ) : void {
92+ const client = createTestClient ( ) ;
93+ postgresChannelIntegration ( options ) . setup ?.( client ) ;
94+ client . emit ( 'orchestrion.module-runtime-injected' , 'pg' ) ;
95+ }
96+
6497// The subscriber builds spans via `startInactiveSpan` and gates on
6598// `getActiveSpan`. We spy both: `getActiveSpan` to satisfy the
6699// requireParentSpan gate, and `startInactiveSpan` to capture the span
@@ -84,10 +117,10 @@ describe('postgresChannelIntegration', () => {
84117
85118 // Subscribe once for the whole file so a single subscriber handles each
86119 // publish (avoids accumulating duplicate subscriptions across tests). The
87- // strategy must be installed first so `setupOnce `'s `waitForTracingChannelBinding` fires synchronously.
120+ // strategy must be installed first so `setup `'s `waitForTracingChannelBinding` fires synchronously.
88121 beforeAll ( ( ) => {
89122 installTestAsyncContextStrategy ( ) ;
90- postgresChannelIntegration ( ) . setupOnce ?. ( ) ;
123+ setupPostgresChannelIntegration ( ) ;
91124 } ) ;
92125
93126 afterAll ( ( ) => {
0 commit comments