Skip to content

Commit ba91b90

Browse files
authored
fix: handle rejected promise in server tests (#4705)
* fix: handle rejected promise in server tests Problem: - We get: rejected promise not handled within 1 second: Error: AuthSSOServer: foo: foo rejected promise not handled within 1 second: Error: AuthSSOServer: invalid state rejected promise not handled within 1 second: Error: AuthSSOServer: missing code rejected promise not handled within 1 second: Error: AuthSSOServer: missing state Solution: - Catch and test the authorization promise
1 parent 6c3eb5e commit ba91b90

File tree

3 files changed

+30
-13
lines changed

3 files changed

+30
-13
lines changed

packages/core/src/auth/sso/server.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { getLogger } from '../../shared/logger'
88
import { ToolkitError } from '../../shared/errors'
99
import { Socket } from 'net'
1010
import globals from '../../shared/extensionGlobals'
11+
import { Result } from '../../shared/utilities/result'
1112

1213
export class MissingPortError extends ToolkitError {
1314
constructor() {
@@ -49,14 +50,14 @@ export class AuthSSOServer {
4950
private authenticationFlowTimeoutInMs = 600000
5051
private authenticationWarningTimeoutInMs = 60000
5152

52-
private readonly authenticationPromise: Promise<string>
53-
private deferred: { resolve: (result: string) => void; reject: (reason: any) => void } | undefined
53+
private readonly authenticationPromise: Promise<Result<string>>
54+
private deferred: { resolve: (result: Result<string>) => void } | undefined
5455
private server: http.Server
5556
private connections: Socket[]
5657

5758
constructor(private readonly state: string, private readonly vscodeUriPath: string) {
58-
this.authenticationPromise = new Promise<string>((resolve, reject) => {
59-
this.deferred = { resolve, reject }
59+
this.authenticationPromise = new Promise<Result<string>>(resolve => {
60+
this.deferred = { resolve }
6061
})
6162

6263
this.connections = []
@@ -174,7 +175,7 @@ export class AuthSSOServer {
174175
return
175176
}
176177

177-
this.deferred?.resolve(code)
178+
this.deferred?.resolve(Result.ok(code))
178179
res.setHeader('Content-Type', 'text/html')
179180
res.writeHead(200)
180181
res.end(`
@@ -194,13 +195,13 @@ export class AuthSSOServer {
194195
res.end(error.message)
195196

196197
// Send the response back to the editor
197-
this.deferred?.reject(error)
198+
this.deferred?.resolve(Result.err(error))
198199
}
199200

200-
public waitForAuthorization(): Promise<string> {
201+
public waitForAuthorization(): Promise<Result<string>> {
201202
return Promise.race([
202203
this.authenticationPromise,
203-
new Promise<string>((_, reject) => {
204+
new Promise<Result<string>>((_, reject) => {
204205
globals.clock.setTimeout(() => {
205206
reject(
206207
new ToolkitError('Timed-out waiting for browser login flow to complete', {

packages/core/src/auth/sso/ssoAccessTokenProvider.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,14 +427,17 @@ class AuthFlowAuthorization extends SsoAccessTokenProvider {
427427
}
428428

429429
const authorizationCode = await authServer.waitForAuthorization()
430+
if (authorizationCode.isErr()) {
431+
throw authorizationCode.err()
432+
}
430433

431434
const tokenRequest: OidcClientPKCE.CreateTokenRequest = {
432435
clientId: registration.clientId,
433436
clientSecret: registration.clientSecret,
434437
grantType: authorizationGrantType,
435438
redirectUri,
436439
codeVerifier,
437-
code: authorizationCode,
440+
code: authorizationCode.unwrap(),
438441
}
439442

440443
return this.oidc.createToken(tokenRequest)

packages/core/src/test/credentials/sso/server.test.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
} from '../../../auth/sso/server'
1414
import request, { RequestError } from '../../../common/request'
1515
import { URLSearchParams } from 'url'
16+
import { ToolkitError } from '../../../shared/errors'
1617

1718
describe('AuthSSOServer', function () {
1819
const code = 'zfhgaiufgsbdfigsdfg'
@@ -39,13 +40,25 @@ describe('AuthSSOServer', function () {
3940

4041
async function assertRequestError(params: Record<string, string>, expectedErrorMsg: string) {
4142
const url = createURL(server.redirectUri, params)
43+
const authorizationPromise = server.waitForAuthorization()
4244
try {
4345
const response = await request.fetch('GET', url).response
4446
assert.fail(`Expected error but found ${response.body}`)
4547
} catch (err: unknown) {
46-
if (err instanceof RequestError) {
47-
assert.strictEqual(err.code, 400)
48-
assert.deepStrictEqual(err.body, expectedErrorMsg)
48+
if (!(err instanceof RequestError)) {
49+
assert.fail('Unknown error')
50+
}
51+
52+
const e = err as RequestError
53+
assert.strictEqual(e.code, 400)
54+
assert.deepStrictEqual(e.body, expectedErrorMsg)
55+
}
56+
57+
try {
58+
await authorizationPromise
59+
} catch (err: unknown) {
60+
if (err instanceof ToolkitError) {
61+
assert.deepStrictEqual(err.message, expectedErrorMsg)
4962
return
5063
}
5164
assert.fail('Unknown error')
@@ -103,7 +116,7 @@ describe('AuthSSOServer', function () {
103116
assert.deepStrictEqual(response.status, 200)
104117

105118
const token = await server.waitForAuthorization()
106-
assert.deepStrictEqual(code, token)
119+
assert.deepStrictEqual(code, token.unwrap())
107120
})
108121

109122
it('address is bound to localhost', function () {

0 commit comments

Comments
 (0)