Merge pull request #2023 from github/koesie10/db-panel-controller-repo-welcome
Show welcome view when controller repo is not setup
This commit is contained in:
@@ -1315,6 +1315,11 @@
|
||||
{
|
||||
"view": "codeQLEvalLogViewer",
|
||||
"contents": "Run the 'Show Evaluator Log (UI)' command on a CodeQL query run in the Query History view."
|
||||
},
|
||||
{
|
||||
"view": "codeQLVariantAnalysisRepositories",
|
||||
"contents": "Set up a controller repository to start using variant analysis.\n[Set up controller repository](command:codeQLVariantAnalysisRepositories.setupControllerRepository)",
|
||||
"when": "!config.codeQL.variantAnalysis.controllerRepo"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -539,6 +539,27 @@ export async function setRemoteControllerRepo(repo: string | undefined) {
|
||||
await REMOTE_CONTROLLER_REPO.updateValue(repo, ConfigurationTarget.Global);
|
||||
}
|
||||
|
||||
export interface VariantAnalysisConfig {
|
||||
controllerRepo: string | undefined;
|
||||
onDidChangeConfiguration?: Event<void>;
|
||||
}
|
||||
|
||||
export class VariantAnalysisConfigListener
|
||||
extends ConfigListener
|
||||
implements VariantAnalysisConfig
|
||||
{
|
||||
protected handleDidChangeConfiguration(e: ConfigurationChangeEvent): void {
|
||||
this.handleDidChangeConfigurationForRelevantSettings(
|
||||
[VARIANT_ANALYSIS_SETTING],
|
||||
e,
|
||||
);
|
||||
}
|
||||
|
||||
public get controllerRepo(): string | undefined {
|
||||
return getRemoteControllerRepo();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The branch of "github/codeql-variant-analysis-action" to use with the "Run Variant Analysis" command.
|
||||
* Default value is "main".
|
||||
|
||||
@@ -24,7 +24,7 @@ export class DbModule extends DisposableObject {
|
||||
const dbModule = new DbModule(app);
|
||||
app.subscriptions.push(dbModule);
|
||||
|
||||
await dbModule.initialize();
|
||||
await dbModule.initialize(app);
|
||||
return dbModule;
|
||||
}
|
||||
|
||||
@@ -39,12 +39,12 @@ export class DbModule extends DisposableObject {
|
||||
return isCanary() && isVariantAnalysisReposPanelEnabled();
|
||||
}
|
||||
|
||||
private async initialize(): Promise<void> {
|
||||
private async initialize(app: App): Promise<void> {
|
||||
void extLogger.log("Initializing database module");
|
||||
|
||||
await this.dbConfigStore.initialize();
|
||||
|
||||
const dbPanel = new DbPanel(this.dbManager);
|
||||
const dbPanel = new DbPanel(this.dbManager, app.credentials);
|
||||
await dbPanel.initialize();
|
||||
|
||||
this.push(dbPanel);
|
||||
|
||||
@@ -29,6 +29,9 @@ import { DbManager } from "../db-manager";
|
||||
import { DbTreeDataProvider } from "./db-tree-data-provider";
|
||||
import { DbTreeViewItem } from "./db-tree-view-item";
|
||||
import { getGitHubUrl } from "./db-tree-view-item-action";
|
||||
import { getControllerRepo } from "../../remote-queries/run-remote-query";
|
||||
import { getErrorMessage } from "../../pure/helpers-pure";
|
||||
import { Credentials } from "../../common/authentication";
|
||||
|
||||
export interface RemoteDatabaseQuickPickItem extends QuickPickItem {
|
||||
kind: string;
|
||||
@@ -42,7 +45,10 @@ export class DbPanel extends DisposableObject {
|
||||
private readonly dataProvider: DbTreeDataProvider;
|
||||
private readonly treeView: TreeView<DbTreeViewItem>;
|
||||
|
||||
public constructor(private readonly dbManager: DbManager) {
|
||||
public constructor(
|
||||
private readonly dbManager: DbManager,
|
||||
private readonly credentials: Credentials,
|
||||
) {
|
||||
super();
|
||||
|
||||
this.dataProvider = new DbTreeDataProvider(dbManager);
|
||||
@@ -112,6 +118,12 @@ export class DbPanel extends DisposableObject {
|
||||
(treeViewItem: DbTreeViewItem) => this.removeItem(treeViewItem),
|
||||
),
|
||||
);
|
||||
this.push(
|
||||
commandRunner(
|
||||
"codeQLVariantAnalysisRepositories.setupControllerRepository",
|
||||
() => this.setupControllerRepository(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
private async openConfigFile(): Promise<void> {
|
||||
@@ -383,4 +395,21 @@ export class DbPanel extends DisposableObject {
|
||||
|
||||
await commands.executeCommand("vscode.open", Uri.parse(githubUrl));
|
||||
}
|
||||
|
||||
private async setupControllerRepository(): Promise<void> {
|
||||
try {
|
||||
// This will also validate that the controller repository is valid
|
||||
await getControllerRepo(this.credentials);
|
||||
} catch (e: unknown) {
|
||||
if (e instanceof UserCancellationException) {
|
||||
return;
|
||||
}
|
||||
|
||||
void showAndLogErrorMessage(
|
||||
`An error occurred while setting up the controller repository: ${getErrorMessage(
|
||||
e,
|
||||
)}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
DbConfigValidationError,
|
||||
DbConfigValidationErrorKind,
|
||||
} from "../db-validation-errors";
|
||||
import { VariantAnalysisConfigListener } from "../../config";
|
||||
|
||||
export class DbTreeDataProvider
|
||||
extends DisposableObject
|
||||
@@ -27,8 +28,17 @@ export class DbTreeDataProvider
|
||||
);
|
||||
private dbTreeItems: DbTreeViewItem[];
|
||||
|
||||
private variantAnalysisConfig: VariantAnalysisConfigListener;
|
||||
|
||||
public constructor(private readonly dbManager: DbManager) {
|
||||
super();
|
||||
|
||||
this.variantAnalysisConfig = this.push(new VariantAnalysisConfigListener());
|
||||
this.variantAnalysisConfig.onDidChangeConfiguration(() => {
|
||||
this.dbTreeItems = this.createTree();
|
||||
this._onDidChangeTreeData.fire(undefined);
|
||||
});
|
||||
|
||||
this.dbTreeItems = this.createTree();
|
||||
this.onDidChangeTreeData = this._onDidChangeTreeData.event;
|
||||
|
||||
@@ -62,6 +72,11 @@ export class DbTreeDataProvider
|
||||
}
|
||||
|
||||
private createTree(): DbTreeViewItem[] {
|
||||
// Returning an empty tree here will show the welcome view
|
||||
if (!this.variantAnalysisConfig.controllerRepo) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const dbItemsResult = this.dbManager.getDbItems();
|
||||
|
||||
if (dbItemsResult.isFailure) {
|
||||
|
||||
@@ -376,10 +376,10 @@ export async function getControllerRepo(
|
||||
);
|
||||
controllerRepoNwo = await window.showInputBox({
|
||||
title:
|
||||
"Controller repository in which to run the GitHub Actions workflow for this variant analysis",
|
||||
"Controller repository in which to run GitHub Actions workflows for variant analyses",
|
||||
placeHolder: "<owner>/<repo>",
|
||||
prompt:
|
||||
"Enter the name of a GitHub repository in the format <owner>/<repo>",
|
||||
"Enter the name of a GitHub repository in the format <owner>/<repo>. You can change this in the extension settings.",
|
||||
ignoreFocusOut: true,
|
||||
});
|
||||
if (!controllerRepoNwo) {
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
|
||||
import { CodeQLExtensionInterface } from "../../../../src/extension";
|
||||
import { MockGitHubApiServer } from "../../../../src/mocks/mock-gh-api-server";
|
||||
import { mockConfiguration } from "../../utils/configuration-helpers";
|
||||
|
||||
jest.setTimeout(30_000);
|
||||
|
||||
@@ -35,50 +36,17 @@ describe("Variant Analysis Submission Integration", () => {
|
||||
let showErrorMessageSpy: jest.SpiedFunction<typeof window.showErrorMessage>;
|
||||
|
||||
beforeEach(async () => {
|
||||
const originalGetConfiguration = workspace.getConfiguration;
|
||||
|
||||
jest
|
||||
.spyOn(workspace, "getConfiguration")
|
||||
.mockImplementation((section, scope) => {
|
||||
const configuration = originalGetConfiguration(section, scope);
|
||||
|
||||
return {
|
||||
get(key: string, defaultValue?: unknown) {
|
||||
if (section === "codeQL.variantAnalysis" && key === "liveResults") {
|
||||
return true;
|
||||
}
|
||||
if (section === "codeQL" && key == "canary") {
|
||||
return true;
|
||||
}
|
||||
if (
|
||||
section === "codeQL.variantAnalysis" &&
|
||||
key === "controllerRepo"
|
||||
) {
|
||||
return "github/vscode-codeql";
|
||||
}
|
||||
return configuration.get(key, defaultValue);
|
||||
},
|
||||
has(key: string) {
|
||||
return configuration.has(key);
|
||||
},
|
||||
inspect(key: string) {
|
||||
return configuration.inspect(key);
|
||||
},
|
||||
update(
|
||||
key: string,
|
||||
value: unknown,
|
||||
configurationTarget?: boolean,
|
||||
overrideInLanguage?: boolean,
|
||||
) {
|
||||
return configuration.update(
|
||||
key,
|
||||
value,
|
||||
configurationTarget,
|
||||
overrideInLanguage,
|
||||
);
|
||||
},
|
||||
};
|
||||
});
|
||||
mockConfiguration({
|
||||
values: {
|
||||
codeQL: {
|
||||
canary: true,
|
||||
},
|
||||
"codeQL.variantAnalysis": {
|
||||
liveResults: true,
|
||||
controllerRepo: "github/vscode-codeql",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
jest.spyOn(authentication, "getSession").mockResolvedValue({
|
||||
id: "test",
|
||||
|
||||
@@ -13,6 +13,7 @@ import { DbTreeViewItem } from "../../../../src/databases/ui/db-tree-view-item";
|
||||
import { ExtensionApp } from "../../../../src/common/vscode/vscode-app";
|
||||
import { createMockExtensionContext } from "../../../factories/extension-context";
|
||||
import { createDbConfig } from "../../../factories/db-config-factories";
|
||||
import { mockConfiguration } from "../../utils/configuration-helpers";
|
||||
|
||||
describe("db panel rendering nodes", () => {
|
||||
const workspaceStoragePath = join(__dirname, "test-workspace-storage");
|
||||
@@ -48,238 +49,281 @@ describe("db panel rendering nodes", () => {
|
||||
await remove(workspaceStoragePath);
|
||||
});
|
||||
|
||||
it("should render default remote nodes when the config is empty", async () => {
|
||||
const dbConfig: DbConfig = createDbConfig();
|
||||
|
||||
await saveDbConfig(dbConfig);
|
||||
|
||||
const dbTreeItems = await dbTreeDataProvider.getChildren();
|
||||
|
||||
expect(dbTreeItems).toBeTruthy();
|
||||
const items = dbTreeItems!;
|
||||
expect(items.length).toBe(3);
|
||||
|
||||
checkRemoteSystemDefinedListItem(items[0], 10);
|
||||
checkRemoteSystemDefinedListItem(items[1], 100);
|
||||
checkRemoteSystemDefinedListItem(items[2], 1000);
|
||||
});
|
||||
|
||||
it("should render remote repository list nodes", async () => {
|
||||
const dbConfig: DbConfig = createDbConfig({
|
||||
remoteLists: [
|
||||
{
|
||||
name: "my-list-1",
|
||||
repositories: ["owner1/repo1", "owner1/repo2"],
|
||||
describe("when controller repo is not set", () => {
|
||||
mockConfiguration({
|
||||
values: {
|
||||
"codeQL.variantAnalysis": {
|
||||
controllerRepo: undefined,
|
||||
},
|
||||
{
|
||||
name: "my-list-2",
|
||||
repositories: ["owner1/repo1", "owner2/repo1", "owner2/repo2"],
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
await saveDbConfig(dbConfig);
|
||||
it("should not have any items", async () => {
|
||||
const dbConfig: DbConfig = createDbConfig({
|
||||
remoteLists: [
|
||||
{
|
||||
name: "my-list-1",
|
||||
repositories: ["owner1/repo1", "owner1/repo2"],
|
||||
},
|
||||
{
|
||||
name: "my-list-2",
|
||||
repositories: ["owner2/repo1", "owner2/repo2"],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const dbTreeItems = await dbTreeDataProvider.getChildren();
|
||||
expect(dbTreeItems).toBeTruthy();
|
||||
await saveDbConfig(dbConfig);
|
||||
|
||||
const systemDefinedListItems = dbTreeItems!.filter(
|
||||
(item) => item.dbItem?.kind === DbItemKind.RemoteSystemDefinedList,
|
||||
);
|
||||
expect(systemDefinedListItems.length).toBe(3);
|
||||
const dbTreeItems = await dbTreeDataProvider.getChildren();
|
||||
|
||||
const userDefinedListItems = dbTreeItems!.filter(
|
||||
(item) => item.dbItem?.kind === DbItemKind.RemoteUserDefinedList,
|
||||
);
|
||||
expect(userDefinedListItems.length).toBe(2);
|
||||
checkUserDefinedListItem(userDefinedListItems[0], "my-list-1", [
|
||||
"owner1/repo1",
|
||||
"owner1/repo2",
|
||||
]);
|
||||
checkUserDefinedListItem(userDefinedListItems[1], "my-list-2", [
|
||||
"owner1/repo1",
|
||||
"owner2/repo1",
|
||||
"owner2/repo2",
|
||||
]);
|
||||
expect(dbTreeItems).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
|
||||
it("should render owner list nodes", async () => {
|
||||
const dbConfig: DbConfig = createDbConfig({
|
||||
remoteOwners: ["owner1", "owner2"],
|
||||
describe("when controller repo is set", () => {
|
||||
beforeEach(() => {
|
||||
mockConfiguration({
|
||||
values: {
|
||||
"codeQL.variantAnalysis": {
|
||||
controllerRepo: "github/codeql",
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
await saveDbConfig(dbConfig);
|
||||
it("should render default remote nodes when the config is empty", async () => {
|
||||
const dbConfig: DbConfig = createDbConfig();
|
||||
|
||||
const dbTreeItems = await dbTreeDataProvider.getChildren();
|
||||
expect(dbTreeItems).toBeTruthy();
|
||||
expect(dbTreeItems?.length).toBe(5);
|
||||
await saveDbConfig(dbConfig);
|
||||
|
||||
const ownerListItems = dbTreeItems!.filter(
|
||||
(item) => item.dbItem?.kind === DbItemKind.RemoteOwner,
|
||||
);
|
||||
expect(ownerListItems.length).toBe(2);
|
||||
checkOwnerItem(ownerListItems[0], "owner1");
|
||||
checkOwnerItem(ownerListItems[1], "owner2");
|
||||
});
|
||||
const dbTreeItems = await dbTreeDataProvider.getChildren();
|
||||
|
||||
it("should render repository nodes", async () => {
|
||||
const dbConfig: DbConfig = createDbConfig({
|
||||
remoteRepos: ["owner1/repo1", "owner1/repo2"],
|
||||
expect(dbTreeItems).toBeTruthy();
|
||||
const items = dbTreeItems!;
|
||||
expect(items.length).toBe(3);
|
||||
|
||||
checkRemoteSystemDefinedListItem(items[0], 10);
|
||||
checkRemoteSystemDefinedListItem(items[1], 100);
|
||||
checkRemoteSystemDefinedListItem(items[2], 1000);
|
||||
});
|
||||
|
||||
await saveDbConfig(dbConfig);
|
||||
it("should render remote repository list nodes", async () => {
|
||||
const dbConfig: DbConfig = createDbConfig({
|
||||
remoteLists: [
|
||||
{
|
||||
name: "my-list-1",
|
||||
repositories: ["owner1/repo1", "owner1/repo2"],
|
||||
},
|
||||
{
|
||||
name: "my-list-2",
|
||||
repositories: ["owner1/repo1", "owner2/repo1", "owner2/repo2"],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const dbTreeItems = await dbTreeDataProvider.getChildren();
|
||||
expect(dbTreeItems).toBeTruthy();
|
||||
expect(dbTreeItems!.length).toBe(5);
|
||||
await saveDbConfig(dbConfig);
|
||||
|
||||
const repoItems = dbTreeItems!.filter(
|
||||
(item) => item.dbItem?.kind === DbItemKind.RemoteRepo,
|
||||
);
|
||||
expect(repoItems.length).toBe(2);
|
||||
checkRemoteRepoItem(repoItems[0], "owner1/repo1");
|
||||
checkRemoteRepoItem(repoItems[1], "owner1/repo2");
|
||||
});
|
||||
const dbTreeItems = await dbTreeDataProvider.getChildren();
|
||||
expect(dbTreeItems).toBeTruthy();
|
||||
|
||||
it.skip("should render local list nodes", async () => {
|
||||
const dbConfig: DbConfig = createDbConfig({
|
||||
localLists: [
|
||||
const systemDefinedListItems = dbTreeItems!.filter(
|
||||
(item) => item.dbItem?.kind === DbItemKind.RemoteSystemDefinedList,
|
||||
);
|
||||
expect(systemDefinedListItems.length).toBe(3);
|
||||
|
||||
const userDefinedListItems = dbTreeItems!.filter(
|
||||
(item) => item.dbItem?.kind === DbItemKind.RemoteUserDefinedList,
|
||||
);
|
||||
expect(userDefinedListItems.length).toBe(2);
|
||||
checkUserDefinedListItem(userDefinedListItems[0], "my-list-1", [
|
||||
"owner1/repo1",
|
||||
"owner1/repo2",
|
||||
]);
|
||||
checkUserDefinedListItem(userDefinedListItems[1], "my-list-2", [
|
||||
"owner1/repo1",
|
||||
"owner2/repo1",
|
||||
"owner2/repo2",
|
||||
]);
|
||||
});
|
||||
|
||||
it("should render owner list nodes", async () => {
|
||||
const dbConfig: DbConfig = createDbConfig({
|
||||
remoteOwners: ["owner1", "owner2"],
|
||||
});
|
||||
|
||||
await saveDbConfig(dbConfig);
|
||||
|
||||
const dbTreeItems = await dbTreeDataProvider.getChildren();
|
||||
expect(dbTreeItems).toBeTruthy();
|
||||
expect(dbTreeItems?.length).toBe(5);
|
||||
|
||||
const ownerListItems = dbTreeItems!.filter(
|
||||
(item) => item.dbItem?.kind === DbItemKind.RemoteOwner,
|
||||
);
|
||||
expect(ownerListItems.length).toBe(2);
|
||||
checkOwnerItem(ownerListItems[0], "owner1");
|
||||
checkOwnerItem(ownerListItems[1], "owner2");
|
||||
});
|
||||
|
||||
it("should render repository nodes", async () => {
|
||||
const dbConfig: DbConfig = createDbConfig({
|
||||
remoteRepos: ["owner1/repo1", "owner1/repo2"],
|
||||
});
|
||||
|
||||
await saveDbConfig(dbConfig);
|
||||
|
||||
const dbTreeItems = await dbTreeDataProvider.getChildren();
|
||||
expect(dbTreeItems).toBeTruthy();
|
||||
expect(dbTreeItems!.length).toBe(5);
|
||||
|
||||
const repoItems = dbTreeItems!.filter(
|
||||
(item) => item.dbItem?.kind === DbItemKind.RemoteRepo,
|
||||
);
|
||||
expect(repoItems.length).toBe(2);
|
||||
checkRemoteRepoItem(repoItems[0], "owner1/repo1");
|
||||
checkRemoteRepoItem(repoItems[1], "owner1/repo2");
|
||||
});
|
||||
|
||||
it.skip("should render local list nodes", async () => {
|
||||
const dbConfig: DbConfig = createDbConfig({
|
||||
localLists: [
|
||||
{
|
||||
name: "my-list-1",
|
||||
databases: [
|
||||
{
|
||||
name: "db1",
|
||||
dateAdded: 1668428293677,
|
||||
language: "cpp",
|
||||
storagePath: "/path/to/db1/",
|
||||
},
|
||||
{
|
||||
name: "db2",
|
||||
dateAdded: 1668428472731,
|
||||
language: "cpp",
|
||||
storagePath: "/path/to/db2/",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "my-list-2",
|
||||
databases: [
|
||||
{
|
||||
name: "db3",
|
||||
dateAdded: 1668428472731,
|
||||
language: "ruby",
|
||||
storagePath: "/path/to/db3/",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
await saveDbConfig(dbConfig);
|
||||
|
||||
const dbTreeItems = await dbTreeDataProvider.getChildren();
|
||||
expect(dbTreeItems).toBeTruthy();
|
||||
|
||||
const localRootNode = dbTreeItems?.find(
|
||||
(i) => i.dbItem?.kind === DbItemKind.RootLocal,
|
||||
);
|
||||
expect(localRootNode).toBeTruthy();
|
||||
|
||||
expect(localRootNode!.dbItem).toBeTruthy();
|
||||
expect(localRootNode!.collapsibleState).toBe(
|
||||
TreeItemCollapsibleState.Collapsed,
|
||||
);
|
||||
expect(localRootNode!.children).toBeTruthy();
|
||||
expect(localRootNode!.children.length).toBe(2);
|
||||
|
||||
const localListItems = localRootNode!.children.filter(
|
||||
(item) => item.dbItem?.kind === DbItemKind.LocalList,
|
||||
);
|
||||
expect(localListItems.length).toBe(2);
|
||||
checkLocalListItem(localListItems[0], "my-list-1", [
|
||||
{
|
||||
name: "my-list-1",
|
||||
databases: [
|
||||
{
|
||||
name: "db1",
|
||||
dateAdded: 1668428293677,
|
||||
language: "cpp",
|
||||
storagePath: "/path/to/db1/",
|
||||
},
|
||||
{
|
||||
name: "db2",
|
||||
dateAdded: 1668428472731,
|
||||
language: "cpp",
|
||||
storagePath: "/path/to/db2/",
|
||||
},
|
||||
],
|
||||
kind: DbItemKind.LocalDatabase,
|
||||
databaseName: "db1",
|
||||
dateAdded: 1668428293677,
|
||||
language: "cpp",
|
||||
storagePath: "/path/to/db1/",
|
||||
selected: false,
|
||||
},
|
||||
{
|
||||
name: "my-list-2",
|
||||
databases: [
|
||||
{
|
||||
name: "db3",
|
||||
dateAdded: 1668428472731,
|
||||
language: "ruby",
|
||||
storagePath: "/path/to/db3/",
|
||||
},
|
||||
],
|
||||
kind: DbItemKind.LocalDatabase,
|
||||
databaseName: "db2",
|
||||
dateAdded: 1668428472731,
|
||||
language: "cpp",
|
||||
storagePath: "/path/to/db2/",
|
||||
selected: false,
|
||||
},
|
||||
],
|
||||
]);
|
||||
checkLocalListItem(localListItems[1], "my-list-2", [
|
||||
{
|
||||
kind: DbItemKind.LocalDatabase,
|
||||
databaseName: "db3",
|
||||
dateAdded: 1668428472731,
|
||||
language: "ruby",
|
||||
storagePath: "/path/to/db3/",
|
||||
selected: false,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
await saveDbConfig(dbConfig);
|
||||
it.skip("should render local database nodes", async () => {
|
||||
const dbConfig: DbConfig = createDbConfig({
|
||||
localDbs: [
|
||||
{
|
||||
name: "db1",
|
||||
dateAdded: 1668428293677,
|
||||
language: "csharp",
|
||||
storagePath: "/path/to/db1/",
|
||||
},
|
||||
{
|
||||
name: "db2",
|
||||
dateAdded: 1668428472731,
|
||||
language: "go",
|
||||
storagePath: "/path/to/db2/",
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const dbTreeItems = await dbTreeDataProvider.getChildren();
|
||||
expect(dbTreeItems).toBeTruthy();
|
||||
await saveDbConfig(dbConfig);
|
||||
|
||||
const localRootNode = dbTreeItems?.find(
|
||||
(i) => i.dbItem?.kind === DbItemKind.RootLocal,
|
||||
);
|
||||
expect(localRootNode).toBeTruthy();
|
||||
const dbTreeItems = await dbTreeDataProvider.getChildren();
|
||||
|
||||
expect(localRootNode!.dbItem).toBeTruthy();
|
||||
expect(localRootNode!.collapsibleState).toBe(
|
||||
TreeItemCollapsibleState.Collapsed,
|
||||
);
|
||||
expect(localRootNode!.children).toBeTruthy();
|
||||
expect(localRootNode!.children.length).toBe(2);
|
||||
expect(dbTreeItems).toBeTruthy();
|
||||
const localRootNode = dbTreeItems?.find(
|
||||
(i) => i.dbItem?.kind === DbItemKind.RootLocal,
|
||||
);
|
||||
expect(localRootNode).toBeTruthy();
|
||||
|
||||
const localListItems = localRootNode!.children.filter(
|
||||
(item) => item.dbItem?.kind === DbItemKind.LocalList,
|
||||
);
|
||||
expect(localListItems.length).toBe(2);
|
||||
checkLocalListItem(localListItems[0], "my-list-1", [
|
||||
{
|
||||
expect(localRootNode!.dbItem).toBeTruthy();
|
||||
expect(localRootNode!.collapsibleState).toBe(
|
||||
TreeItemCollapsibleState.Collapsed,
|
||||
);
|
||||
expect(localRootNode!.children).toBeTruthy();
|
||||
expect(localRootNode!.children.length).toBe(2);
|
||||
|
||||
const localDatabaseItems = localRootNode!.children.filter(
|
||||
(item) => item.dbItem?.kind === DbItemKind.LocalDatabase,
|
||||
);
|
||||
expect(localDatabaseItems.length).toBe(2);
|
||||
checkLocalDatabaseItem(localDatabaseItems[0], {
|
||||
kind: DbItemKind.LocalDatabase,
|
||||
databaseName: "db1",
|
||||
dateAdded: 1668428293677,
|
||||
language: "cpp",
|
||||
language: "csharp",
|
||||
storagePath: "/path/to/db1/",
|
||||
selected: false,
|
||||
},
|
||||
{
|
||||
});
|
||||
checkLocalDatabaseItem(localDatabaseItems[1], {
|
||||
kind: DbItemKind.LocalDatabase,
|
||||
databaseName: "db2",
|
||||
dateAdded: 1668428472731,
|
||||
language: "cpp",
|
||||
language: "go",
|
||||
storagePath: "/path/to/db2/",
|
||||
selected: false,
|
||||
},
|
||||
]);
|
||||
checkLocalListItem(localListItems[1], "my-list-2", [
|
||||
{
|
||||
kind: DbItemKind.LocalDatabase,
|
||||
databaseName: "db3",
|
||||
dateAdded: 1668428472731,
|
||||
language: "ruby",
|
||||
storagePath: "/path/to/db3/",
|
||||
selected: false,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it.skip("should render local database nodes", async () => {
|
||||
const dbConfig: DbConfig = createDbConfig({
|
||||
localDbs: [
|
||||
{
|
||||
name: "db1",
|
||||
dateAdded: 1668428293677,
|
||||
language: "csharp",
|
||||
storagePath: "/path/to/db1/",
|
||||
},
|
||||
{
|
||||
name: "db2",
|
||||
dateAdded: 1668428472731,
|
||||
language: "go",
|
||||
storagePath: "/path/to/db2/",
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
await saveDbConfig(dbConfig);
|
||||
|
||||
const dbTreeItems = await dbTreeDataProvider.getChildren();
|
||||
|
||||
expect(dbTreeItems).toBeTruthy();
|
||||
const localRootNode = dbTreeItems?.find(
|
||||
(i) => i.dbItem?.kind === DbItemKind.RootLocal,
|
||||
);
|
||||
expect(localRootNode).toBeTruthy();
|
||||
|
||||
expect(localRootNode!.dbItem).toBeTruthy();
|
||||
expect(localRootNode!.collapsibleState).toBe(
|
||||
TreeItemCollapsibleState.Collapsed,
|
||||
);
|
||||
expect(localRootNode!.children).toBeTruthy();
|
||||
expect(localRootNode!.children.length).toBe(2);
|
||||
|
||||
const localDatabaseItems = localRootNode!.children.filter(
|
||||
(item) => item.dbItem?.kind === DbItemKind.LocalDatabase,
|
||||
);
|
||||
expect(localDatabaseItems.length).toBe(2);
|
||||
checkLocalDatabaseItem(localDatabaseItems[0], {
|
||||
kind: DbItemKind.LocalDatabase,
|
||||
databaseName: "db1",
|
||||
dateAdded: 1668428293677,
|
||||
language: "csharp",
|
||||
storagePath: "/path/to/db1/",
|
||||
selected: false,
|
||||
});
|
||||
checkLocalDatabaseItem(localDatabaseItems[1], {
|
||||
kind: DbItemKind.LocalDatabase,
|
||||
databaseName: "db2",
|
||||
dateAdded: 1668428472731,
|
||||
language: "go",
|
||||
storagePath: "/path/to/db2/",
|
||||
selected: false,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import { DbTreeViewItem } from "../../../../src/databases/ui/db-tree-view-item";
|
||||
import { ExtensionApp } from "../../../../src/common/vscode/vscode-app";
|
||||
import { createMockExtensionContext } from "../../../factories/extension-context";
|
||||
import { createDbConfig } from "../../../factories/db-config-factories";
|
||||
import { mockConfiguration } from "../../utils/configuration-helpers";
|
||||
|
||||
describe("db panel", () => {
|
||||
const workspaceStoragePath = join(__dirname, "test-workspace-storage");
|
||||
@@ -38,6 +39,14 @@ describe("db panel", () => {
|
||||
|
||||
beforeEach(async () => {
|
||||
await ensureDir(workspaceStoragePath);
|
||||
|
||||
mockConfiguration({
|
||||
values: {
|
||||
"codeQL.variantAnalysis": {
|
||||
controllerRepo: "github/codeql",
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
import { ExtensionApp } from "../../../../src/common/vscode/vscode-app";
|
||||
import { createMockExtensionContext } from "../../../factories/extension-context";
|
||||
import { createDbConfig } from "../../../factories/db-config-factories";
|
||||
import { mockConfiguration } from "../../utils/configuration-helpers";
|
||||
|
||||
describe("db panel selection", () => {
|
||||
const workspaceStoragePath = join(__dirname, "test-workspace-storage");
|
||||
@@ -44,6 +45,14 @@ describe("db panel selection", () => {
|
||||
|
||||
beforeEach(async () => {
|
||||
await ensureDir(workspaceStoragePath);
|
||||
|
||||
mockConfiguration({
|
||||
values: {
|
||||
"codeQL.variantAnalysis": {
|
||||
controllerRepo: "github/codeql",
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
import { workspace } from "vscode";
|
||||
|
||||
type MockConfigurationConfig = {
|
||||
values: {
|
||||
[section: string]: {
|
||||
[scope: string]: any | (() => any);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
export function mockConfiguration(config: MockConfigurationConfig) {
|
||||
const originalGetConfiguration = workspace.getConfiguration;
|
||||
|
||||
jest
|
||||
.spyOn(workspace, "getConfiguration")
|
||||
.mockImplementation((section, scope) => {
|
||||
const configuration = originalGetConfiguration(section, scope);
|
||||
|
||||
return {
|
||||
get(key: string, defaultValue?: unknown) {
|
||||
if (
|
||||
section &&
|
||||
config.values[section] &&
|
||||
config.values[section][key]
|
||||
) {
|
||||
const value = config.values[section][key];
|
||||
return typeof value === "function" ? value() : value;
|
||||
}
|
||||
|
||||
return configuration.get(key, defaultValue);
|
||||
},
|
||||
has(key: string) {
|
||||
return configuration.has(key);
|
||||
},
|
||||
inspect(key: string) {
|
||||
return configuration.inspect(key);
|
||||
},
|
||||
update(
|
||||
key: string,
|
||||
value: unknown,
|
||||
configurationTarget?: boolean,
|
||||
overrideInLanguage?: boolean,
|
||||
) {
|
||||
return configuration.update(
|
||||
key,
|
||||
value,
|
||||
configurationTarget,
|
||||
overrideInLanguage,
|
||||
);
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user