Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Broaden install prompt #705

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/actions/promptInstall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { WorkspaceServices } from '../services/workspaceServices';
import * as vscode from 'vscode';
import { INSTALL_PROMPT, Telemetry } from '../telemetry';
import ExtensionState from '../configuration/extensionState';
import { hasSupportedFramework, isLanguageSupported } from '../workspace/projectMetadata';

export enum ButtonText {
Confirm = 'Open instructions',
Expand All @@ -23,10 +24,9 @@ const promptResponses: ReadonlyArray<vscode.MessageItem> = [
];

const meetsPromptCriteria = (project: ProjectStateServiceInstance): boolean =>
project.installable &&
!project.metadata.agentInstalled &&
project.metadata.language?.name === 'Ruby' &&
project.metadata.webFramework?.name === 'Rails';
isLanguageSupported(project.metadata) &&
hasSupportedFramework(project.metadata) &&
!project.metadata.agentInstalled;

export default async function promptInstall(
services: WorkspaceServices,
Expand Down
3 changes: 1 addition & 2 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<AppMap
findByName(context, projectStates, appmapCollectionFile);
resetUsageState(context, extensionState);

if (!openedInstallGuide && !SignInManager.shouldShowSignIn())
promptInstall(workspaceServices, extensionState);
if (!openedInstallGuide) promptInstall(workspaceServices, extensionState);

vscode.env.onDidChangeTelemetryEnabled((enabled: boolean) => {
Telemetry.sendEvent(TELEMETRY_ENABLED, {
Expand Down
42 changes: 19 additions & 23 deletions test/integration/actions/promptInstall.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import promptInstall, { ButtonText } from '../../../src/actions/promptInstall';
import ExtensionState from '../../../src/configuration/extensionState';
import { ProjectStateServiceInstance } from '../../../src/services/projectStateService';
import { ProjectA, unsafeCast } from '../util';
import Feature from '../../../src/workspace/feature';

const stubWorkspaceServices = (installable = true, language = 'Ruby', webFramework = 'Rails') =>
const stubWorkspaceServices = (language: Feature, webFramework?: Feature) =>
unsafeCast<WorkspaceServices>({
getService: () => sinon.stub(),
getServiceInstances: () =>
Expand All @@ -17,20 +18,26 @@ const stubWorkspaceServices = (installable = true, language = 'Ruby', webFramewo
folder: { name: path.basename(ProjectA), uri: vscode.Uri.parse(ProjectA), index: -1 },
metadata: {
agentInstalled: false,
language: { name: language },
webFramework: { name: webFramework },
language,
languages: [language],
webFramework,
},
installable,
},
]),
});

describe('promptInstall', () => {
const workspaceServices = stubWorkspaceServices();
const langAndFrameworkProject = stubWorkspaceServices(
{ name: 'Ruby', score: 2, text: 'GA language' },
{ name: 'Rails', score: 2, text: 'GA framework' }
);
const langOnlyProject = stubWorkspaceServices({ name: 'Ruby', score: 2, text: 'GA language' });

afterEach(() => sinon.restore());

context('in an installable project', () => {
const project = langAndFrameworkProject;

let hideInstallPrompt = false;
const extensionState = unsafeCast<ExtensionState>({
getHideInstallPrompt: () => hideInstallPrompt,
Expand All @@ -47,7 +54,7 @@ describe('promptInstall', () => {
it('prompts the user to install AppMap', async () => {
const showInformationMessage = sinon.stub(vscode.window, 'showInformationMessage').resolves();

await promptInstall(workspaceServices, extensionState);
await promptInstall(project, extensionState);

assert(
showInformationMessage.calledWith(
Expand All @@ -61,7 +68,7 @@ describe('promptInstall', () => {
sinon.stub(vscode.window, 'showInformationMessage').resolves({ title: ButtonText.Confirm });
const executeCommand = sinon.stub(vscode.commands, 'executeCommand').resolves();

await promptInstall(workspaceServices, extensionState);
await promptInstall(project, extensionState);

assert(executeCommand.calledWith('appmap.openInstallGuide', 'project-picker'));
});
Expand All @@ -73,7 +80,7 @@ describe('promptInstall', () => {
const executeCommand = sinon.stub(vscode.commands, 'executeCommand').resolves();

for (let i = 0; i < 5; ++i) {
await promptInstall(workspaceServices, extensionState);
await promptInstall(project, extensionState);
assert(!executeCommand.called);
assert(showInformationMessage.calledOnce);
assert((extensionState.setHideInstallPrompt as sinon.SinonStub).calledOnce);
Expand All @@ -82,34 +89,23 @@ describe('promptInstall', () => {
});

context('when the user requests to never prompt in this project', () => {
const workspaceServices = stubWorkspaceServices();
const project = langAndFrameworkProject;
const extensionState = unsafeCast<ExtensionState>({ getHideInstallPrompt: () => true });

it('does not prompt', async () => {
const showInformationMessage = sinon.stub(vscode.window, 'showInformationMessage');
await promptInstall(workspaceServices, extensionState);
await promptInstall(project, extensionState);
assert(!showInformationMessage.called);
});
});

context('when in an uninstallable project', () => {
const workspaceServices = stubWorkspaceServices(false);
const extensionState = unsafeCast<ExtensionState>({ getHideInstallPrompt: () => false });

it('does not prompt', async () => {
const showInformationMessage = sinon.stub(vscode.window, 'showInformationMessage');
await promptInstall(workspaceServices, extensionState);
assert(!showInformationMessage.called);
});
});

context('when in an installable java project', () => {
const workspaceServices = stubWorkspaceServices(true, 'Java', 'Spring');
const project = langOnlyProject;
const extensionState = unsafeCast<ExtensionState>({ getHideInstallPrompt: () => false });

it('does not prompt', async () => {
const showInformationMessage = sinon.stub(vscode.window, 'showInformationMessage');
await promptInstall(workspaceServices, extensionState);
await promptInstall(project, extensionState);
assert(!showInformationMessage.called);
});
});
Expand Down