@@ -62,30 +62,43 @@ describe("checkOAuthProviderScope", () => {
6262 expect ( expired . access ) . toBe ( "refreshed-codex" ) ;
6363 } ) ;
6464
65- test ( "codex: reports an expired staged token refresh failure as unavailable " , async ( ) => {
65+ test ( "codex: blocks a definitive staged refresh rejection " , async ( ) => {
6666 const expired = { ...codexTokens , expiresAt : 0 } ;
67- stubFetch ( ( ) => new Response ( "refresh rejected" , { status : 401 } ) ) ;
67+ stubFetch ( ( ) => new Response ( JSON . stringify ( { error : "invalid_grant" } ) , { status : 400 } ) ) ;
68+
69+ const result = await checkOAuthProviderScope ( "codex" , expired ) ;
70+
71+ expect ( result . status ) . toBe ( "blocked" ) ;
72+ if ( result . status === "blocked" ) {
73+ expect ( result . message ) . toMatch ( / e x p i r e d | r e v o k e d / i) ;
74+ }
75+ } ) ;
76+
77+ test ( "codex: reports a transient staged refresh failure as unavailable" , async ( ) => {
78+ const expired = { ...codexTokens , expiresAt : 0 } ;
79+ stubFetch ( ( ) => {
80+ throw new Error ( "network down" ) ;
81+ } ) ;
6882
6983 const result = await checkOAuthProviderScope ( "codex" , expired ) ;
7084
7185 expect ( result . status ) . toBe ( "unavailable" ) ;
7286 } ) ;
7387
74- test ( "codex: insufficient-scope on a definitive 403" , async ( ) => {
88+ test ( "codex: blocks a definitive 403 without surfacing the raw body " , async ( ) => {
7589 stubFetch ( ( ) => new Response ( "forbidden" , { status : 403 } ) ) ;
7690 const result = await checkOAuthProviderScope ( "codex" , codexTokens ) ;
77- expect ( result . status ) . toBe ( "insufficient-scope " ) ;
78- if ( result . status === "insufficient-scope " ) {
91+ expect ( result . status ) . toBe ( "blocked " ) ;
92+ if ( result . status === "blocked " ) {
7993 expect ( result . message ) . toMatch ( / r e c o n n e c t / i) ;
80- // Must never surface the raw response body.
8194 expect ( result . message ) . not . toContain ( "forbidden" ) ;
8295 }
8396 } ) ;
8497
85- test ( "codex: insufficient-scope on a definitive 401" , async ( ) => {
98+ test ( "codex: blocks a definitive 401" , async ( ) => {
8699 stubFetch ( ( ) => new Response ( "nope" , { status : 401 } ) ) ;
87100 const result = await checkOAuthProviderScope ( "codex" , codexTokens ) ;
88- expect ( result . status ) . toBe ( "insufficient-scope " ) ;
101+ expect ( result . status ) . toBe ( "blocked " ) ;
89102 } ) ;
90103
91104 test ( "codex: unavailable on a network failure, not blocked" , async ( ) => {
@@ -133,19 +146,33 @@ describe("checkOAuthProviderScope", () => {
133146 expect ( expired . access ) . toBe ( "refreshed-xai" ) ;
134147 } ) ;
135148
136- test ( "xai: reports an expired staged token refresh failure as unavailable " , async ( ) => {
149+ test ( "xai: blocks a definitive staged refresh rejection " , async ( ) => {
137150 const expired = { ...xaiTokens , expiresAt : 0 } ;
138- stubFetch ( ( ) => new Response ( "refresh rejected" , { status : 401 } ) ) ;
151+ stubFetch ( ( ) => new Response ( JSON . stringify ( { error : "revoked" } ) , { status : 401 } ) ) ;
152+
153+ const result = await checkOAuthProviderScope ( "xai" , expired ) ;
154+
155+ expect ( result . status ) . toBe ( "blocked" ) ;
156+ if ( result . status === "blocked" ) {
157+ expect ( result . message ) . toMatch ( / e x p i r e d | r e v o k e d / i) ;
158+ }
159+ } ) ;
160+
161+ test ( "xai: reports a transient staged refresh failure as unavailable" , async ( ) => {
162+ const expired = { ...xaiTokens , expiresAt : 0 } ;
163+ stubFetch ( ( ) => {
164+ throw new DOMException ( "The operation timed out." , "TimeoutError" ) ;
165+ } ) ;
139166
140167 const result = await checkOAuthProviderScope ( "xai" , expired ) ;
141168
142169 expect ( result . status ) . toBe ( "unavailable" ) ;
143170 } ) ;
144171
145- test ( "xai: insufficient-scope on a definitive 403" , async ( ) => {
172+ test ( "xai: blocks a definitive 403" , async ( ) => {
146173 stubFetch ( ( ) => new Response ( "forbidden" , { status : 403 } ) ) ;
147174 const result = await checkOAuthProviderScope ( "xai" , xaiTokens ) ;
148- expect ( result . status ) . toBe ( "insufficient-scope " ) ;
175+ expect ( result . status ) . toBe ( "blocked " ) ;
149176 } ) ;
150177
151178 test ( "xai: unavailable on a timeout-style abort" , async ( ) => {
0 commit comments