Skip to content
Merged
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
4 changes: 2 additions & 2 deletions extensions/ql-vscode/src/databases/local-databases-ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,15 +235,15 @@ async function chooseDatabaseDir(byFolder: boolean): Promise<Uri | undefined> {
return getFirst(chosen);
}

interface DatabaseSelectionQuickPickItem extends QuickPickItem {
export interface DatabaseSelectionQuickPickItem extends QuickPickItem {
databaseKind: "new" | "existing";
}

export interface DatabaseQuickPickItem extends QuickPickItem {
databaseItem: DatabaseItem;
}

interface DatabaseImportQuickPickItems extends QuickPickItem {
export interface DatabaseImportQuickPickItems extends QuickPickItem {
importType: "URL" | "github" | "archive" | "folder";
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,42 @@ import {
createFileSync,
pathExistsSync,
} from "fs-extra";
import { Uri } from "vscode";
import { CancellationTokenSource, Uri, window } from "vscode";

import type {
DatabaseImportQuickPickItems,
DatabaseQuickPickItem,
DatabaseSelectionQuickPickItem,
} from "../../../../src/databases/local-databases-ui";

import { DatabaseUI } from "../../../../src/databases/local-databases-ui";
import { testDisposeHandler } from "../../test-dispose-handler";
import { createMockApp } from "../../../__mocks__/appMock";
import { QueryLanguage } from "../../../../src/common/query-language";
import { mockedQuickPickItem, mockedObject } from "../../utils/mocking.helpers";

describe("local-databases-ui", () => {
const storageDir = dirSync({ unsafeCleanup: true }).name;
const db1 = createDatabase(storageDir, "db1-imported", QueryLanguage.Cpp);
const db2 = createDatabase(storageDir, "db2-notimported", QueryLanguage.Cpp);
const db3 = createDatabase(storageDir, "db3-invalidlanguage", "hucairz");

// these two should be deleted
const db4 = createDatabase(
storageDir,
"db2-notimported-with-db-info",
QueryLanguage.Cpp,
".dbinfo",
);
const db5 = createDatabase(
storageDir,
"db2-notimported-with-codeql-database.yml",
QueryLanguage.Cpp,
"codeql-database.yml",
);

const app = createMockApp({});

describe("fixDbUri", () => {
const fixDbUri = (DatabaseUI.prototype as any).fixDbUri;
it("should choose current directory normally", async () => {
Expand Down Expand Up @@ -64,30 +92,6 @@ describe("local-databases-ui", () => {
});

it("should delete orphaned databases", async () => {
const storageDir = dirSync({ unsafeCleanup: true }).name;
const db1 = createDatabase(storageDir, "db1-imported", QueryLanguage.Cpp);
const db2 = createDatabase(
storageDir,
"db2-notimported",
QueryLanguage.Cpp,
);
const db3 = createDatabase(storageDir, "db3-invalidlanguage", "hucairz");

// these two should be deleted
const db4 = createDatabase(
storageDir,
"db2-notimported-with-db-info",
QueryLanguage.Cpp,
".dbinfo",
);
const db5 = createDatabase(
storageDir,
"db2-notimported-with-codeql-database.yml",
QueryLanguage.Cpp,
"codeql-database.yml",
);

const app = createMockApp({});
const databaseUI = new DatabaseUI(
app,
{
Expand All @@ -98,6 +102,7 @@ describe("local-databases-ui", () => {
onDidChangeCurrentDatabaseItem: () => {
/**/
},
setCurrentDatabaseItem: () => {},
} as any,
{
onLanguageContextChanged: () => {
Expand All @@ -108,7 +113,6 @@ describe("local-databases-ui", () => {
storageDir,
storageDir,
);

await databaseUI.handleRemoveOrphanedDatabases();

expect(pathExistsSync(db1)).toBe(true);
Expand All @@ -121,6 +125,130 @@ describe("local-databases-ui", () => {
databaseUI.dispose(testDisposeHandler);
});

describe("getDatabaseItem", () => {
const progress = jest.fn();
const token = new CancellationTokenSource().token;
describe("when there is a current database", () => {
const databaseUI = new DatabaseUI(
app,
{
databaseItems: [{ databaseUri: Uri.file(db1) }],
onDidChangeDatabaseItem: () => {
/**/
},
onDidChangeCurrentDatabaseItem: () => {
/**/
},
setCurrentDatabaseItem: () => {},
currentDatabaseItem: { databaseUri: Uri.file(db1) },
} as any,
{
onLanguageContextChanged: () => {
/**/
},
} as any,
{} as any,
storageDir,
storageDir,
);

it("should return current database", async () => {
const databaseItem = await databaseUI.getDatabaseItem(progress, token);

expect(databaseItem).toEqual({ databaseUri: Uri.file(db1) });
});
});

describe("when there is no current database", () => {
const databaseManager = {
databaseItems: [
{ databaseUri: Uri.file(db1) },
{ databaseUri: Uri.file(db2) },
],
onDidChangeDatabaseItem: () => {
/**/
},
onDidChangeCurrentDatabaseItem: () => {
/**/
},
setCurrentDatabaseItem: () => {},
currentDatabaseItem: undefined,
} as any;

const databaseUI = new DatabaseUI(
app,
databaseManager,
{
onLanguageContextChanged: () => {
/**/
},
} as any,
{} as any,
storageDir,
storageDir,
);

it("should prompt for a database and select existing one", async () => {
const showQuickPickSpy = jest
.spyOn(window, "showQuickPick")
.mockResolvedValueOnce(
mockedQuickPickItem(
mockedObject<DatabaseSelectionQuickPickItem>({
databaseKind: "existing",
}),
),
)
.mockResolvedValueOnce(
mockedQuickPickItem(
mockedObject<DatabaseQuickPickItem>({
databaseItem: { databaseUri: Uri.file(db2) },
}),
),
);

const setCurrentDatabaseItemSpy = jest.spyOn(
databaseManager,
"setCurrentDatabaseItem",
);

await databaseUI.getDatabaseItem(progress, token);

expect(showQuickPickSpy).toHaveBeenCalledTimes(2);
expect(setCurrentDatabaseItemSpy).toHaveBeenCalledWith({
databaseUri: Uri.file(db2),
});
});

it("should prompt for a database and import a new one", async () => {
const showQuickPickSpy = jest
.spyOn(window, "showQuickPick")
.mockResolvedValueOnce(
mockedQuickPickItem(
mockedObject<DatabaseSelectionQuickPickItem>({
databaseKind: "new",
}),
),
)
.mockResolvedValueOnce(
mockedQuickPickItem(
mockedObject<DatabaseImportQuickPickItems>({
importType: "github",
}),
),
);

const handleChooseDatabaseGithubSpy = jest
.spyOn(databaseUI as any, "handleChooseDatabaseGithub")
.mockResolvedValue(undefined);

await databaseUI.getDatabaseItem(progress, token);

expect(showQuickPickSpy).toHaveBeenCalledTimes(2);
expect(handleChooseDatabaseGithubSpy).toHaveBeenCalledTimes(1);
});
});
});

function createDatabase(
storageDir: string,
dbName: string,
Expand Down