Loading package.json +14 −14 Original line number Diff line number Diff line Loading @@ -52,7 +52,7 @@ "type": "webview", "id": "gl.chatView", "name": "Experiment", "when": "config.gitlab.duoChat.enabled && !gitlab:noAccount" "when": "config.gitlab.duoChat.enabled && gitlab:chatAvailable" } ] }, Loading Loading @@ -103,23 +103,23 @@ "commandPalette": [ { "command": "gl.openChat", "when": "config.gitlab.duoChat.enabled && !gitlab:noAccount" "when": "config.gitlab.duoChat.enabled && gitlab:chatAvailable" }, { "command": "gl.explainSelectedCode", "when": "config.gitlab.duoChat.enabled && !gitlab:noAccount && editorHasSelection" "when": "config.gitlab.duoChat.enabled && gitlab:chatAvailable && editorHasSelection" }, { "command": "gl.generateTests", "when": "config.gitlab.duoChat.enabled && !gitlab:noAccount && editorHasSelection" "when": "config.gitlab.duoChat.enabled && gitlab:chatAvailable && editorHasSelection" }, { "command": "gl.refactorCode", "when": "config.gitlab.duoChat.enabled && !gitlab:noAccount && editorHasSelection" "when": "config.gitlab.duoChat.enabled && gitlab:chatAvailable && editorHasSelection" }, { "command": "gl.newChatConversation", "when": "config.gitlab.duoChat.enabled && !gitlab:noAccount" "when": "config.gitlab.duoChat.enabled && gitlab:chatAvailable" } ], "editor/context": [ Loading @@ -132,44 +132,44 @@ { "command": "gl.explainSelectedCode", "group": "navigation", "when": "config.gitlab.duoChat.enabled && !gitlab:noAccount && editorHasSelection" "when": "config.gitlab.duoChat.enabled && gitlab:chatAvailable && editorHasSelection" }, { "command": "gl.generateTests", "group": "navigation", "when": "config.gitlab.duoChat.enabled && !gitlab:noAccount && editorHasSelection" "when": "config.gitlab.duoChat.enabled && gitlab:chatAvailable && editorHasSelection" }, { "command": "gl.refactorCode", "group": "navigation", "when": "config.gitlab.duoChat.enabled && !gitlab:noAccount && editorHasSelection" "when": "config.gitlab.duoChat.enabled && gitlab:chatAvailable && editorHasSelection" } ] }, "keybindings": [ { "command": "gl.openChat", "when": "config.gitlab.duoChat.enabled && !gitlab:noAccount", "when": "config.gitlab.duoChat.enabled && gitlab:chatAvailable", "key": "alt+d" }, { "command": "gl.explainSelectedCode", "when": "config.gitlab.duoChat.enabled && !gitlab:noAccount && editorHasSelection", "when": "config.gitlab.duoChat.enabled && gitlab:chatAvailable && editorHasSelection", "key": "alt+e" }, { "command": "gl.generateTests", "when": "config.gitlab.duoChat.enabled && !gitlab:noAccount && editorHasSelection", "when": "config.gitlab.duoChat.enabled && gitlab:chatAvailable && editorHasSelection", "key": "alt+t" }, { "command": "gl.refactorCode", "when": "config.gitlab.duoChat.enabled && !gitlab:noAccount && editorHasSelection", "when": "config.gitlab.duoChat.enabled && gitlab:chatAvailable && editorHasSelection", "key": "alt+r" }, { "command": "gl.newChatConversation", "when": "config.gitlab.duoChat.enabled && !gitlab:noAccount", "when": "config.gitlab.duoChat.enabled && gitlab:chatAvailable", "key": "alt+n" } ], Loading src/browser/browser.ts +4 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ import { activateCommon } from '../common/main'; import * as featureFlags from '../common/feature_flags'; import { registerLanguageServer } from '../common/language_server/register_language_server'; import { CodeSuggestions } from '../common/code_suggestions/code_suggestions'; import { getChatSupport } from '../common/chat/api/get_chat_support'; import { browserLanguageClientFactory } from './language_server/browser_language_client_factory'; import { createDependencyContainer } from './dependency_container_browser'; Loading @@ -16,6 +17,9 @@ export const activate = async (context: vscode.ExtensionContext) => { await vscode.commands.executeCommand('setContext', 'gitlab:noAccount', false); await vscode.commands.executeCommand('setContext', 'gitlab:validState', true); const duoChatAvailable: boolean = await getChatSupport(dependencyContainer.gitLabPlatformManager); await vscode.commands.executeCommand('setContext', 'gitlab:chatAvailable', duoChatAvailable); const platform = await dependencyContainer.gitLabPlatformManager.getForSaaSAccount(); await vscode.commands.executeCommand( Loading src/common/chat/api/get_chat_support.test.ts 0 → 100644 +69 −0 Original line number Diff line number Diff line import { GitLabPlatformManager } from '../../platform/gitlab_platform'; import { GitLabPlatformManagerForChat } from '../get_platform_manager_for_chat'; import { gitlabPlatformForAccount } from '../../test_utils/entities'; import { createFakePartial } from '../../test_utils/create_fake_partial'; import { log } from '../../log'; import { getChatSupport, ChatAvailableResponseType } from './get_chat_support'; jest.mock('../get_platform_manager_for_chat'); describe('getChatSupport', () => { let manager: GitLabPlatformManager; let platformManagerForChat: GitLabPlatformManagerForChat; const mockApiResponse = (duoChatAvailable: boolean = true) => { const apiResponse: ChatAvailableResponseType = { currentUser: { duoChatAvailable, }, }; jest.mocked(platformManagerForChat.getGitLabPlatform).mockResolvedValue({ ...gitlabPlatformForAccount, fetchFromApi: jest.fn().mockResolvedValue(apiResponse), }); }; beforeEach(() => { manager = createFakePartial<GitLabPlatformManager>({ getForAllAccounts: jest.fn(), }); platformManagerForChat = createFakePartial<GitLabPlatformManagerForChat>({ getGitLabPlatform: jest.fn(), }); jest.mocked(GitLabPlatformManagerForChat).mockImplementation(() => platformManagerForChat); jest.spyOn(log, 'error'); }); afterEach(() => { jest.clearAllMocks(); }); it('returns false if there is no platform', async () => { jest.mocked(platformManagerForChat.getGitLabPlatform).mockResolvedValue(undefined); const result = await getChatSupport(manager); expect(result).toBe(false); }); it('returns false and logs if fetching `duoChatAvailable` fails', async () => { jest.mocked(platformManagerForChat.getGitLabPlatform).mockResolvedValue({ ...gitlabPlatformForAccount, fetchFromApi: jest.fn().mockRejectedValueOnce('foo'), }); const result = await getChatSupport(manager); expect(result).toBe(false); expect(log.error).toHaveBeenCalledWith('foo'); }); it('returns false and does not log if the user does not have chat support', async () => { mockApiResponse(false); const result = await getChatSupport(manager); expect(result).toBe(false); expect(log.error).not.toHaveBeenCalled(); }); it('returns true if the user has chat support', async () => { mockApiResponse(); const result = await getChatSupport(manager); expect(result).toBe(true); expect(log.error).not.toHaveBeenCalled(); }); }); src/common/chat/api/get_chat_support.ts 0 → 100644 +40 −0 Original line number Diff line number Diff line import { gql } from 'graphql-request'; import { GraphQLRequest } from '../../platform/web_ide'; import { GitLabPlatformManager } from '../../platform/gitlab_platform'; import { GitLabPlatformManagerForChat } from '../get_platform_manager_for_chat'; import { log } from '../../log'; const queryGetChatAvailability = gql` query duoChatAvailable { currentUser { duoChatAvailable } } `; export type ChatAvailableResponseType = { currentUser: { duoChatAvailable: boolean; }; }; export async function getChatSupport(manager: GitLabPlatformManager): Promise<boolean> { let user; const platformManagerForChat = new GitLabPlatformManagerForChat(manager); const request: GraphQLRequest<ChatAvailableResponseType> = { type: 'graphql', query: queryGetChatAvailability, variables: {}, }; const platform = await platformManagerForChat.getGitLabPlatform(); if (!platform) { return false; } try { user = await platform.fetchFromApi(request); return user.currentUser.duoChatAvailable; } catch (e) { log.error(e); return false; } } src/desktop/extension.ts +2 −1 Original line number Diff line number Diff line Loading @@ -264,7 +264,7 @@ export const activate = async (context: vscode.ExtensionContext) => { 'GitLab.com Authentication', new GitLabAuthenticationProvider(), ); await extensionState.init(accountService); registerSidebarTreeDataProviders(); registerRepositoryRootProvider( issuableController, Loading @@ -274,6 +274,7 @@ export const activate = async (context: vscode.ExtensionContext) => { await migrateCredentials(context, accountService).catch(e => handleError(e)); const dependencyContainer = createDependencyContainer(); await extensionState.init(accountService, dependencyContainer.gitLabPlatformManager); if (featureFlags.isEnabled(featureFlags.FeatureFlag.LanguageServer)) { await registerLanguageServer( Loading Loading
package.json +14 −14 Original line number Diff line number Diff line Loading @@ -52,7 +52,7 @@ "type": "webview", "id": "gl.chatView", "name": "Experiment", "when": "config.gitlab.duoChat.enabled && !gitlab:noAccount" "when": "config.gitlab.duoChat.enabled && gitlab:chatAvailable" } ] }, Loading Loading @@ -103,23 +103,23 @@ "commandPalette": [ { "command": "gl.openChat", "when": "config.gitlab.duoChat.enabled && !gitlab:noAccount" "when": "config.gitlab.duoChat.enabled && gitlab:chatAvailable" }, { "command": "gl.explainSelectedCode", "when": "config.gitlab.duoChat.enabled && !gitlab:noAccount && editorHasSelection" "when": "config.gitlab.duoChat.enabled && gitlab:chatAvailable && editorHasSelection" }, { "command": "gl.generateTests", "when": "config.gitlab.duoChat.enabled && !gitlab:noAccount && editorHasSelection" "when": "config.gitlab.duoChat.enabled && gitlab:chatAvailable && editorHasSelection" }, { "command": "gl.refactorCode", "when": "config.gitlab.duoChat.enabled && !gitlab:noAccount && editorHasSelection" "when": "config.gitlab.duoChat.enabled && gitlab:chatAvailable && editorHasSelection" }, { "command": "gl.newChatConversation", "when": "config.gitlab.duoChat.enabled && !gitlab:noAccount" "when": "config.gitlab.duoChat.enabled && gitlab:chatAvailable" } ], "editor/context": [ Loading @@ -132,44 +132,44 @@ { "command": "gl.explainSelectedCode", "group": "navigation", "when": "config.gitlab.duoChat.enabled && !gitlab:noAccount && editorHasSelection" "when": "config.gitlab.duoChat.enabled && gitlab:chatAvailable && editorHasSelection" }, { "command": "gl.generateTests", "group": "navigation", "when": "config.gitlab.duoChat.enabled && !gitlab:noAccount && editorHasSelection" "when": "config.gitlab.duoChat.enabled && gitlab:chatAvailable && editorHasSelection" }, { "command": "gl.refactorCode", "group": "navigation", "when": "config.gitlab.duoChat.enabled && !gitlab:noAccount && editorHasSelection" "when": "config.gitlab.duoChat.enabled && gitlab:chatAvailable && editorHasSelection" } ] }, "keybindings": [ { "command": "gl.openChat", "when": "config.gitlab.duoChat.enabled && !gitlab:noAccount", "when": "config.gitlab.duoChat.enabled && gitlab:chatAvailable", "key": "alt+d" }, { "command": "gl.explainSelectedCode", "when": "config.gitlab.duoChat.enabled && !gitlab:noAccount && editorHasSelection", "when": "config.gitlab.duoChat.enabled && gitlab:chatAvailable && editorHasSelection", "key": "alt+e" }, { "command": "gl.generateTests", "when": "config.gitlab.duoChat.enabled && !gitlab:noAccount && editorHasSelection", "when": "config.gitlab.duoChat.enabled && gitlab:chatAvailable && editorHasSelection", "key": "alt+t" }, { "command": "gl.refactorCode", "when": "config.gitlab.duoChat.enabled && !gitlab:noAccount && editorHasSelection", "when": "config.gitlab.duoChat.enabled && gitlab:chatAvailable && editorHasSelection", "key": "alt+r" }, { "command": "gl.newChatConversation", "when": "config.gitlab.duoChat.enabled && !gitlab:noAccount", "when": "config.gitlab.duoChat.enabled && gitlab:chatAvailable", "key": "alt+n" } ], Loading
src/browser/browser.ts +4 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ import { activateCommon } from '../common/main'; import * as featureFlags from '../common/feature_flags'; import { registerLanguageServer } from '../common/language_server/register_language_server'; import { CodeSuggestions } from '../common/code_suggestions/code_suggestions'; import { getChatSupport } from '../common/chat/api/get_chat_support'; import { browserLanguageClientFactory } from './language_server/browser_language_client_factory'; import { createDependencyContainer } from './dependency_container_browser'; Loading @@ -16,6 +17,9 @@ export const activate = async (context: vscode.ExtensionContext) => { await vscode.commands.executeCommand('setContext', 'gitlab:noAccount', false); await vscode.commands.executeCommand('setContext', 'gitlab:validState', true); const duoChatAvailable: boolean = await getChatSupport(dependencyContainer.gitLabPlatformManager); await vscode.commands.executeCommand('setContext', 'gitlab:chatAvailable', duoChatAvailable); const platform = await dependencyContainer.gitLabPlatformManager.getForSaaSAccount(); await vscode.commands.executeCommand( Loading
src/common/chat/api/get_chat_support.test.ts 0 → 100644 +69 −0 Original line number Diff line number Diff line import { GitLabPlatformManager } from '../../platform/gitlab_platform'; import { GitLabPlatformManagerForChat } from '../get_platform_manager_for_chat'; import { gitlabPlatformForAccount } from '../../test_utils/entities'; import { createFakePartial } from '../../test_utils/create_fake_partial'; import { log } from '../../log'; import { getChatSupport, ChatAvailableResponseType } from './get_chat_support'; jest.mock('../get_platform_manager_for_chat'); describe('getChatSupport', () => { let manager: GitLabPlatformManager; let platformManagerForChat: GitLabPlatformManagerForChat; const mockApiResponse = (duoChatAvailable: boolean = true) => { const apiResponse: ChatAvailableResponseType = { currentUser: { duoChatAvailable, }, }; jest.mocked(platformManagerForChat.getGitLabPlatform).mockResolvedValue({ ...gitlabPlatformForAccount, fetchFromApi: jest.fn().mockResolvedValue(apiResponse), }); }; beforeEach(() => { manager = createFakePartial<GitLabPlatformManager>({ getForAllAccounts: jest.fn(), }); platformManagerForChat = createFakePartial<GitLabPlatformManagerForChat>({ getGitLabPlatform: jest.fn(), }); jest.mocked(GitLabPlatformManagerForChat).mockImplementation(() => platformManagerForChat); jest.spyOn(log, 'error'); }); afterEach(() => { jest.clearAllMocks(); }); it('returns false if there is no platform', async () => { jest.mocked(platformManagerForChat.getGitLabPlatform).mockResolvedValue(undefined); const result = await getChatSupport(manager); expect(result).toBe(false); }); it('returns false and logs if fetching `duoChatAvailable` fails', async () => { jest.mocked(platformManagerForChat.getGitLabPlatform).mockResolvedValue({ ...gitlabPlatformForAccount, fetchFromApi: jest.fn().mockRejectedValueOnce('foo'), }); const result = await getChatSupport(manager); expect(result).toBe(false); expect(log.error).toHaveBeenCalledWith('foo'); }); it('returns false and does not log if the user does not have chat support', async () => { mockApiResponse(false); const result = await getChatSupport(manager); expect(result).toBe(false); expect(log.error).not.toHaveBeenCalled(); }); it('returns true if the user has chat support', async () => { mockApiResponse(); const result = await getChatSupport(manager); expect(result).toBe(true); expect(log.error).not.toHaveBeenCalled(); }); });
src/common/chat/api/get_chat_support.ts 0 → 100644 +40 −0 Original line number Diff line number Diff line import { gql } from 'graphql-request'; import { GraphQLRequest } from '../../platform/web_ide'; import { GitLabPlatformManager } from '../../platform/gitlab_platform'; import { GitLabPlatformManagerForChat } from '../get_platform_manager_for_chat'; import { log } from '../../log'; const queryGetChatAvailability = gql` query duoChatAvailable { currentUser { duoChatAvailable } } `; export type ChatAvailableResponseType = { currentUser: { duoChatAvailable: boolean; }; }; export async function getChatSupport(manager: GitLabPlatformManager): Promise<boolean> { let user; const platformManagerForChat = new GitLabPlatformManagerForChat(manager); const request: GraphQLRequest<ChatAvailableResponseType> = { type: 'graphql', query: queryGetChatAvailability, variables: {}, }; const platform = await platformManagerForChat.getGitLabPlatform(); if (!platform) { return false; } try { user = await platform.fetchFromApi(request); return user.currentUser.duoChatAvailable; } catch (e) { log.error(e); return false; } }
src/desktop/extension.ts +2 −1 Original line number Diff line number Diff line Loading @@ -264,7 +264,7 @@ export const activate = async (context: vscode.ExtensionContext) => { 'GitLab.com Authentication', new GitLabAuthenticationProvider(), ); await extensionState.init(accountService); registerSidebarTreeDataProviders(); registerRepositoryRootProvider( issuableController, Loading @@ -274,6 +274,7 @@ export const activate = async (context: vscode.ExtensionContext) => { await migrateCredentials(context, accountService).catch(e => handleError(e)); const dependencyContainer = createDependencyContainer(); await extensionState.init(accountService, dependencyContainer.gitLabPlatformManager); if (featureFlags.isEnabled(featureFlags.FeatureFlag.LanguageServer)) { await registerLanguageServer( Loading