From def870c4864ab6f3c66b5dbac10fea6b7892f823 Mon Sep 17 00:00:00 2001 From: Volodymyr Kolesnykov Date: Fri, 9 Oct 2026 15:16:42 +0300 Subject: [PATCH] test: stub browser opening in rechallenge tests --- internal/gql/rechallenge_test.go | 10 ++++++++++ internal/rechallenge/flow_noninteractive_test.go | 4 ++++ internal/rechallenge/flow_test.go | 13 ++++++++++--- internal/rechallenge/redact_test.go | 1 + 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/internal/gql/rechallenge_test.go b/internal/gql/rechallenge_test.go index 2e87a70fa..d45657bc4 100644 --- a/internal/gql/rechallenge_test.go +++ b/internal/gql/rechallenge_test.go @@ -95,6 +95,7 @@ func TestRechallengePreflightAttachesCachedToken(t *testing.T) { func TestRechallengeFullFlowOnElevatedError(t *testing.T) { mutationHits := int32(0) + var openedURLs []string var headerAfterRetry string parker := http.NewServeMux() @@ -125,6 +126,7 @@ func TestRechallengeFullFlowOnElevatedError(t *testing.T) { runner := &rechallenge.Runner{ Client: &rechallenge.Client{APIHost: parkerSrv.URL, HTTP: parkerSrv.Client()}, TokenCache: cache, + OpenURL: func(url string) { openedURLs = append(openedURLs, url) }, Sleep: func(_ context.Context, _ time.Duration) error { return nil }, } c := NewClient(Config{ @@ -154,6 +156,9 @@ func TestRechallengeFullFlowOnElevatedError(t *testing.T) { if headerAfterRetry != "elev" { t.Errorf("retry header = %q, want elev", headerAfterRetry) } + if len(openedURLs) != 1 || openedURLs[0] != "https://example/v" { + t.Errorf("opened URLs = %q, want one verification URL", openedURLs) + } } func TestRechallengeSurfacesOriginalErrorOnFlowFailure(t *testing.T) { @@ -172,6 +177,7 @@ func TestRechallengeSurfacesOriginalErrorOnFlowFailure(t *testing.T) { runner := &rechallenge.Runner{ Client: &rechallenge.Client{APIHost: parker.URL, HTTP: parker.Client()}, TokenCache: cache, + OpenURL: func(string) { t.Error("failed session creation must not open a browser") }, Sleep: func(_ context.Context, _ time.Duration) error { return nil }, } c := NewClient(Config{ @@ -228,6 +234,7 @@ func TestRechallengeUsesConfigInteractivityProvider(t *testing.T) { runner := &rechallenge.Runner{ Client: &rechallenge.Client{APIHost: parkerSrv.URL, HTTP: parkerSrv.Client()}, TokenCache: cache, + OpenURL: func(string) {}, Sleep: func(_ context.Context, _ time.Duration) error { return nil }, } @@ -302,6 +309,7 @@ func TestRechallengeSurfacesStepUpFailureReason(t *testing.T) { Runner: &rechallenge.Runner{ Client: &rechallenge.Client{APIHost: parker.URL, HTTP: parker.Client()}, TokenCache: cache, + OpenURL: func(string) { t.Error("failed session creation must not open a browser") }, Sleep: func(context.Context, time.Duration) error { return nil }, }, Interactive: func() bool { return true }, @@ -356,6 +364,7 @@ func TestRechallengeFailureReasonCannotLeakToken(t *testing.T) { APIHost: parker.URL, HTTP: parker.Client(), BearerToken: bearer, }, TokenCache: cache, + OpenURL: func(string) { t.Error("failed session creation must not open a browser") }, Sleep: func(context.Context, time.Duration) error { return nil }, }, Interactive: func() bool { return true }, @@ -404,6 +413,7 @@ func TestRechallengeNonInteractiveReturnsPromptly(t *testing.T) { Runner: &rechallenge.Runner{ Client: &rechallenge.Client{APIHost: parker.URL, HTTP: parker.Client()}, TokenCache: cache, + OpenURL: func(string) { t.Error("non-interactive flow must not open a browser") }, Sleep: func(ctx context.Context, _ time.Duration) error { select { case <-ctx.Done(): diff --git a/internal/rechallenge/flow_noninteractive_test.go b/internal/rechallenge/flow_noninteractive_test.go index 5494ba13f..603dba935 100644 --- a/internal/rechallenge/flow_noninteractive_test.go +++ b/internal/rechallenge/flow_noninteractive_test.go @@ -76,6 +76,7 @@ func TestFlowNonInteractiveFailsFastInsteadOfPolling(t *testing.T) { Tracker: tr, TokenCache: newTestCache(), Stdout: io.Discard, + OpenURL: func(string) { t.Error("non-interactive flow must not open a browser") }, Sleep: func(ctx context.Context, _ time.Duration) error { select { case <-ctx.Done(): @@ -147,6 +148,7 @@ func TestFlowNonInteractiveWaitOptInStillPolls(t *testing.T) { Tracker: &fakeTracker{}, TokenCache: newTestCache(), Stdout: &out, + OpenURL: func(string) { t.Error("non-interactive wait must not open a browser") }, Sleep: func(context.Context, time.Duration) error { return nil }, } tok, err := r.Run(context.Background(), RunInput{ @@ -190,6 +192,7 @@ func TestFlowRejectsUnusableDeadline(t *testing.T) { Tracker: &fakeTracker{}, TokenCache: newTestCache(), Stdout: io.Discard, + OpenURL: func(string) {}, Sleep: func(ctx context.Context, _ time.Duration) error { select { case <-ctx.Done(): @@ -256,6 +259,7 @@ func TestFlowFloorsServerPollInterval(t *testing.T) { Tracker: &fakeTracker{}, TokenCache: newTestCache(), Stdout: io.Discard, + OpenURL: func(string) {}, Sleep: func(_ context.Context, d time.Duration) error { mu.Lock() slept = append(slept, d) diff --git a/internal/rechallenge/flow_test.go b/internal/rechallenge/flow_test.go index f0701bf31..7f446ee72 100644 --- a/internal/rechallenge/flow_test.go +++ b/internal/rechallenge/flow_test.go @@ -29,7 +29,7 @@ func (f *fakeTracker) Track(name string, _ map[string]any) { func TestFlowUnsupportedVersion(t *testing.T) { cache := newTestCache() tr := &fakeTracker{} - r := &Runner{Tracker: tr, TokenCache: cache} + r := &Runner{Tracker: tr, TokenCache: cache, OpenURL: func(string) { t.Error("unsupported version must not open a browser") }} _, err := r.Run(context.Background(), RunInput{ RequestedOperation: "doThing", Extension: Extension{ @@ -75,8 +75,13 @@ func TestFlowHappyPathVerified(t *testing.T) { Tracker: tr, TokenCache: cache, Stdout: &out, - OpenURL: func(string) { atomic.AddInt32(&openCalled, 1) }, - Sleep: func(_ context.Context, _ time.Duration) error { return nil }, + OpenURL: func(url string) { + atomic.AddInt32(&openCalled, 1) + if url != "https://example/v/c1" { + t.Errorf("OpenURL = %q, want verification URL", url) + } + }, + Sleep: func(_ context.Context, _ time.Duration) error { return nil }, } var diagnostics bytes.Buffer @@ -146,6 +151,7 @@ func TestFlowTerminalCancelled(t *testing.T) { Client: &Client{APIHost: srv.URL, HTTP: srv.Client()}, Tracker: &fakeTracker{}, TokenCache: newTestCache(), + OpenURL: func(string) {}, Sleep: func(_ context.Context, _ time.Duration) error { return nil }, } _, err := r.Run(context.Background(), RunInput{ @@ -184,6 +190,7 @@ func TestFlowAbortedByContext(t *testing.T) { Client: &Client{APIHost: srv.URL, HTTP: srv.Client()}, Tracker: &fakeTracker{}, TokenCache: newTestCache(), + OpenURL: func(string) {}, Sleep: func(ctx context.Context, _ time.Duration) error { <-ctx.Done() return ctx.Err() diff --git a/internal/rechallenge/redact_test.go b/internal/rechallenge/redact_test.go index 576e6667a..09f60d03d 100644 --- a/internal/rechallenge/redact_test.go +++ b/internal/rechallenge/redact_test.go @@ -123,6 +123,7 @@ func TestFlowRedactsStatusReason(t *testing.T) { Tracker: &fakeTracker{}, TokenCache: newTestCache(), Stdout: new(strings.Builder), + OpenURL: func(string) {}, Sleep: func(context.Context, time.Duration) error { return nil }, } _, err := r.Run(context.Background(), RunInput{