Show the user a selection box before downloading database

At the moment, we're always deciding which database to download for the
user for an example query.

We'd like to give them a chance to change the database, so here we're
adding a step where we're showing the user a selection box with the
suggested database pre-filled.

They can choose to type in a different database before continuing the
skeleton generation process.
This commit is contained in:
Elena Tanasoiu
2023-03-31 17:03:32 +00:00
parent 3e3eb0da0a
commit 919219c084
3 changed files with 67 additions and 16 deletions

View File

@@ -1,7 +1,7 @@
import fetch, { Response } from "node-fetch";
import { zip } from "zip-a-folder";
import { Open } from "unzipper";
import { Uri, CancellationToken, window } from "vscode";
import { Uri, CancellationToken, window, InputBoxOptions } from "vscode";
import { CodeQLCliServer } from "./cli";
import {
ensureDir,
@@ -92,17 +92,7 @@ export async function promptImportGithubDatabase(
token: CancellationToken,
cli?: CodeQLCliServer,
): Promise<DatabaseItem | undefined> {
progress({
message: "Choose repository",
step: 1,
maxStep: 2,
});
const githubRepo = await window.showInputBox({
title:
'Enter a GitHub repository URL or "name with owner" (e.g. https://github.com/github/codeql or github/codeql)',
placeHolder: "https://github.com/<owner>/<repo> or <owner>/<repo>",
ignoreFocusOut: true,
});
const githubRepo = await askForGitHubRepo(progress);
if (!githubRepo) {
return;
}
@@ -128,6 +118,30 @@ export async function promptImportGithubDatabase(
return;
}
export async function askForGitHubRepo(
progress: ProgressCallback,
suggestedValue?: string,
): Promise<string | undefined> {
progress({
message: "Choose repository",
step: 1,
maxStep: 2,
});
const options: InputBoxOptions = {
title:
'Enter a GitHub repository URL or "name with owner" (e.g. https://github.com/github/codeql or github/codeql)',
placeHolder: "https://github.com/<owner>/<repo> or <owner>/<repo>",
ignoreFocusOut: true,
};
if (suggestedValue) {
options.value = suggestedValue;
}
return await window.showInputBox(options);
}
/**
* Downloads a database from GitHub
*

View File

@@ -207,9 +207,17 @@ export class SkeletonQueryWizard {
});
const githubRepoNwo = QUERY_LANGUAGE_TO_DATABASE_REPO[this.language];
const chosenRepo = await databaseFetcher.askForGitHubRepo(
this.progress,
githubRepoNwo,
);
if (!chosenRepo) {
throw new Error("No GitHub repository provided");
}
await databaseFetcher.downloadGitHubDatabase(
githubRepoNwo,
chosenRepo,
this.databaseManager,
this.storagePath,
this.credentials,

View File

@@ -32,6 +32,9 @@ describe("SkeletonQueryWizard", () => {
let downloadGitHubDatabaseSpy: jest.SpiedFunction<
typeof databaseFetcher.downloadGitHubDatabase
>;
let askForGitHubRepoSpy: jest.SpiedFunction<
typeof databaseFetcher.askForGitHubRepo
>;
let openTextDocumentSpy: jest.SpiedFunction<
typeof workspace.openTextDocument
>;
@@ -59,6 +62,8 @@ describe("SkeletonQueryWizard", () => {
getSupportedLanguages: jest.fn(),
});
jest.spyOn(extLogger, "log").mockResolvedValue(undefined);
beforeEach(async () => {
dir = tmp.dirSync({
prefix: "skeleton_query_wizard_",
@@ -102,6 +107,10 @@ describe("SkeletonQueryWizard", () => {
mockDatabaseManager,
token,
);
askForGitHubRepoSpy = jest
.spyOn(databaseFetcher, "askForGitHubRepo")
.mockResolvedValue(QUERY_LANGUAGE_TO_DATABASE_REPO[chosenLanguage]);
});
afterEach(async () => {
@@ -251,10 +260,30 @@ describe("SkeletonQueryWizard", () => {
.mockResolvedValue(undefined);
});
it("should download a new database for language", async () => {
await wizard.execute();
describe("if the user choses to downloaded the suggested database from GitHub", () => {
it("should download a new database for language", async () => {
await wizard.execute();
expect(downloadGitHubDatabaseSpy).toHaveBeenCalled();
expect(askForGitHubRepoSpy).toHaveBeenCalled();
expect(downloadGitHubDatabaseSpy).toHaveBeenCalled();
});
});
describe("if the user choses to download a different database from GitHub than the one suggested", () => {
beforeEach(() => {
const chosenGitHubRepo = "pickles-owner/pickles-repo";
askForGitHubRepoSpy = jest
.spyOn(databaseFetcher, "askForGitHubRepo")
.mockResolvedValue(chosenGitHubRepo);
});
it("should download the newly chosen database", async () => {
await wizard.execute();
expect(askForGitHubRepoSpy).toHaveBeenCalled();
expect(downloadGitHubDatabaseSpy).toHaveBeenCalled();
});
});
});
});