@@ -56,6 +56,43 @@ test("capture called immediately after toggle-off makes zero fetch calls", () =>
5656 expect ( fetchCalls ( ) ) . toBe ( 0 ) ;
5757} ) ;
5858
59+ // Opting out is a statement about activity already generated, not only about
60+ // activity to come: events captured before the toggle must never be sent
61+ // afterwards. Dropping the singleton is not enough on its own — the outgoing
62+ // instance's batch timer would still fire and post its queue — so this test
63+ // guards the explicit discard. If a future change makes opt-out flush what it
64+ // was holding, this fails, and that is the point.
65+ test ( "opting out discards events captured before the toggle instead of sending them" , async ( ) => {
66+ let sends = 0 ;
67+ const fetchFn = ( ( ) => {
68+ sends ++ ;
69+ return Promise . resolve ( new Response ( "1" , { status : 200 } ) ) ;
70+ } ) as unknown as typeof fetch ;
71+ const { deps, getInstance } = fakeDeps ( {
72+ createTelemetry : ( opts ) =>
73+ createTelemetry ( {
74+ ...opts ,
75+ env : opts . env ?? { } ,
76+ apiKey : opts . apiKey ?? "test-key" ,
77+ fetchFn,
78+ // Short enough that an undiscarded queue would reach the network well
79+ // inside this test's wait, rather than passing by outrunning a timer.
80+ batch : { intervalMs : 20 } ,
81+ } ) ,
82+ } ) ;
83+ const handler = createTelemetryToggleHandler ( "/fake/path" , deps ) ;
84+
85+ handler ( true ) ;
86+ await new Promise ( ( resolve ) => setTimeout ( resolve , 10 ) ) ;
87+ getInstance ( ) . capture ( "cli_start" ) ;
88+ expect ( sends ) . toBe ( 0 ) ;
89+
90+ handler ( false ) ;
91+ await new Promise ( ( resolve ) => setTimeout ( resolve , 150 ) ) ;
92+ expect ( getInstance ( ) . enabled ) . toBe ( false ) ;
93+ expect ( sends ) . toBe ( 0 ) ;
94+ } ) ;
95+
5996test ( "save rejection leaves the singleton disabled with no unhandled rejection" , async ( ) => {
6097 const { deps, getInstance } = fakeDeps ( {
6198 saveGlobalSettings : async ( ) => {
@@ -90,7 +127,12 @@ test("load failure skips persistence entirely and stays disabled in memory", asy
90127test ( "toggle on while env-killed writes nothing and swaps no instance" , async ( ) => {
91128 let ensureCalled = false ;
92129 let saveCalled = false ;
93- const initial : Telemetry = { enabled : false , capture : ( ) => { } , flush : async ( ) => { } } ;
130+ const initial : Telemetry = {
131+ enabled : false ,
132+ capture : ( ) => { } ,
133+ flush : async ( ) => { } ,
134+ discard : ( ) => { } ,
135+ } ;
94136 let setInstance : Telemetry | undefined ;
95137 const { deps } = fakeDeps ( {
96138 getTelemetry : ( ) => initial ,
0 commit comments