Path: blob/main/extensions/copilot/src/extension/conversation/vscode-node/test/conversationFeature.test.ts
13405 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/456import assert from 'assert';7import * as sinon from 'sinon';8import * as vscode from 'vscode';9import { IAuthenticationService } from '../../../../platform/authentication/common/authentication';10import { CopilotToken, createTestExtendedTokenInfo } from '../../../../platform/authentication/common/copilotToken';11import { setCopilotToken, StaticGitHubAuthenticationService } from '../../../../platform/authentication/common/staticGitHubAuthenticationService';12import { FailingDevContainerConfigurationService, IDevContainerConfigurationService } from '../../../../platform/devcontainer/common/devContainerConfigurationService';13import { ICombinedEmbeddingIndex, VSCodeCombinedIndexImpl } from '../../../../platform/embeddings/common/vscodeIndex';14import { IVSCodeExtensionContext } from '../../../../platform/extContext/common/extensionContext';15import { IGitCommitMessageService, NoopGitCommitMessageService } from '../../../../platform/git/common/gitCommitMessageService';16import { ISettingsEditorSearchService, NoopSettingsEditorSearchService } from '../../../../platform/settingsEditor/common/settingsEditorSearchService';17import { ITestingServicesAccessor } from '../../../../platform/test/node/services';18import { SyncDescriptor } from '../../../../util/vs/platform/instantiation/common/descriptors';19import { IInstantiationService } from '../../../../util/vs/platform/instantiation/common/instantiation';20import { IMergeConflictService } from '../../../git/common/mergeConflictService';21import { TestMergeConflictServiceImpl } from '../../../git/vscode/mergeConflictServiceImpl';22import { IIntentService, IntentService } from '../../../intents/node/intentService';23import { INewWorkspacePreviewContentManager, NewWorkspacePreviewContentManagerImpl } from '../../../intents/node/newIntent';24import { createExtensionTestingServices } from '../../../test/vscode-node/services';25import { ConversationFeature } from '../conversationFeature';2627suite('Conversation feature test suite', function () {28let accessor: ITestingServicesAccessor;29let instaService: IInstantiationService;30let sandbox: sinon.SinonSandbox;3132function createAccessor() {33const testingServiceCollection = createExtensionTestingServices();34testingServiceCollection.define(ICombinedEmbeddingIndex, new SyncDescriptor(VSCodeCombinedIndexImpl, [/*useRemoteCache*/ false]));35testingServiceCollection.define(INewWorkspacePreviewContentManager, new SyncDescriptor(NewWorkspacePreviewContentManagerImpl));36testingServiceCollection.define(IGitCommitMessageService, new NoopGitCommitMessageService());37testingServiceCollection.define(IDevContainerConfigurationService, new FailingDevContainerConfigurationService());38testingServiceCollection.define(IIntentService, new SyncDescriptor(IntentService));39testingServiceCollection.define(ISettingsEditorSearchService, new SyncDescriptor(NoopSettingsEditorSearchService));40testingServiceCollection.define(IMergeConflictService, new SyncDescriptor(TestMergeConflictServiceImpl));41// We don't need auth in these tests42testingServiceCollection.define(IAuthenticationService, new SyncDescriptor(StaticGitHubAuthenticationService, [() => undefined]));4344accessor = testingServiceCollection.createTestingAccessor();45instaService = accessor.get(IInstantiationService);46}4748setup(() => {49sandbox = sinon.createSandbox();50sandbox.stub(vscode.commands, 'registerCommand').returns({ dispose: () => { } });51sandbox.stub(vscode.workspace, 'registerFileSystemProvider').returns({ dispose: () => { } });52createAccessor();53});5455teardown(() => {56sandbox.restore();57const extensionContext = accessor.get(IVSCodeExtensionContext);58extensionContext.subscriptions.forEach(sub => sub.dispose());59});6061test.skip(`If the 'interactive' namespace is not available, the feature is not enabled and not activated`, function () {62// TODO: The vscode module cannot be stubbed63sandbox.stub(vscode, 'interactive').value(undefined);6465const conversationFeature = instaService.createInstance(ConversationFeature);66try {67assert.deepStrictEqual(conversationFeature.enabled, false);68assert.deepStrictEqual(conversationFeature.activated, false);69} finally {70conversationFeature.dispose();71}72});7374test(`If the 'interactive' version does not match, the feature is not enabled and not activated`, function () {75const conversationFeature = instaService.createInstance(ConversationFeature);76try {77assert.deepStrictEqual(conversationFeature.enabled, false);78assert.deepStrictEqual(conversationFeature.activated, false);79} finally {80conversationFeature.dispose();81}82});8384test('The feature is enabled and activated in test mode', function () {85const conversationFeature = instaService.createInstance(ConversationFeature);86try {87const copilotToken = new CopilotToken(createTestExtendedTokenInfo({ token: 'token', username: 'fake', copilot_plan: 'unknown' }));88setCopilotToken(accessor.get(IAuthenticationService), copilotToken);8990assert.deepStrictEqual(conversationFeature.enabled, true);91assert.deepStrictEqual(conversationFeature.activated, true);92} finally {93conversationFeature.dispose();94}95});9697test('If the token envelope setting is set to true, the feature should be enabled', function () {98const conversationFeature = instaService.createInstance(ConversationFeature);99try {100const copilotToken = new CopilotToken(createTestExtendedTokenInfo({ token: 'token', username: 'fake', copilot_plan: 'unknown' }));101setCopilotToken(accessor.get(IAuthenticationService), copilotToken);102103assert.deepStrictEqual(conversationFeature.enabled, true);104} finally {105conversationFeature.dispose();106}107});108109test('The feature should be activated when it becomes enabled', function () {110const conversationFeature = instaService.createInstance(ConversationFeature);111try {112const copilotToken = new CopilotToken(createTestExtendedTokenInfo({ token: 'token', username: 'fake', copilot_plan: 'unknown' }));113setCopilotToken(accessor.get(IAuthenticationService), copilotToken);114assert.deepStrictEqual(conversationFeature.enabled, true);115assert.deepStrictEqual(conversationFeature.activated, true);116} finally {117conversationFeature.dispose();118}119});120121test('The feature should register a chat provider on activation', function () {122if (!vscode.chat.createChatParticipant) {123this.skip();124}125126const conversationFeature = instaService.createInstance(ConversationFeature);127try {128129const copilotToken = new CopilotToken(createTestExtendedTokenInfo({ token: 'token', username: 'fake', copilot_plan: 'unknown' }));130setCopilotToken(accessor.get(IAuthenticationService), copilotToken);131132assert.deepStrictEqual(conversationFeature.activated, true);133} finally {134conversationFeature.dispose();135}136});137});138139140