Skip to content

Commit 2ba6210

Browse files
committed
Fix unit tests
1 parent 834ceeb commit 2ba6210

File tree

17 files changed

+282
-283
lines changed

17 files changed

+282
-283
lines changed

docs/lsp.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ sequenceDiagram
4848
3. Enable the lsp experiment:
4949
```
5050
"aws.experiments": {
51-
"amazonqLSP": true,
5251
"amazonqLSPInline": true, // optional: enables inline completion from flare
5352
"amazonqLSPChat": true // optional: enables chat from flare
5453
}

packages/amazonq/src/extension.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,12 @@ export async function activateAmazonQCommon(context: vscode.ExtensionContext, is
115115

116116
await initializeAuth(globals.loginManager)
117117

118-
if (Experiments.instance.get('amazonqLSP', false)) {
119-
await activateAmazonqLsp(context)
120-
}
118+
await activateAmazonqLsp(context)
121119

122120
const extContext = {
123121
extensionContext: context,
124122
}
123+
125124
// This contains every lsp agnostic things (auth, security scan, code scan)
126125
await activateCodeWhisperer(extContext as ExtContext)
127126

@@ -172,7 +171,7 @@ export async function activateAmazonQCommon(context: vscode.ExtensionContext, is
172171

173172
context.subscriptions.push(
174173
Experiments.instance.onDidChange(async (event) => {
175-
if (event.key === 'amazonqLSP' || event.key === 'amazonqChatLSP' || event.key === 'amazonqLSPInline') {
174+
if (event.key === 'amazonqChatLSP' || event.key === 'amazonqLSPInline') {
176175
await vscode.window
177176
.showInformationMessage(
178177
'Amazon Q LSP setting has changed. Reload VS Code for the changes to take effect.',

packages/amazonq/src/extensionNode.ts

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,24 @@ import * as vscode from 'vscode'
77
import { activateAmazonQCommon, amazonQContextPrefix, deactivateCommon } from './extension'
88
import { DefaultAmazonQAppInitContext } from 'aws-core-vscode/amazonq'
99
import { activate as activateQGumby } from 'aws-core-vscode/amazonqGumby'
10-
import { ExtContext, globals, CrashMonitoring, Experiments } from 'aws-core-vscode/shared'
10+
import {
11+
ExtContext,
12+
globals,
13+
CrashMonitoring /* , getLogger, isNetworkError, isSageMaker */,
14+
} from 'aws-core-vscode/shared'
1115
import { filetypes, SchemaService } from 'aws-core-vscode/sharedNode'
1216
import { updateDevMode } from 'aws-core-vscode/dev'
1317
import { CommonAuthViewProvider } from 'aws-core-vscode/login'
1418
import { isExtensionActive, VSCODE_EXTENSION_ID } from 'aws-core-vscode/utils'
1519
import { registerSubmitFeedback } from 'aws-core-vscode/feedback'
1620
import { DevOptions } from 'aws-core-vscode/dev'
17-
import { Auth } from 'aws-core-vscode/auth'
21+
import { Auth /* , AuthUtils, getTelemetryMetadataForConn, isAnySsoConnection*/ } from 'aws-core-vscode/auth'
1822
import api from './api'
1923
import { activate as activateCWChat } from './app/chat/activation'
20-
import { activate as activateInlineChat } from './inlineChat/activation'
2124
import { beta } from 'aws-core-vscode/dev'
22-
import { NotificationsController } from 'aws-core-vscode/notifications'
25+
import { /* activate as activateNotifications, */ NotificationsController } from 'aws-core-vscode/notifications'
26+
// import { AuthState, AuthUtil } from 'aws-core-vscode/codewhisperer'
27+
// import { telemetry, AuthUserState } from 'aws-core-vscode/telemetry'
2328

2429
export async function activate(context: vscode.ExtensionContext) {
2530
// IMPORTANT: No other code should be added to this function. Place it in one of the following 2 functions where appropriate.
@@ -42,11 +47,8 @@ async function activateAmazonQNode(context: vscode.ExtensionContext) {
4247
extensionContext: context,
4348
}
4449

45-
if (!Experiments.instance.get('amazonqChatLSP', false)) {
46-
await activateCWChat(context)
47-
await activateQGumby(extContext as ExtContext)
48-
}
49-
activateInlineChat(context)
50+
await activateCWChat(context)
51+
await activateQGumby(extContext as ExtContext)
5052

5153
const authProvider = new CommonAuthViewProvider(
5254
context,
@@ -68,9 +70,7 @@ async function activateAmazonQNode(context: vscode.ExtensionContext) {
6870
await setupDevMode(context)
6971
await beta.activate(context)
7072

71-
// TODO: @opieter add telemetry
72-
73-
// TODO: Should probably emit for web as well.
73+
// TODO: @opieter Fix telemetry
7474
// Will the web metric look the same?
7575
// telemetry.auth_userState.emit({
7676
// passive: true,
@@ -87,19 +87,21 @@ async function activateAmazonQNode(context: vscode.ExtensionContext) {
8787
// try {
8888
// // May call connection validate functions that try to refresh the token.
8989
// // This could result in network errors.
90-
// authState = AuthUtil.instance.getAuthState()
90+
// authState = (await AuthUtil.instance._getChatAuthState(false)).codewhispererChat
9191
// } catch (err) {
9292
// if (
9393
// isNetworkError(err) &&
94-
// AuthUtil.instance.isConnected()
94+
// AuthUtil.instance.conn &&
95+
// AuthUtil.instance.auth.getConnectionState(AuthUtil.instance.conn) === 'valid'
9596
// ) {
9697
// authState = 'connectedWithNetworkError'
9798
// } else {
9899
// throw err
99100
// }
100101
// }
101-
// if (AuthUtil.instance.isConnected() && !(AuthUtil.instance.isSsoSession() || isSageMaker())) {
102-
// getLogger().error('Current Amazon Q connection is not SSO')
102+
// const currConn = AuthUtil.instance.conn
103+
// if (currConn !== undefined && !(isAnySsoConnection(currConn) || isSageMaker())) {
104+
// getLogger().error(`Current Amazon Q connection is not SSO, type is: %s`, currConn?.type)
103105
// }
104106

105107
// return {

packages/amazonq/src/lsp/activation.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,20 @@
44
*/
55

66
import vscode from 'vscode'
7-
import { startLanguageServer } from './client'
7+
import { clientId, encryptionKey, startLanguageServer } from './client'
88
import { AmazonQLspInstaller } from './lspInstaller'
99
import { lspSetupStage, ToolkitError } from 'aws-core-vscode/shared'
10+
import { AuthUtil } from 'aws-core-vscode/codewhisperer'
11+
import { auth2 } from 'aws-core-vscode/auth'
1012

1113
export async function activate(ctx: vscode.ExtensionContext) {
1214
try {
13-
await lspSetupStage('all', async () => {
15+
const client = await lspSetupStage('all', async () => {
1416
const installResult = await new AmazonQLspInstaller().resolve()
1517
return await lspSetupStage('launch', () => startLanguageServer(ctx, installResult.resourcePaths))
1618
})
19+
AuthUtil.create(new auth2.LanguageClientAuth(client, clientId, encryptionKey))
20+
await AuthUtil.instance.restore()
1721
} catch (err) {
1822
const e = err as ToolkitError
1923
void vscode.window.showInformationMessage(`Unable to launch amazonq language server: ${e.message}`)

packages/amazonq/src/lsp/client.ts

Lines changed: 73 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export const encryptionKey = crypto.randomBytes(32)
4545
export async function startLanguageServer(
4646
extensionContext: vscode.ExtensionContext,
4747
resourcePaths: AmazonQResourcePaths
48-
) {
48+
): Promise<LanguageClient> {
4949
const toDispose = extensionContext.subscriptions
5050

5151
const serverModule = resourcePaths.lsp
@@ -109,87 +109,83 @@ export async function startLanguageServer(
109109
const disposable = client.start()
110110
toDispose.push(disposable)
111111

112-
return client.onReady().then(async () => {
113-
// Request handler for when the server wants to know about the clients auth connnection. Must be registered before the initial auth init call
114-
client.onRequest<ConnectionMetadata, Error>(auth2.notificationTypes.getConnectionMetadata.method, () => {
115-
return {
116-
sso: {
117-
startUrl: AuthUtil.instance.connection?.startUrl,
118-
},
119-
}
120-
})
121-
122-
client.onRequest<ShowDocumentResult, Error>(ShowDocumentRequest.method, async (params: ShowDocumentParams) => {
123-
try {
124-
return { success: await openUrl(vscode.Uri.parse(params.uri), lspName) }
125-
} catch (err: any) {
126-
getLogger().error(`Failed to open document for LSP: ${lspName}, error: %s`, err)
127-
return { success: false }
112+
await client.onReady()
113+
114+
// Request handler for when the server wants to know about the clients auth connnection. Must be registered before the initial auth init call
115+
client.onRequest<ConnectionMetadata, Error>(auth2.notificationTypes.getConnectionMetadata.method, () => {
116+
return {
117+
sso: {
118+
startUrl: AuthUtil.instance.connection?.startUrl,
119+
},
120+
}
121+
})
122+
123+
client.onRequest<ShowDocumentResult, Error>(ShowDocumentRequest.method, async (params: ShowDocumentParams) => {
124+
try {
125+
return { success: await openUrl(vscode.Uri.parse(params.uri), lspName) }
126+
} catch (err: any) {
127+
getLogger().error(`Failed to open document for LSP: ${lspName}, error: %s`, err)
128+
return { success: false }
129+
}
130+
})
131+
132+
client.onRequest<MessageActionItem | null, Error>(
133+
ShowMessageRequest.method,
134+
async (params: ShowMessageRequestParams) => {
135+
const actions = params.actions?.map((a) => a.title) ?? []
136+
const response = await vscode.window.showInformationMessage(params.message, { modal: true }, ...actions)
137+
return params.actions?.find((a) => a.title === response) ?? (undefined as unknown as null)
138+
}
139+
)
140+
141+
let promise: Promise<void> | undefined
142+
let resolver: () => void = () => {}
143+
client.onProgress(GetSsoTokenProgressType, GetSsoTokenProgressToken, async (partialResult: GetSsoTokenProgress) => {
144+
const decryptedKey = await jose.compactDecrypt(partialResult as unknown as string, encryptionKey)
145+
const val: GetSsoTokenProgress = JSON.parse(decryptedKey.plaintext.toString())
146+
147+
if (val.state === 'InProgress') {
148+
if (promise) {
149+
resolver()
128150
}
129-
})
130-
131-
client.onRequest<MessageActionItem | null, Error>(
132-
ShowMessageRequest.method,
133-
async (params: ShowMessageRequestParams) => {
134-
const actions = params.actions?.map((a) => a.title) ?? []
135-
const response = await vscode.window.showInformationMessage(params.message, { modal: true }, ...actions)
136-
return params.actions?.find((a) => a.title === response) ?? (undefined as unknown as null)
151+
promise = new Promise<void>((resolve) => {
152+
resolver = resolve
153+
})
154+
} else {
155+
resolver()
156+
promise = undefined
157+
return
158+
}
159+
160+
void vscode.window.withProgress(
161+
{
162+
cancellable: true,
163+
location: vscode.ProgressLocation.Notification,
164+
title: val.message,
165+
},
166+
async (_) => {
167+
await promise
137168
}
138169
)
170+
})
139171

140-
let promise: Promise<void> | undefined
141-
let resolver: () => void = () => {}
142-
client.onProgress(
143-
GetSsoTokenProgressType,
144-
GetSsoTokenProgressToken,
145-
async (partialResult: GetSsoTokenProgress) => {
146-
const decryptedKey = await jose.compactDecrypt(partialResult as unknown as string, encryptionKey)
147-
const val: GetSsoTokenProgress = JSON.parse(decryptedKey.plaintext.toString())
148-
149-
if (val.state === 'InProgress') {
150-
if (promise) {
151-
resolver()
152-
}
153-
promise = new Promise<void>((resolve) => {
154-
resolver = resolve
155-
})
156-
} else {
157-
resolver()
158-
promise = undefined
159-
return
160-
}
161-
162-
void vscode.window.withProgress(
163-
{
164-
cancellable: true,
165-
location: vscode.ProgressLocation.Notification,
166-
title: val.message,
167-
},
168-
async (_) => {
169-
await promise
170-
}
171-
)
172-
}
172+
if (Experiments.instance.get('amazonqLSPInline', false)) {
173+
const inlineManager = new InlineCompletionManager(client)
174+
inlineManager.registerInlineCompletion()
175+
toDispose.push(
176+
inlineManager,
177+
Commands.register({ id: 'aws.amazonq.invokeInlineCompletion', autoconnect: true }, async () => {
178+
await vscode.commands.executeCommand('editor.action.inlineSuggest.trigger')
179+
}),
180+
vscode.workspace.onDidCloseTextDocument(async () => {
181+
await vscode.commands.executeCommand('aws.amazonq.rejectCodeSuggestion')
182+
})
173183
)
184+
}
174185

175-
if (Experiments.instance.get('amazonqLSPInline', false)) {
176-
const inlineManager = new InlineCompletionManager(client)
177-
inlineManager.registerInlineCompletion()
178-
toDispose.push(
179-
inlineManager,
180-
Commands.register({ id: 'aws.amazonq.invokeInlineCompletion', autoconnect: true }, async () => {
181-
await vscode.commands.executeCommand('editor.action.inlineSuggest.trigger')
182-
}),
183-
vscode.workspace.onDidCloseTextDocument(async () => {
184-
await vscode.commands.executeCommand('aws.amazonq.rejectCodeSuggestion')
185-
})
186-
)
187-
}
186+
if (Experiments.instance.get('amazonqChatLSP', false)) {
187+
activate(client, encryptionKey, resourcePaths.ui)
188+
}
188189

189-
if (Experiments.instance.get('amazonqChatLSP', false)) {
190-
activate(client, encryptionKey, resourcePaths.ui)
191-
AuthUtil.create(new auth2.LanguageClientAuth(client, clientId, encryptionKey))
192-
await AuthUtil.instance.restore()
193-
}
194-
})
190+
return client
195191
}

packages/amazonq/test/unit/codewhisperer/util/authUtil.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
// /*!
2-
// * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3-
// * SPDX-License-Identifier: Apache-2.0
4-
// */
1+
/*!
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
55

66
// import assert from 'assert'
77
// import {

packages/core/src/auth/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,7 @@ export async function findSsoConnections(
617617
return (await allConnections()).filter(predicate).filter(isIdcSsoConnection)
618618
}
619619

620-
export type BuilderIdKind = 'any' | 'codewhisperer' | 'codecatalyst'
620+
export type BuilderIdKind = 'any' | 'codecatalyst'
621621

622622
/**
623623
* Returns true if a Builder ID connection exists.

packages/core/src/shared/settings-toolkit.gen.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ export const toolkitSettings = {
4242
},
4343
"aws.experiments": {
4444
"jsonResourceModification": {},
45-
"amazonqLSP": {},
4645
"amazonqLSPInline": {},
4746
"amazonqChatLSP": {}
4847
},

packages/core/src/test/amazonq/customizationUtil.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
import { FeatureContext, globals } from '../../shared'
2020
import { resetCodeWhispererGlobalVariables } from '../codewhisperer/testUtil'
2121
import { createSsoProfile, createTestAuth } from '../credentials/testUtil'
22+
import { LanguageClientAuth } from '../../auth/auth2'
2223

2324
const enterpriseSsoStartUrl = 'https://enterprise.awsapps.com/start'
2425

@@ -29,6 +30,10 @@ describe('CodeWhisperer-customizationUtils', function () {
2930
before(async function () {
3031
createTestAuth(globals.globalState)
3132
tryRegister(refreshStatusBar)
33+
const mockLspAuth: Partial<LanguageClientAuth> = {
34+
registerSsoTokenChangedHandler: sinon.stub().resolves(),
35+
}
36+
AuthUtil.create(mockLspAuth as LanguageClientAuth)
3237
})
3338

3439
beforeEach(async function () {
@@ -58,6 +63,7 @@ describe('CodeWhisperer-customizationUtils', function () {
5863

5964
it('Returns baseCustomization when not SSO', async function () {
6065
sinon.stub(AuthUtil.instance, 'isIdcConnection').returns(false)
66+
6167
const customization = getSelectedCustomization()
6268

6369
assert.strictEqual(customization.name, baseCustomization.name)
@@ -80,6 +86,8 @@ describe('CodeWhisperer-customizationUtils', function () {
8086
})
8187

8288
it(`setSelectedCustomization should set to the customization provided if override option is false or not specified`, async function () {
89+
sinon.stub(AuthUtil.instance, 'isIdcConnection').returns(true)
90+
8391
await setSelectedCustomization({ arn: 'FOO' }, false)
8492
assert.strictEqual(getSelectedCustomization().arn, 'FOO')
8593

@@ -94,6 +102,8 @@ describe('CodeWhisperer-customizationUtils', function () {
94102
})
95103

96104
it(`setSelectedCustomization should only set to the customization provided once for override per customization arn if override is true`, async function () {
105+
sinon.stub(AuthUtil.instance, 'isIdcConnection').returns(true)
106+
97107
await setSelectedCustomization({ arn: 'OVERRIDE' }, true)
98108
assert.strictEqual(getSelectedCustomization().arn, 'OVERRIDE')
99109

0 commit comments

Comments
 (0)