Skip to content

Commit 894774f

Browse files
committed
fix(test): add unit test for auth activation initialize method
1 parent 2d7fc6f commit 894774f

File tree

2 files changed

+293
-1
lines changed

2 files changed

+293
-1
lines changed

packages/core/src/auth/activation.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { isAmazonQ, isSageMaker } from '../shared/extensionUtilities'
1212
import { getLogger } from '../shared/logger/logger'
1313
import { getErrorMsg } from '../shared/errors'
1414

15-
interface SagemakerCookie {
15+
export interface SagemakerCookie {
1616
authMode?: 'Sso' | 'Iam'
1717
}
1818

Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
1+
/*!
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import * as vscode from 'vscode'
7+
import * as sinon from 'sinon'
8+
import assert from 'assert'
9+
import { initialize, SagemakerCookie } from '../../auth/activation'
10+
import { LoginManager } from '../../auth/deprecated/loginManager'
11+
import * as extensionUtilities from '../../shared/extensionUtilities'
12+
import * as authUtils from '../../auth/utils'
13+
import * as errors from '../../shared/errors'
14+
import * as credentials from '../../auth/providers/credentials'
15+
16+
describe('auth/activation', function () {
17+
let sandbox: sinon.SinonSandbox
18+
let mockLoginManager: LoginManager
19+
let executeCommandStub: sinon.SinonStub
20+
let isAmazonQStub: sinon.SinonStub
21+
let isSageMakerStub: sinon.SinonStub
22+
let initializeCredentialsProviderManagerStub: sinon.SinonStub
23+
let getErrorMsgStub: sinon.SinonStub
24+
let fromStringStub: sinon.SinonStub
25+
let mockLogger: any
26+
let onDidChangeActiveConnectionEvent: sinon.SinonStub
27+
28+
beforeEach(function () {
29+
sandbox = sinon.createSandbox()
30+
31+
// Create mocks
32+
mockLoginManager = {
33+
login: sandbox.stub(),
34+
logout: sandbox.stub(),
35+
} as any
36+
37+
mockLogger = {
38+
warn: sandbox.stub(),
39+
info: sandbox.stub(),
40+
error: sandbox.stub(),
41+
debug: sandbox.stub(),
42+
}
43+
44+
onDidChangeActiveConnectionEvent = sandbox.stub()
45+
46+
// Stub external dependencies
47+
executeCommandStub = sandbox.stub(vscode.commands, 'executeCommand')
48+
isAmazonQStub = sandbox.stub(extensionUtilities, 'isAmazonQ')
49+
isSageMakerStub = sandbox.stub(extensionUtilities, 'isSageMaker')
50+
initializeCredentialsProviderManagerStub = sandbox.stub(authUtils, 'initializeCredentialsProviderManager')
51+
getErrorMsgStub = sandbox.stub(errors, 'getErrorMsg')
52+
fromStringStub = sandbox.stub(credentials, 'fromString')
53+
})
54+
55+
afterEach(function () {
56+
sandbox.restore()
57+
})
58+
59+
describe('initialize', function () {
60+
it('should not execute sagemaker.parseCookies when not in AmazonQ and SageMaker environment', async function () {
61+
isAmazonQStub.returns(false)
62+
isSageMakerStub.returns(false)
63+
64+
await initialize(mockLoginManager)
65+
66+
assert.ok(!executeCommandStub.called)
67+
assert.ok(!initializeCredentialsProviderManagerStub.called)
68+
})
69+
70+
it('should not execute sagemaker.parseCookies when only in AmazonQ environment', async function () {
71+
isAmazonQStub.returns(true)
72+
isSageMakerStub.returns(false)
73+
74+
await initialize(mockLoginManager)
75+
76+
assert.ok(!executeCommandStub.called)
77+
assert.ok(!initializeCredentialsProviderManagerStub.called)
78+
})
79+
80+
it('should not execute sagemaker.parseCookies when only in SageMaker environment', async function () {
81+
isAmazonQStub.returns(false)
82+
isSageMakerStub.returns(true)
83+
84+
await initialize(mockLoginManager)
85+
86+
assert.ok(!executeCommandStub.called)
87+
assert.ok(!initializeCredentialsProviderManagerStub.called)
88+
})
89+
90+
it('should execute sagemaker.parseCookies when in both AmazonQ and SageMaker environment', async function () {
91+
isAmazonQStub.returns(true)
92+
isSageMakerStub.returns(true)
93+
executeCommandStub.withArgs('sagemaker.parseCookies').resolves({ authMode: 'Sso' } as SagemakerCookie)
94+
95+
await initialize(mockLoginManager)
96+
97+
assert.ok(executeCommandStub.calledOnceWith('sagemaker.parseCookies'))
98+
assert.ok(!initializeCredentialsProviderManagerStub.called)
99+
})
100+
101+
it('should initialize credentials provider manager when authMode is not Sso', async function () {
102+
isAmazonQStub.returns(true)
103+
isSageMakerStub.returns(true)
104+
executeCommandStub.withArgs('sagemaker.parseCookies').resolves({ authMode: 'Iam' } as SagemakerCookie)
105+
106+
await initialize(mockLoginManager)
107+
108+
assert.ok(executeCommandStub.calledOnceWith('sagemaker.parseCookies'))
109+
assert.ok(initializeCredentialsProviderManagerStub.calledOnce)
110+
})
111+
112+
it('should initialize credentials provider manager when authMode is undefined', async function () {
113+
isAmazonQStub.returns(true)
114+
isSageMakerStub.returns(true)
115+
executeCommandStub.withArgs('sagemaker.parseCookies').resolves({} as SagemakerCookie)
116+
117+
await initialize(mockLoginManager)
118+
119+
assert.ok(executeCommandStub.calledOnceWith('sagemaker.parseCookies'))
120+
assert.ok(initializeCredentialsProviderManagerStub.calledOnce)
121+
})
122+
123+
it('should warn and not throw when sagemaker.parseCookies command is not found', async function () {
124+
isAmazonQStub.returns(true)
125+
isSageMakerStub.returns(true)
126+
const error = new Error("command 'sagemaker.parseCookies' not found")
127+
executeCommandStub.withArgs('sagemaker.parseCookies').rejects(error)
128+
getErrorMsgStub.returns("command 'sagemaker.parseCookies' not found")
129+
130+
await initialize(mockLoginManager)
131+
132+
assert.ok(executeCommandStub.calledOnceWith('sagemaker.parseCookies'))
133+
assert.ok(getErrorMsgStub.calledOnceWith(error))
134+
assert.ok(
135+
mockLogger.warn.calledOnceWith(
136+
'yueny testing Failed to execute command "sagemaker.parseCookies": Error: command \'sagemaker.parseCookies\' not found'
137+
)
138+
)
139+
assert.ok(!initializeCredentialsProviderManagerStub.called)
140+
})
141+
142+
it('should throw when sagemaker.parseCookies fails with non-command-not-found error', async function () {
143+
isAmazonQStub.returns(true)
144+
isSageMakerStub.returns(true)
145+
const error = new Error('Some other error')
146+
executeCommandStub.withArgs('sagemaker.parseCookies').rejects(error)
147+
getErrorMsgStub.returns('Some other error')
148+
149+
await assert.rejects(initialize(mockLoginManager), /Some other error/)
150+
151+
assert.ok(executeCommandStub.calledOnceWith('sagemaker.parseCookies'))
152+
assert.ok(getErrorMsgStub.calledOnceWith(error))
153+
assert.ok(!mockLogger.warn.called)
154+
assert.ok(!initializeCredentialsProviderManagerStub.called)
155+
})
156+
157+
it('should set up connection change listener correctly', async function () {
158+
isAmazonQStub.returns(false)
159+
isSageMakerStub.returns(false)
160+
let eventCallback: (conn: any) => void = () => {}
161+
162+
onDidChangeActiveConnectionEvent.callsFake((callback: any) => {
163+
eventCallback = callback
164+
return { dispose: sandbox.stub() }
165+
})
166+
167+
await initialize(mockLoginManager)
168+
169+
assert.ok(onDidChangeActiveConnectionEvent.calledOnce)
170+
171+
// Test the event callback is set up
172+
assert.strictEqual(typeof eventCallback, 'function')
173+
})
174+
175+
describe('connection change event handler', function () {
176+
let eventCallback: (conn: any) => Promise<void>
177+
178+
beforeEach(async function () {
179+
isAmazonQStub.returns(false)
180+
isSageMakerStub.returns(false)
181+
182+
onDidChangeActiveConnectionEvent.callsFake((callback: any) => {
183+
eventCallback = callback
184+
return { dispose: sandbox.stub() }
185+
})
186+
187+
await initialize(mockLoginManager)
188+
})
189+
190+
it('should call login when connection is valid IAM', async function () {
191+
const mockConnection = {
192+
type: 'iam',
193+
state: 'valid',
194+
id: 'test-connection-id',
195+
}
196+
const mockProviderId = { credentialSource: 'test', credentialTypeId: 'test' }
197+
fromStringStub.withArgs('test-connection-id').returns(mockProviderId)
198+
;(mockLoginManager.login as sinon.SinonStub).resolves(true)
199+
200+
await eventCallback(mockConnection)
201+
202+
assert.ok(fromStringStub.calledOnceWith('test-connection-id'))
203+
assert.ok(
204+
(mockLoginManager.login as sinon.SinonStub).calledOnceWith({
205+
passive: true,
206+
providerId: mockProviderId,
207+
})
208+
)
209+
assert.ok(!(mockLoginManager.logout as sinon.SinonStub).called)
210+
})
211+
212+
it('should call logout when connection is not IAM', async function () {
213+
const mockConnection = {
214+
type: 'sso',
215+
state: 'valid',
216+
id: 'test-connection-id',
217+
}
218+
;(mockLoginManager.logout as sinon.SinonStub).resolves()
219+
220+
await eventCallback(mockConnection)
221+
222+
assert.ok((mockLoginManager.logout as sinon.SinonStub).calledOnce)
223+
assert.ok(!(mockLoginManager.login as sinon.SinonStub).called)
224+
assert.ok(!fromStringStub.called)
225+
})
226+
227+
it('should call logout when connection state is not valid', async function () {
228+
const mockConnection = {
229+
type: 'iam',
230+
state: 'invalid',
231+
id: 'test-connection-id',
232+
}
233+
;(mockLoginManager.logout as sinon.SinonStub).resolves()
234+
235+
await eventCallback(mockConnection)
236+
237+
assert.ok((mockLoginManager.logout as sinon.SinonStub).calledOnce)
238+
assert.ok(!(mockLoginManager.login as sinon.SinonStub).called)
239+
assert.ok(!fromStringStub.called)
240+
})
241+
242+
it('should call logout when connection is undefined', async function () {
243+
;(mockLoginManager.logout as sinon.SinonStub).resolves()
244+
245+
await eventCallback(undefined)
246+
247+
assert.ok((mockLoginManager.logout as sinon.SinonStub).calledOnce)
248+
assert.ok(!(mockLoginManager.login as sinon.SinonStub).called)
249+
assert.ok(!fromStringStub.called)
250+
})
251+
})
252+
253+
it('should handle the complete flow for AmazonQ + SageMaker with Iam authMode', async function () {
254+
isAmazonQStub.returns(true)
255+
isSageMakerStub.returns(true)
256+
executeCommandStub.withArgs('sagemaker.parseCookies').resolves({ authMode: 'Iam' } as SagemakerCookie)
257+
258+
let eventCallback: (conn: any) => Promise<void> = async () => {}
259+
onDidChangeActiveConnectionEvent.callsFake((callback: any) => {
260+
eventCallback = callback
261+
return { dispose: sandbox.stub() }
262+
})
263+
264+
const mockConnection = {
265+
type: 'iam',
266+
state: 'valid',
267+
id: 'test-connection-id',
268+
}
269+
const mockProviderId = { credentialSource: 'test', credentialTypeId: 'test' }
270+
fromStringStub.withArgs('test-connection-id').returns(mockProviderId)
271+
;(mockLoginManager.login as sinon.SinonStub).resolves(true)
272+
273+
await initialize(mockLoginManager)
274+
275+
// Verify SageMaker initialization
276+
assert.ok(executeCommandStub.calledOnceWith('sagemaker.parseCookies'))
277+
assert.ok(initializeCredentialsProviderManagerStub.calledOnce)
278+
279+
// Verify event listener is set up
280+
assert.ok(onDidChangeActiveConnectionEvent.calledOnce)
281+
282+
// Test event handler works correctly
283+
await eventCallback(mockConnection)
284+
assert.ok(
285+
(mockLoginManager.login as sinon.SinonStub).calledOnceWith({
286+
passive: true,
287+
providerId: mockProviderId,
288+
})
289+
)
290+
})
291+
})
292+
})

0 commit comments

Comments
 (0)