@@ -3,6 +3,7 @@ import * as vscode from "vscode";
33
44import { MementoManager } from "@/core/mementoManager" ;
55import { SecretsManager } from "@/core/secretsManager" ;
6+ import { CALLBACK_PATH } from "@/oauth/utils" ;
67import { maybeAskUrl } from "@/promptUtils" ;
78import { registerUriHandler } from "@/uri/uriHandler" ;
89
@@ -318,4 +319,66 @@ describe("uriHandler", () => {
318319 ) ;
319320 } ) ;
320321 } ) ;
322+
323+ describe ( CALLBACK_PATH , ( ) => {
324+ type CallbackData = {
325+ state : string ;
326+ code : string | null ;
327+ error : string | null ;
328+ } ;
329+
330+ it ( "stores OAuth callback with code and state" , async ( ) => {
331+ const { handleUri, secretsManager } = createTestContext ( ) ;
332+
333+ const callbackPromise = new Promise < CallbackData > ( ( resolve ) => {
334+ secretsManager . onDidChangeOAuthCallback ( resolve ) ;
335+ } ) ;
336+
337+ await handleUri (
338+ createMockUri ( CALLBACK_PATH , "code=auth-code&state=test-state" ) ,
339+ ) ;
340+
341+ const callbackData = await callbackPromise ;
342+ expect ( callbackData ) . toEqual ( {
343+ state : "test-state" ,
344+ code : "auth-code" ,
345+ error : null ,
346+ } ) ;
347+ } ) ;
348+
349+ it ( "stores OAuth callback with error" , async ( ) => {
350+ const { handleUri, secretsManager } = createTestContext ( ) ;
351+
352+ const callbackPromise = new Promise < CallbackData > ( ( resolve ) => {
353+ secretsManager . onDidChangeOAuthCallback ( resolve ) ;
354+ } ) ;
355+
356+ await handleUri (
357+ createMockUri ( CALLBACK_PATH , "state=test-state&error=access_denied" ) ,
358+ ) ;
359+
360+ const callbackData = await callbackPromise ;
361+ expect ( callbackData ) . toEqual ( {
362+ state : "test-state" ,
363+ code : null ,
364+ error : "access_denied" ,
365+ } ) ;
366+ } ) ;
367+
368+ it ( "does not store callback when state is missing" , async ( ) => {
369+ const { handleUri, secretsManager } = createTestContext ( ) ;
370+
371+ let callbackReceived = false ;
372+ secretsManager . onDidChangeOAuthCallback ( ( ) => {
373+ callbackReceived = true ;
374+ } ) ;
375+
376+ await handleUri ( createMockUri ( CALLBACK_PATH , "code=auth-code" ) ) ;
377+
378+ // Flush microtask queue to ensure any async callback would have fired
379+ await Promise . resolve ( ) ;
380+
381+ expect ( callbackReceived ) . toBe ( false ) ;
382+ } ) ;
383+ } ) ;
321384} ) ;
0 commit comments