@@ -63,7 +63,7 @@ it.live("orgsByAccount groups orgs per account", () =>
6363 url : "https://one.example.com" ,
6464 accessToken : AccessToken . make ( "at_1" ) ,
6565 refreshToken : RefreshToken . make ( "rt_1" ) ,
66- expiry : Date . now ( ) + 60_000 ,
66+ expiry : Date . now ( ) + 10 * 60_000 ,
6767 orgID : Option . none ( ) ,
6868 } ) ,
6969 )
@@ -75,7 +75,7 @@ it.live("orgsByAccount groups orgs per account", () =>
7575 url : "https://two.example.com" ,
7676 accessToken : AccessToken . make ( "at_2" ) ,
7777 refreshToken : RefreshToken . make ( "rt_2" ) ,
78- expiry : Date . now ( ) + 60_000 ,
78+ expiry : Date . now ( ) + 10 * 60_000 ,
7979 orgID : Option . none ( ) ,
8080 } ) ,
8181 )
@@ -148,6 +148,50 @@ it.live("token refresh persists the new token", () =>
148148 } ) ,
149149)
150150
151+ it . live ( "token refreshes before expiry when inside the eager refresh window" , ( ) =>
152+ Effect . gen ( function * ( ) {
153+ const id = AccountID . make ( "user-1" )
154+
155+ yield * AccountRepo . use ( ( r ) =>
156+ r . persistAccount ( {
157+ id,
158+ email : "user@example.com" ,
159+ url : "https://one.example.com" ,
160+ accessToken : AccessToken . make ( "at_old" ) ,
161+ refreshToken : RefreshToken . make ( "rt_old" ) ,
162+ expiry : Date . now ( ) + 60_000 ,
163+ orgID : Option . none ( ) ,
164+ } ) ,
165+ )
166+
167+ let refreshCalls = 0
168+ const client = HttpClient . make ( ( req ) =>
169+ Effect . promise ( async ( ) => {
170+ if ( req . url === "https://one.example.com/auth/device/token" ) {
171+ refreshCalls += 1
172+ return json ( req , {
173+ access_token : "at_new" ,
174+ refresh_token : "rt_new" ,
175+ expires_in : 60 ,
176+ } )
177+ }
178+
179+ return json ( req , { } , 404 )
180+ } ) ,
181+ )
182+
183+ const token = yield * Account . Service . use ( ( s ) => s . token ( id ) ) . pipe ( Effect . provide ( live ( client ) ) )
184+
185+ expect ( String ( Option . getOrThrow ( token ) ) ) . toBe ( "at_new" )
186+ expect ( refreshCalls ) . toBe ( 1 )
187+
188+ const row = yield * AccountRepo . use ( ( r ) => r . getRow ( id ) )
189+ const value = Option . getOrThrow ( row )
190+ expect ( value . access_token ) . toBe ( AccessToken . make ( "at_new" ) )
191+ expect ( value . refresh_token ) . toBe ( RefreshToken . make ( "rt_new" ) )
192+ } ) ,
193+ )
194+
151195it . live ( "concurrent config and token requests coalesce token refresh" , ( ) =>
152196 Effect . gen ( function * ( ) {
153197 const id = AccountID . make ( "user-1" )
@@ -223,7 +267,7 @@ it.live("config sends the selected org header", () =>
223267 url : "https://one.example.com" ,
224268 accessToken : AccessToken . make ( "at_1" ) ,
225269 refreshToken : RefreshToken . make ( "rt_1" ) ,
226- expiry : Date . now ( ) + 60_000 ,
270+ expiry : Date . now ( ) + 10 * 60_000 ,
227271 orgID : Option . none ( ) ,
228272 } ) ,
229273 )
0 commit comments