Merge pull request #1989 from github/robertbrignull/credentials_in_app
Add credentials to App
This commit is contained in:
Коммит
ad6cbe60fd
|
@ -1,6 +1,7 @@
|
|||
import * as vscode from "vscode";
|
||||
import * as Octokit from "@octokit/rest";
|
||||
import { retry } from "@octokit/plugin-retry";
|
||||
import { Credentials } from "./common/authentication";
|
||||
|
||||
const GITHUB_AUTH_PROVIDER_ID = "github";
|
||||
|
||||
|
@ -13,41 +14,12 @@ const SCOPES = ["repo", "gist", "read:packages"];
|
|||
/**
|
||||
* Handles authentication to GitHub, using the VS Code [authentication API](https://code.visualstudio.com/api/references/vscode-api#authentication).
|
||||
*/
|
||||
export class Credentials {
|
||||
export class VSCodeCredentials implements Credentials {
|
||||
/**
|
||||
* A specific octokit to return, otherwise a new authenticated octokit will be created when needed.
|
||||
*/
|
||||
private octokit: Octokit.Octokit | undefined;
|
||||
|
||||
// Explicitly make the constructor private, so that we can't accidentally call the constructor from outside the class
|
||||
// without also initializing the class.
|
||||
private constructor(octokit?: Octokit.Octokit) {
|
||||
this.octokit = octokit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a Credentials instance. This will generate octokit instances
|
||||
* authenticated as the user. If there is not already an authenticated GitHub
|
||||
* session available then the user will be prompted to log in.
|
||||
*
|
||||
* @returns An instance of credentials.
|
||||
*/
|
||||
static async initialize(): Promise<Credentials> {
|
||||
return new Credentials();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes an instance of credentials with an octokit instance using
|
||||
* a specific known token. This method is meant to be used in
|
||||
* non-interactive environments such as tests.
|
||||
*
|
||||
* @param overrideToken The GitHub token to use for authentication.
|
||||
* @returns An instance of credentials.
|
||||
*/
|
||||
static async initializeWithToken(overrideToken: string) {
|
||||
return new Credentials(new Octokit.Octokit({ auth: overrideToken, retry }));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates or returns an instance of Octokit.
|
||||
*
|
||||
|
|
|
@ -27,7 +27,7 @@ import { Logger, ProgressReporter } from "./common";
|
|||
import { CompilationMessage } from "./pure/legacy-messages";
|
||||
import { sarifParser } from "./sarif-parser";
|
||||
import { dbSchemeToLanguage, walkDirectory } from "./helpers";
|
||||
import { Credentials } from "./authentication";
|
||||
import { App } from "./common/app";
|
||||
|
||||
/**
|
||||
* The version of the SARIF format that we are using.
|
||||
|
@ -197,6 +197,7 @@ export class CodeQLCliServer implements Disposable {
|
|||
public quiet = false;
|
||||
|
||||
constructor(
|
||||
private readonly app: App,
|
||||
private distributionProvider: DistributionProvider,
|
||||
private cliConfig: CliConfig,
|
||||
private logger: Logger,
|
||||
|
@ -618,9 +619,7 @@ export class CodeQLCliServer implements Disposable {
|
|||
addFormat = true,
|
||||
progressReporter?: ProgressReporter,
|
||||
): Promise<OutputType> {
|
||||
const credentials = await Credentials.initialize();
|
||||
|
||||
const accessToken = await credentials.getExistingAccessToken();
|
||||
const accessToken = await this.app.credentials.getExistingAccessToken();
|
||||
|
||||
const extraArgs = accessToken ? ["--github-auth-stdin"] : [];
|
||||
|
||||
|
@ -633,7 +632,7 @@ export class CodeQLCliServer implements Disposable {
|
|||
async (line) => {
|
||||
if (line.startsWith("Enter value for --github-auth-stdin")) {
|
||||
try {
|
||||
return await credentials.getAccessToken();
|
||||
return await this.app.credentials.getAccessToken();
|
||||
} catch (e) {
|
||||
// If the user cancels the authentication prompt, we still need to give a value to the CLI.
|
||||
// By giving a potentially invalid value, the user will just get a 401/403 when they try to access a
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { Credentials } from "./authentication";
|
||||
import { Disposable } from "../pure/disposable-object";
|
||||
import { AppEventEmitter } from "./events";
|
||||
import { Logger } from "./logging";
|
||||
|
@ -13,6 +14,7 @@ export interface App {
|
|||
readonly globalStoragePath: string;
|
||||
readonly workspaceStoragePath?: string;
|
||||
readonly workspaceState: Memento;
|
||||
readonly credentials: Credentials;
|
||||
}
|
||||
|
||||
export enum AppMode {
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
import * as Octokit from "@octokit/rest";
|
||||
|
||||
/**
|
||||
* An interface providing methods for obtaining access tokens
|
||||
* or an octokit instance for making HTTP requests.
|
||||
*/
|
||||
export interface Credentials {
|
||||
/**
|
||||
* Returns an authenticated instance of Octokit.
|
||||
* May prompt the user to log in and grant permission to use their
|
||||
* token, if they have not already done so.
|
||||
*
|
||||
* @returns An instance of Octokit.
|
||||
*/
|
||||
getOctokit(): Promise<Octokit.Octokit>;
|
||||
|
||||
/**
|
||||
* Returns an OAuth access token.
|
||||
* May prompt the user to log in and grant permission to use their
|
||||
* token, if they have not already done so.
|
||||
*
|
||||
* @returns An OAuth access token.
|
||||
*/
|
||||
getAccessToken(): Promise<string>;
|
||||
|
||||
/**
|
||||
* Returns an OAuth access token if one is available.
|
||||
* If a token is not available this will return undefined and
|
||||
* will not prompt the user to log in.
|
||||
*
|
||||
* @returns An OAuth access token, or undefined.
|
||||
*/
|
||||
getExistingAccessToken(): Promise<string | undefined>;
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
import * as vscode from "vscode";
|
||||
import { VSCodeCredentials } from "../../authentication";
|
||||
import { Disposable } from "../../pure/disposable-object";
|
||||
import { App, AppMode } from "../app";
|
||||
import { AppEventEmitter } from "../events";
|
||||
|
@ -7,9 +8,13 @@ import { Memento } from "../memento";
|
|||
import { VSCodeAppEventEmitter } from "./events";
|
||||
|
||||
export class ExtensionApp implements App {
|
||||
public readonly credentials: VSCodeCredentials;
|
||||
|
||||
public constructor(
|
||||
public readonly extensionContext: vscode.ExtensionContext,
|
||||
) {}
|
||||
) {
|
||||
this.credentials = new VSCodeCredentials();
|
||||
}
|
||||
|
||||
public get extensionPath(): string {
|
||||
return this.extensionContext.extensionPath;
|
||||
|
|
|
@ -20,12 +20,12 @@ import { DatabaseManager, DatabaseItem } from "./databases";
|
|||
import { showAndLogInformationMessage, tmpDir } from "./helpers";
|
||||
import { reportStreamProgress, ProgressCallback } from "./commandRunner";
|
||||
import { extLogger } from "./common";
|
||||
import { Credentials } from "./authentication";
|
||||
import { getErrorMessage } from "./pure/helpers-pure";
|
||||
import {
|
||||
getNwoFromGitHubUrl,
|
||||
isValidGitHubNwo,
|
||||
} from "./common/github-url-identifier-helper";
|
||||
import { Credentials } from "./common/authentication";
|
||||
|
||||
/**
|
||||
* Prompts a user to fetch a database from a remote location. Database is assumed to be an archive file.
|
||||
|
|
|
@ -35,9 +35,10 @@ import {
|
|||
promptImportInternetDatabase,
|
||||
} from "./databaseFetcher";
|
||||
import { asyncFilter, getErrorMessage } from "./pure/helpers-pure";
|
||||
import { Credentials } from "./authentication";
|
||||
import { QueryRunner } from "./queryRunner";
|
||||
import { isCanary } from "./config";
|
||||
import { App } from "./common/app";
|
||||
import { Credentials } from "./common/authentication";
|
||||
|
||||
type ThemableIconPath = { light: string; dark: string } | string;
|
||||
|
||||
|
@ -220,11 +221,11 @@ export class DatabaseUI extends DisposableObject {
|
|||
private treeDataProvider: DatabaseTreeDataProvider;
|
||||
|
||||
public constructor(
|
||||
private app: App,
|
||||
private databaseManager: DatabaseManager,
|
||||
private readonly queryServer: QueryRunner | undefined,
|
||||
private readonly storagePath: string,
|
||||
readonly extensionPath: string,
|
||||
private readonly getCredentials: () => Promise<Credentials>,
|
||||
) {
|
||||
super();
|
||||
|
||||
|
@ -297,9 +298,7 @@ export class DatabaseUI extends DisposableObject {
|
|||
commandRunnerWithProgress(
|
||||
"codeQLDatabases.chooseDatabaseGithub",
|
||||
async (progress: ProgressCallback, token: CancellationToken) => {
|
||||
const credentials = isCanary()
|
||||
? await this.getCredentials()
|
||||
: undefined;
|
||||
const credentials = isCanary() ? this.app.credentials : undefined;
|
||||
await this.handleChooseDatabaseGithub(credentials, progress, token);
|
||||
},
|
||||
{
|
||||
|
|
|
@ -102,7 +102,6 @@ import {
|
|||
} from "./commandRunner";
|
||||
import { CodeQlStatusBarHandler } from "./status-bar";
|
||||
|
||||
import { Credentials } from "./authentication";
|
||||
import { RemoteQueriesManager } from "./remote-queries/remote-queries-manager";
|
||||
import { RemoteQueryResult } from "./remote-queries/remote-query-result";
|
||||
import { URLSearchParams } from "url";
|
||||
|
@ -546,6 +545,8 @@ async function activateWithInstalledDistribution(
|
|||
// of activation.
|
||||
errorStubs.forEach((stub) => stub.dispose());
|
||||
|
||||
const app = new ExtensionApp(ctx);
|
||||
|
||||
void extLogger.log("Initializing configuration listener...");
|
||||
const qlConfigurationListener =
|
||||
await QueryServerConfigListener.createQueryServerConfigListener(
|
||||
|
@ -555,6 +556,7 @@ async function activateWithInstalledDistribution(
|
|||
|
||||
void extLogger.log("Initializing CodeQL cli server...");
|
||||
const cliServer = new CodeQLCliServer(
|
||||
app,
|
||||
distributionManager,
|
||||
new CliConfigListener(),
|
||||
extLogger,
|
||||
|
@ -587,11 +589,11 @@ async function activateWithInstalledDistribution(
|
|||
ctx.subscriptions.push(dbm);
|
||||
void extLogger.log("Initializing database panel.");
|
||||
const databaseUI = new DatabaseUI(
|
||||
app,
|
||||
dbm,
|
||||
qs,
|
||||
getContextStoragePath(ctx),
|
||||
ctx.extensionPath,
|
||||
() => Credentials.initialize(),
|
||||
);
|
||||
databaseUI.init();
|
||||
ctx.subscriptions.push(databaseUI);
|
||||
|
@ -623,8 +625,6 @@ async function activateWithInstalledDistribution(
|
|||
|
||||
void extLogger.log("Initializing variant analysis manager.");
|
||||
|
||||
const app = new ExtensionApp(ctx);
|
||||
|
||||
const dbModule = await DbModule.initialize(app);
|
||||
|
||||
const variantAnalysisStorageDir = join(
|
||||
|
@ -633,12 +633,14 @@ async function activateWithInstalledDistribution(
|
|||
);
|
||||
await ensureDir(variantAnalysisStorageDir);
|
||||
const variantAnalysisResultsManager = new VariantAnalysisResultsManager(
|
||||
app.credentials,
|
||||
cliServer,
|
||||
extLogger,
|
||||
);
|
||||
|
||||
const variantAnalysisManager = new VariantAnalysisManager(
|
||||
ctx,
|
||||
app,
|
||||
cliServer,
|
||||
variantAnalysisStorageDir,
|
||||
variantAnalysisResultsManager,
|
||||
|
@ -656,6 +658,7 @@ async function activateWithInstalledDistribution(
|
|||
void extLogger.log("Initializing remote queries manager.");
|
||||
const rqm = new RemoteQueriesManager(
|
||||
ctx,
|
||||
app,
|
||||
cliServer,
|
||||
queryStorageDir,
|
||||
extLogger,
|
||||
|
@ -664,6 +667,7 @@ async function activateWithInstalledDistribution(
|
|||
|
||||
void extLogger.log("Initializing query history.");
|
||||
const qhm = new QueryHistoryManager(
|
||||
app,
|
||||
qs,
|
||||
dbm,
|
||||
localQueryResultsView,
|
||||
|
@ -1224,7 +1228,7 @@ async function activateWithInstalledDistribution(
|
|||
commandRunner(
|
||||
"codeQL.exportRemoteQueryResults",
|
||||
async (queryId: string) => {
|
||||
await exportRemoteQueryResults(qhm, rqm, queryId);
|
||||
await exportRemoteQueryResults(qhm, rqm, queryId, app.credentials);
|
||||
},
|
||||
),
|
||||
);
|
||||
|
@ -1242,6 +1246,7 @@ async function activateWithInstalledDistribution(
|
|||
variantAnalysisManager,
|
||||
variantAnalysisId,
|
||||
filterSort,
|
||||
app.credentials,
|
||||
progress,
|
||||
token,
|
||||
);
|
||||
|
@ -1342,9 +1347,7 @@ async function activateWithInstalledDistribution(
|
|||
commandRunnerWithProgress(
|
||||
"codeQL.chooseDatabaseGithub",
|
||||
async (progress: ProgressCallback, token: CancellationToken) => {
|
||||
const credentials = isCanary()
|
||||
? await Credentials.initialize()
|
||||
: undefined;
|
||||
const credentials = isCanary() ? app.credentials : undefined;
|
||||
await databaseUI.handleChooseDatabaseGithub(
|
||||
credentials,
|
||||
progress,
|
||||
|
@ -1398,8 +1401,7 @@ async function activateWithInstalledDistribution(
|
|||
* Credentials for authenticating to GitHub.
|
||||
* These are used when making API calls.
|
||||
*/
|
||||
const credentials = await Credentials.initialize();
|
||||
const octokit = await credentials.getOctokit();
|
||||
const octokit = await app.credentials.getOctokit();
|
||||
const userInfo = await octokit.users.getAuthenticated();
|
||||
void showAndLogInformationMessage(
|
||||
`Authenticated to GitHub as user: ${userInfo.data.login}`,
|
||||
|
|
|
@ -56,7 +56,6 @@ import {
|
|||
import { pathExists } from "fs-extra";
|
||||
import { CliVersionConstraint } from "../cli";
|
||||
import { HistoryItemLabelProvider } from "./history-item-label-provider";
|
||||
import { Credentials } from "../authentication";
|
||||
import { cancelRemoteQuery } from "../remote-queries/gh-api/gh-actions-api-client";
|
||||
import { RemoteQueriesManager } from "../remote-queries/remote-queries-manager";
|
||||
import { RemoteQueryHistoryItem } from "../remote-queries/remote-query-history-item";
|
||||
|
@ -70,6 +69,7 @@ import { QueryRunner } from "../queryRunner";
|
|||
import { VariantAnalysisManager } from "../remote-queries/variant-analysis-manager";
|
||||
import { VariantAnalysisHistoryItem } from "./variant-analysis-history-item";
|
||||
import { getTotalResultCount } from "../remote-queries/shared/variant-analysis";
|
||||
import { App } from "../common/app";
|
||||
|
||||
/**
|
||||
* query-history.ts
|
||||
|
@ -362,6 +362,7 @@ export class QueryHistoryManager extends DisposableObject {
|
|||
readonly onDidCompleteQuery = this._onDidCompleteQuery.event;
|
||||
|
||||
constructor(
|
||||
private readonly app: App,
|
||||
private readonly qs: QueryRunner,
|
||||
private readonly dbm: DatabaseManager,
|
||||
private readonly localQueriesResultsView: ResultsView,
|
||||
|
@ -604,10 +605,6 @@ export class QueryHistoryManager extends DisposableObject {
|
|||
this._onDidCompleteQuery.fire(info);
|
||||
}
|
||||
|
||||
private getCredentials() {
|
||||
return Credentials.initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register and create the history scrubber.
|
||||
*/
|
||||
|
@ -1314,8 +1311,7 @@ export class QueryHistoryManager extends DisposableObject {
|
|||
void showAndLogInformationMessage(
|
||||
"Cancelling variant analysis. This may take a while.",
|
||||
);
|
||||
const credentials = await this.getCredentials();
|
||||
await cancelRemoteQuery(credentials, item.remoteQuery);
|
||||
await cancelRemoteQuery(this.app.credentials, item.remoteQuery);
|
||||
} else if (item.t === "variant-analysis") {
|
||||
await commands.executeCommand(
|
||||
"codeQL.cancelVariantAnalysis",
|
||||
|
|
|
@ -3,7 +3,6 @@ import { EOL } from "os";
|
|||
import { extname } from "path";
|
||||
import { CancellationToken } from "vscode";
|
||||
|
||||
import { Credentials } from "../authentication";
|
||||
import { Logger } from "../common";
|
||||
import { downloadArtifactFromLink } from "./gh-api/gh-actions-api-client";
|
||||
import { AnalysisSummary } from "./shared/remote-query-result";
|
||||
|
@ -19,6 +18,7 @@ import { CodeQLCliServer } from "../cli";
|
|||
import { extractRawResults } from "./bqrs-processing";
|
||||
import { asyncFilter, getErrorMessage } from "../pure/helpers-pure";
|
||||
import { createDownloadPath } from "./download-link";
|
||||
import { App } from "../common/app";
|
||||
|
||||
export class AnalysesResultsManager {
|
||||
// Store for the results of various analyses for each remote query.
|
||||
|
@ -26,6 +26,7 @@ export class AnalysesResultsManager {
|
|||
private readonly analysesResults: Map<string, AnalysisResults[]>;
|
||||
|
||||
constructor(
|
||||
private readonly app: App,
|
||||
private readonly cliServer: CodeQLCliServer,
|
||||
readonly storagePath: string,
|
||||
private readonly logger: Logger,
|
||||
|
@ -42,17 +43,11 @@ export class AnalysesResultsManager {
|
|||
return;
|
||||
}
|
||||
|
||||
const credentials = await Credentials.initialize();
|
||||
|
||||
void this.logger.log(
|
||||
`Downloading and processing results for ${analysisSummary.nwo}`,
|
||||
);
|
||||
|
||||
await this.downloadSingleAnalysisResults(
|
||||
analysisSummary,
|
||||
credentials,
|
||||
publishResults,
|
||||
);
|
||||
await this.downloadSingleAnalysisResults(analysisSummary, publishResults);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -76,8 +71,6 @@ export class AnalysesResultsManager {
|
|||
(x) => !this.isAnalysisInMemory(x),
|
||||
);
|
||||
|
||||
const credentials = await Credentials.initialize();
|
||||
|
||||
void this.logger.log("Downloading and processing analyses results");
|
||||
|
||||
const batchSize = 3;
|
||||
|
@ -94,11 +87,7 @@ export class AnalysesResultsManager {
|
|||
|
||||
const batch = analysesToDownload.slice(i, i + batchSize);
|
||||
const batchTasks = batch.map((analysis) =>
|
||||
this.downloadSingleAnalysisResults(
|
||||
analysis,
|
||||
credentials,
|
||||
publishResults,
|
||||
),
|
||||
this.downloadSingleAnalysisResults(analysis, publishResults),
|
||||
);
|
||||
|
||||
const nwos = batch.map((a) => a.nwo).join(", ");
|
||||
|
@ -138,7 +127,6 @@ export class AnalysesResultsManager {
|
|||
|
||||
private async downloadSingleAnalysisResults(
|
||||
analysis: AnalysisSummary,
|
||||
credentials: Credentials,
|
||||
publishResults: (analysesResults: AnalysisResults[]) => Promise<void>,
|
||||
): Promise<void> {
|
||||
const analysisResults: AnalysisResults = {
|
||||
|
@ -159,7 +147,7 @@ export class AnalysesResultsManager {
|
|||
let artifactPath;
|
||||
try {
|
||||
artifactPath = await downloadArtifactFromLink(
|
||||
credentials,
|
||||
this.app.credentials,
|
||||
this.storagePath,
|
||||
analysis.downloadLink,
|
||||
);
|
||||
|
|
|
@ -9,7 +9,6 @@ import {
|
|||
window,
|
||||
workspace,
|
||||
} from "vscode";
|
||||
import { Credentials } from "../authentication";
|
||||
import { ProgressCallback, UserCancellationException } from "../commandRunner";
|
||||
import { showInformationMessageWithAction } from "../helpers";
|
||||
import { extLogger } from "../common";
|
||||
|
@ -37,6 +36,7 @@ import {
|
|||
filterAndSortRepositoriesWithResults,
|
||||
RepositoriesFilterSortStateWithIds,
|
||||
} from "../pure/variant-analysis-filter-sort";
|
||||
import { Credentials } from "../common/authentication";
|
||||
|
||||
/**
|
||||
* Exports the results of the currently-selected remote query or variant analysis.
|
||||
|
@ -74,6 +74,7 @@ export async function exportRemoteQueryResults(
|
|||
queryHistoryManager: QueryHistoryManager,
|
||||
remoteQueriesManager: RemoteQueriesManager,
|
||||
queryId: string,
|
||||
credentials: Credentials,
|
||||
): Promise<void> {
|
||||
const queryHistoryItem = queryHistoryManager.getRemoteQueryById(queryId);
|
||||
if (!queryHistoryItem) {
|
||||
|
@ -109,6 +110,7 @@ export async function exportRemoteQueryResults(
|
|||
query,
|
||||
analysesResults,
|
||||
exportFormat,
|
||||
credentials,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -117,6 +119,7 @@ export async function exportRemoteQueryAnalysisResults(
|
|||
query: RemoteQuery,
|
||||
analysesResults: AnalysisResults[],
|
||||
exportFormat: "gist" | "local",
|
||||
credentials: Credentials,
|
||||
) {
|
||||
const description = buildGistDescription(query, analysesResults);
|
||||
const markdownFiles = generateMarkdown(query, analysesResults, exportFormat);
|
||||
|
@ -126,6 +129,7 @@ export async function exportRemoteQueryAnalysisResults(
|
|||
description,
|
||||
markdownFiles,
|
||||
exportFormat,
|
||||
credentials,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -139,6 +143,7 @@ export async function exportVariantAnalysisResults(
|
|||
variantAnalysisManager: VariantAnalysisManager,
|
||||
variantAnalysisId: number,
|
||||
filterSort: RepositoriesFilterSortStateWithIds | undefined,
|
||||
credentials: Credentials,
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
): Promise<void> {
|
||||
|
@ -238,6 +243,7 @@ export async function exportVariantAnalysisResults(
|
|||
getAnalysesResults(),
|
||||
repositories?.length ?? 0,
|
||||
exportFormat,
|
||||
credentials,
|
||||
progress,
|
||||
token,
|
||||
);
|
||||
|
@ -251,6 +257,7 @@ export async function exportVariantAnalysisAnalysisResults(
|
|||
>,
|
||||
expectedAnalysesResultsCount: number,
|
||||
exportFormat: "gist" | "local",
|
||||
credentials: Credentials,
|
||||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
) {
|
||||
|
@ -280,6 +287,7 @@ export async function exportVariantAnalysisAnalysisResults(
|
|||
description,
|
||||
markdownFiles,
|
||||
exportFormat,
|
||||
credentials,
|
||||
progress,
|
||||
token,
|
||||
);
|
||||
|
@ -323,6 +331,7 @@ export async function exportResults(
|
|||
description: string,
|
||||
markdownFiles: MarkdownFile[],
|
||||
exportFormat: "gist" | "local",
|
||||
credentials: Credentials,
|
||||
progress?: ProgressCallback,
|
||||
token?: CancellationToken,
|
||||
) {
|
||||
|
@ -331,7 +340,13 @@ export async function exportResults(
|
|||
}
|
||||
|
||||
if (exportFormat === "gist") {
|
||||
await exportToGist(description, markdownFiles, progress, token);
|
||||
await exportToGist(
|
||||
description,
|
||||
markdownFiles,
|
||||
credentials,
|
||||
progress,
|
||||
token,
|
||||
);
|
||||
} else if (exportFormat === "local") {
|
||||
await exportToLocalMarkdown(
|
||||
exportedResultsPath,
|
||||
|
@ -345,6 +360,7 @@ export async function exportResults(
|
|||
export async function exportToGist(
|
||||
description: string,
|
||||
markdownFiles: MarkdownFile[],
|
||||
credentials: Credentials,
|
||||
progress?: ProgressCallback,
|
||||
token?: CancellationToken,
|
||||
) {
|
||||
|
@ -354,8 +370,6 @@ export async function exportToGist(
|
|||
message: "Creating Gist",
|
||||
});
|
||||
|
||||
const credentials = await Credentials.initialize();
|
||||
|
||||
if (token?.isCancellationRequested) {
|
||||
throw new UserCancellationException("Cancelled");
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import {
|
|||
showAndLogWarningMessage,
|
||||
tmpDir,
|
||||
} from "../../helpers";
|
||||
import { Credentials } from "../../authentication";
|
||||
import { Credentials } from "../../common/authentication";
|
||||
import { extLogger } from "../../common";
|
||||
import { RemoteQueryWorkflowResult } from "../remote-query-workflow-result";
|
||||
import { DownloadLink, createDownloadPath } from "../download-link";
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Credentials } from "../../authentication";
|
||||
import { OctokitResponse } from "@octokit/types/dist-types";
|
||||
import { Credentials } from "../../common/authentication";
|
||||
import { RemoteQueriesSubmission } from "../shared/remote-queries";
|
||||
import { VariantAnalysisSubmission } from "../shared/variant-analysis";
|
||||
import {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { EOL } from "os";
|
||||
import { Credentials } from "../authentication";
|
||||
import { Credentials } from "../common/authentication";
|
||||
import { RepositorySelection } from "./repository-selection";
|
||||
import { Repository } from "./shared/repository";
|
||||
import { RemoteQueriesResponse } from "./gh-api/remote-queries";
|
||||
|
|
|
@ -11,7 +11,6 @@ import { join } from "path";
|
|||
import { writeFile, readFile, remove, pathExists } from "fs-extra";
|
||||
import { EOL } from "os";
|
||||
|
||||
import { Credentials } from "../authentication";
|
||||
import { CodeQLCliServer } from "../cli";
|
||||
import { ProgressCallback } from "../commandRunner";
|
||||
import {
|
||||
|
@ -42,6 +41,7 @@ import { QueryStatus } from "../query-status";
|
|||
import { DisposableObject } from "../pure/disposable-object";
|
||||
import { AnalysisResults } from "./shared/analysis-result";
|
||||
import { runRemoteQueriesApiRequest } from "./remote-queries-api";
|
||||
import { App } from "../common/app";
|
||||
|
||||
const autoDownloadMaxSize = 300 * 1024;
|
||||
const autoDownloadMaxCount = 100;
|
||||
|
@ -82,12 +82,14 @@ export class RemoteQueriesManager extends DisposableObject {
|
|||
|
||||
constructor(
|
||||
ctx: ExtensionContext,
|
||||
private readonly app: App,
|
||||
private readonly cliServer: CodeQLCliServer,
|
||||
private readonly storagePath: string,
|
||||
logger: Logger,
|
||||
) {
|
||||
super();
|
||||
this.analysesResultsManager = new AnalysesResultsManager(
|
||||
app,
|
||||
cliServer,
|
||||
storagePath,
|
||||
logger,
|
||||
|
@ -159,8 +161,6 @@ export class RemoteQueriesManager extends DisposableObject {
|
|||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
): Promise<void> {
|
||||
const credentials = await Credentials.initialize();
|
||||
|
||||
const {
|
||||
actionBranch,
|
||||
base64Pack,
|
||||
|
@ -172,14 +172,14 @@ export class RemoteQueriesManager extends DisposableObject {
|
|||
language,
|
||||
} = await prepareRemoteQueryRun(
|
||||
this.cliServer,
|
||||
credentials,
|
||||
this.app.credentials,
|
||||
uri,
|
||||
progress,
|
||||
token,
|
||||
);
|
||||
|
||||
const apiResponse = await runRemoteQueriesApiRequest(
|
||||
credentials,
|
||||
this.app.credentials,
|
||||
actionBranch,
|
||||
language,
|
||||
repoSelection,
|
||||
|
@ -217,10 +217,9 @@ export class RemoteQueriesManager extends DisposableObject {
|
|||
remoteQuery: RemoteQuery,
|
||||
cancellationToken: CancellationToken,
|
||||
): Promise<void> {
|
||||
const credentials = await Credentials.initialize();
|
||||
|
||||
const queryWorkflowResult = await this.remoteQueriesMonitor.monitorQuery(
|
||||
remoteQuery,
|
||||
this.app.credentials,
|
||||
cancellationToken,
|
||||
);
|
||||
|
||||
|
@ -230,7 +229,6 @@ export class RemoteQueriesManager extends DisposableObject {
|
|||
await this.downloadAvailableResults(
|
||||
queryId,
|
||||
remoteQuery,
|
||||
credentials,
|
||||
executionEndTime,
|
||||
);
|
||||
} else if (queryWorkflowResult.status === "CompletedUnsuccessfully") {
|
||||
|
@ -244,7 +242,6 @@ export class RemoteQueriesManager extends DisposableObject {
|
|||
await this.downloadAvailableResults(
|
||||
queryId,
|
||||
remoteQuery,
|
||||
credentials,
|
||||
executionEndTime,
|
||||
);
|
||||
void showAndLogInformationMessage("Variant analysis was cancelled");
|
||||
|
@ -267,7 +264,6 @@ export class RemoteQueriesManager extends DisposableObject {
|
|||
await this.downloadAvailableResults(
|
||||
queryId,
|
||||
remoteQuery,
|
||||
credentials,
|
||||
executionEndTime,
|
||||
);
|
||||
void showAndLogInformationMessage("Variant analysis was cancelled");
|
||||
|
@ -444,15 +440,14 @@ export class RemoteQueriesManager extends DisposableObject {
|
|||
private async downloadAvailableResults(
|
||||
queryId: string,
|
||||
remoteQuery: RemoteQuery,
|
||||
credentials: Credentials,
|
||||
executionEndTime: number,
|
||||
): Promise<void> {
|
||||
const resultIndex = await getRemoteQueryIndex(credentials, remoteQuery);
|
||||
const resultIndex = await getRemoteQueryIndex(
|
||||
this.app.credentials,
|
||||
remoteQuery,
|
||||
);
|
||||
if (resultIndex) {
|
||||
const metadata = await this.getRepositoriesMetadata(
|
||||
resultIndex,
|
||||
credentials,
|
||||
);
|
||||
const metadata = await this.getRepositoriesMetadata(resultIndex);
|
||||
const queryResult = this.mapQueryResult(
|
||||
executionEndTime,
|
||||
resultIndex,
|
||||
|
@ -494,12 +489,9 @@ export class RemoteQueriesManager extends DisposableObject {
|
|||
}
|
||||
}
|
||||
|
||||
private async getRepositoriesMetadata(
|
||||
resultIndex: RemoteQueryResultIndex,
|
||||
credentials: Credentials,
|
||||
) {
|
||||
private async getRepositoriesMetadata(resultIndex: RemoteQueryResultIndex) {
|
||||
const nwos = resultIndex.successes.map((s) => s.nwo);
|
||||
return await getRepositoriesMetadata(credentials, nwos);
|
||||
return await getRepositoriesMetadata(this.app.credentials, nwos);
|
||||
}
|
||||
|
||||
// Pulled from the analysis results manager, so that we can get access to
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import * as vscode from "vscode";
|
||||
import { Credentials } from "../authentication";
|
||||
import { Logger } from "../common";
|
||||
import { Credentials } from "../common/authentication";
|
||||
import { sleep } from "../pure/time";
|
||||
import {
|
||||
getWorkflowStatus,
|
||||
|
@ -20,10 +20,9 @@ export class RemoteQueriesMonitor {
|
|||
|
||||
public async monitorQuery(
|
||||
remoteQuery: RemoteQuery,
|
||||
credentials: Credentials,
|
||||
cancellationToken: vscode.CancellationToken,
|
||||
): Promise<RemoteQueryWorkflowResult> {
|
||||
const credentials = await Credentials.initialize();
|
||||
|
||||
let attemptCount = 0;
|
||||
|
||||
while (attemptCount <= RemoteQueriesMonitor.maxAttemptCount) {
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
tryGetQueryMetadata,
|
||||
tmpDir,
|
||||
} from "../helpers";
|
||||
import { Credentials } from "../authentication";
|
||||
import { Credentials } from "../common/authentication";
|
||||
import * as cli from "../cli";
|
||||
import { extLogger } from "../common";
|
||||
import {
|
||||
|
|
|
@ -16,7 +16,6 @@ import {
|
|||
workspace,
|
||||
} from "vscode";
|
||||
import { DisposableObject } from "../pure/disposable-object";
|
||||
import { Credentials } from "../authentication";
|
||||
import { VariantAnalysisMonitor } from "./variant-analysis-monitor";
|
||||
import {
|
||||
getActionsWorkflowRunUrl,
|
||||
|
@ -62,6 +61,7 @@ import {
|
|||
import { URLSearchParams } from "url";
|
||||
import { DbManager } from "../databases/db-manager";
|
||||
import { isVariantAnalysisReposPanelEnabled } from "../config";
|
||||
import { App } from "../common/app";
|
||||
|
||||
export class VariantAnalysisManager
|
||||
extends DisposableObject
|
||||
|
@ -100,6 +100,7 @@ export class VariantAnalysisManager
|
|||
|
||||
constructor(
|
||||
private readonly ctx: ExtensionContext,
|
||||
private readonly app: App,
|
||||
private readonly cliServer: CodeQLCliServer,
|
||||
private readonly storagePath: string,
|
||||
private readonly variantAnalysisResultsManager: VariantAnalysisResultsManager,
|
||||
|
@ -126,8 +127,6 @@ export class VariantAnalysisManager
|
|||
progress: ProgressCallback,
|
||||
token: CancellationToken,
|
||||
): Promise<void> {
|
||||
const credentials = await Credentials.initialize();
|
||||
|
||||
const {
|
||||
actionBranch,
|
||||
base64Pack,
|
||||
|
@ -139,7 +138,7 @@ export class VariantAnalysisManager
|
|||
language,
|
||||
} = await prepareRemoteQueryRun(
|
||||
this.cliServer,
|
||||
credentials,
|
||||
this.app.credentials,
|
||||
uri,
|
||||
progress,
|
||||
token,
|
||||
|
@ -175,7 +174,7 @@ export class VariantAnalysisManager
|
|||
};
|
||||
|
||||
const variantAnalysisResponse = await submitVariantAnalysis(
|
||||
credentials,
|
||||
this.app.credentials,
|
||||
variantAnalysisSubmission,
|
||||
);
|
||||
|
||||
|
@ -456,6 +455,7 @@ export class VariantAnalysisManager
|
|||
): Promise<void> {
|
||||
await this.variantAnalysisMonitor.monitorVariantAnalysis(
|
||||
variantAnalysis,
|
||||
this.app.credentials,
|
||||
cancellationToken,
|
||||
);
|
||||
}
|
||||
|
@ -480,8 +480,6 @@ export class VariantAnalysisManager
|
|||
|
||||
await this.onRepoStateUpdated(variantAnalysis.id, repoState);
|
||||
|
||||
const credentials = await Credentials.initialize();
|
||||
|
||||
if (cancellationToken && cancellationToken.isCancellationRequested) {
|
||||
repoState.downloadStatus =
|
||||
VariantAnalysisScannedRepositoryDownloadStatus.Failed;
|
||||
|
@ -492,7 +490,7 @@ export class VariantAnalysisManager
|
|||
let repoTask: VariantAnalysisRepositoryTask;
|
||||
try {
|
||||
const repoTaskResponse = await getVariantAnalysisRepo(
|
||||
credentials,
|
||||
this.app.credentials,
|
||||
variantAnalysis.controllerRepo.id,
|
||||
variantAnalysis.id,
|
||||
scannedRepo.repository.id,
|
||||
|
@ -517,7 +515,6 @@ export class VariantAnalysisManager
|
|||
|
||||
try {
|
||||
await this.variantAnalysisResultsManager.download(
|
||||
credentials,
|
||||
variantAnalysis.id,
|
||||
repoTask,
|
||||
this.getVariantAnalysisStorageLocation(variantAnalysis.id),
|
||||
|
@ -578,12 +575,10 @@ export class VariantAnalysisManager
|
|||
);
|
||||
}
|
||||
|
||||
const credentials = await Credentials.initialize();
|
||||
|
||||
void showAndLogInformationMessage(
|
||||
"Cancelling variant analysis. This may take a while.",
|
||||
);
|
||||
await cancelVariantAnalysis(credentials, variantAnalysis);
|
||||
await cancelVariantAnalysis(this.app.credentials, variantAnalysis);
|
||||
}
|
||||
|
||||
public async openVariantAnalysisLogs(variantAnalysisId: number) {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { CancellationToken, commands, EventEmitter } from "vscode";
|
||||
import { Credentials } from "../authentication";
|
||||
import { getVariantAnalysis } from "./gh-api/gh-api-client";
|
||||
|
||||
import {
|
||||
|
@ -14,6 +13,7 @@ import { DisposableObject } from "../pure/disposable-object";
|
|||
import { sleep } from "../pure/time";
|
||||
import { getErrorMessage } from "../pure/helpers-pure";
|
||||
import { showAndLogWarningMessage } from "../helpers";
|
||||
import { Credentials } from "../common/authentication";
|
||||
|
||||
export class VariantAnalysisMonitor extends DisposableObject {
|
||||
// With a sleep of 5 seconds, the maximum number of attempts takes
|
||||
|
@ -36,10 +36,9 @@ export class VariantAnalysisMonitor extends DisposableObject {
|
|||
|
||||
public async monitorVariantAnalysis(
|
||||
variantAnalysis: VariantAnalysis,
|
||||
credentials: Credentials,
|
||||
cancellationToken: CancellationToken,
|
||||
): Promise<void> {
|
||||
const credentials = await Credentials.initialize();
|
||||
|
||||
let attemptCount = 0;
|
||||
const scannedReposDownloaded: number[] = [];
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import {
|
|||
import { EOL } from "os";
|
||||
import { join } from "path";
|
||||
|
||||
import { Credentials } from "../authentication";
|
||||
import { Credentials } from "../common/authentication";
|
||||
import { Logger } from "../common";
|
||||
import { AnalysisAlert, AnalysisRawResults } from "./shared/analysis-result";
|
||||
import { sarifParser } from "../sarif-parser";
|
||||
|
@ -63,6 +63,7 @@ export class VariantAnalysisResultsManager extends DisposableObject {
|
|||
readonly onResultLoaded = this._onResultLoaded.event;
|
||||
|
||||
constructor(
|
||||
private readonly credentials: Credentials,
|
||||
private readonly cliServer: CodeQLCliServer,
|
||||
private readonly logger: Logger,
|
||||
) {
|
||||
|
@ -71,7 +72,6 @@ export class VariantAnalysisResultsManager extends DisposableObject {
|
|||
}
|
||||
|
||||
public async download(
|
||||
credentials: Credentials,
|
||||
variantAnalysisId: number,
|
||||
repoTask: VariantAnalysisRepositoryTask,
|
||||
variantAnalysisStoragePath: string,
|
||||
|
@ -86,7 +86,7 @@ export class VariantAnalysisResultsManager extends DisposableObject {
|
|||
);
|
||||
|
||||
const result = await getVariantAnalysisRepoResult(
|
||||
credentials,
|
||||
this.credentials,
|
||||
repoTask.artifactUrl,
|
||||
);
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@ import { Memento } from "../../src/common/memento";
|
|||
import { Disposable } from "../../src/pure/disposable-object";
|
||||
import { createMockLogger } from "./loggerMock";
|
||||
import { createMockMemento } from "../mock-memento";
|
||||
import { testCredentialsWithStub } from "../factories/authentication";
|
||||
import { Credentials } from "../../src/common/authentication";
|
||||
|
||||
export function createMockApp({
|
||||
extensionPath = "/mock/extension/path",
|
||||
|
@ -12,6 +14,7 @@ export function createMockApp({
|
|||
createEventEmitter = <T>() => new MockAppEventEmitter<T>(),
|
||||
executeCommand = jest.fn(() => Promise.resolve()),
|
||||
workspaceState = createMockMemento(),
|
||||
credentials = testCredentialsWithStub(),
|
||||
}: {
|
||||
extensionPath?: string;
|
||||
workspaceStoragePath?: string;
|
||||
|
@ -19,6 +22,7 @@ export function createMockApp({
|
|||
createEventEmitter?: <T>() => AppEventEmitter<T>;
|
||||
executeCommand?: () => Promise<void>;
|
||||
workspaceState?: Memento;
|
||||
credentials?: Credentials;
|
||||
}): App {
|
||||
return {
|
||||
mode: AppMode.Test,
|
||||
|
@ -30,6 +34,7 @@ export function createMockApp({
|
|||
workspaceState,
|
||||
createEventEmitter,
|
||||
executeCommand,
|
||||
credentials,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
import { retry } from "@octokit/plugin-retry";
|
||||
import * as Octokit from "@octokit/rest";
|
||||
import { RequestInterface } from "@octokit/types/dist-types/RequestInterface";
|
||||
|
||||
import { Credentials } from "../../src/common/authentication";
|
||||
|
||||
function makeTestOctokit(octokit: Octokit.Octokit): Credentials {
|
||||
return {
|
||||
getOctokit: async () => octokit,
|
||||
getAccessToken: async () => {
|
||||
throw new Error("getAccessToken not supported by test credentials");
|
||||
},
|
||||
getExistingAccessToken: async () => {
|
||||
throw new Error(
|
||||
"getExistingAccessToken not supported by test credentials",
|
||||
);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a Credentials instance that calls a stub function instead
|
||||
* of making real HTTP requests.
|
||||
*/
|
||||
export function testCredentialsWithStub(
|
||||
requestSpy?: jest.SpyInstance<RequestInterface<object>>,
|
||||
): Credentials {
|
||||
const request =
|
||||
requestSpy ??
|
||||
jest.fn(async () => {
|
||||
throw new Error("Tried to make HTTP request but no stub was provided");
|
||||
});
|
||||
return makeTestOctokit({ request } as any);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a Credentials instance that returns a real octokit instance,
|
||||
* optionally authenticated with a given token.
|
||||
*/
|
||||
export function testCredentialsWithRealOctokit(token?: string): Credentials {
|
||||
return makeTestOctokit(new Octokit.Octokit({ auth: token, retry }));
|
||||
}
|
|
@ -1,6 +1,3 @@
|
|||
import { Octokit as Octokit_Octokit } from "@octokit/rest";
|
||||
import { retry } from "@octokit/plugin-retry";
|
||||
|
||||
import { faker } from "@faker-js/faker";
|
||||
|
||||
import {
|
||||
|
@ -10,17 +7,13 @@ import {
|
|||
getVariantAnalysisRepoResult,
|
||||
submitVariantAnalysis,
|
||||
} from "../../../../src/remote-queries/gh-api/gh-api-client";
|
||||
import { Credentials } from "../../../../src/authentication";
|
||||
import { createMockSubmission } from "../../../factories/remote-queries/shared/variant-analysis-submission";
|
||||
import { MockGitHubApiServer } from "../../../../src/mocks/mock-gh-api-server";
|
||||
|
||||
import { response } from "../../../../src/mocks/scenarios/problem-query-success/0-getRepo.json";
|
||||
import { response as variantAnalysisJson_response } from "../../../../src/mocks/scenarios/problem-query-success/1-submitVariantAnalysis.json";
|
||||
import { response as variantAnalysisRepoJson_response } from "../../../../src/mocks/scenarios/problem-query-success/9-getVariantAnalysisRepo.json";
|
||||
|
||||
const mockCredentials = {
|
||||
getOctokit: () => Promise.resolve(new Octokit_Octokit({ retry })),
|
||||
} as unknown as Credentials;
|
||||
import { testCredentialsWithRealOctokit } from "../../../factories/authentication";
|
||||
|
||||
const mockServer = new MockGitHubApiServer();
|
||||
beforeAll(() => mockServer.startServer());
|
||||
|
@ -36,7 +29,7 @@ describe("submitVariantAnalysis", () => {
|
|||
await mockServer.loadScenario("problem-query-success");
|
||||
|
||||
const result = await submitVariantAnalysis(
|
||||
mockCredentials,
|
||||
testCredentialsWithRealOctokit(),
|
||||
createMockSubmission(),
|
||||
);
|
||||
|
||||
|
@ -50,7 +43,7 @@ describe("getVariantAnalysis", () => {
|
|||
await mockServer.loadScenario("problem-query-success");
|
||||
|
||||
const result = await getVariantAnalysis(
|
||||
mockCredentials,
|
||||
testCredentialsWithRealOctokit(),
|
||||
controllerRepoId,
|
||||
variantAnalysisId,
|
||||
);
|
||||
|
@ -65,7 +58,7 @@ describe("getVariantAnalysisRepo", () => {
|
|||
await mockServer.loadScenario("problem-query-success");
|
||||
|
||||
const result = await getVariantAnalysisRepo(
|
||||
mockCredentials,
|
||||
testCredentialsWithRealOctokit(),
|
||||
controllerRepoId,
|
||||
variantAnalysisId,
|
||||
repoTaskId,
|
||||
|
@ -81,7 +74,7 @@ describe("getVariantAnalysisRepoResult", () => {
|
|||
await mockServer.loadScenario("problem-query-success");
|
||||
|
||||
const result = await getVariantAnalysisRepoResult(
|
||||
mockCredentials,
|
||||
testCredentialsWithRealOctokit(),
|
||||
`https://objects-origin.githubusercontent.com/codeql-query-console/codeql-variant-analysis-repo-tasks/${variantAnalysisId}/${repoTaskId}/${faker.datatype.uuid()}`,
|
||||
);
|
||||
|
||||
|
@ -98,7 +91,7 @@ describe("getRepositoryFromNwo", () => {
|
|||
await mockServer.loadScenario("problem-query-success");
|
||||
|
||||
const result = await getRepositoryFromNwo(
|
||||
mockCredentials,
|
||||
testCredentialsWithRealOctokit(),
|
||||
"github",
|
||||
"mrva-demo-controller-repo",
|
||||
);
|
||||
|
|
|
@ -25,11 +25,12 @@ import { OutputChannelLogger } from "../../../../src/common";
|
|||
import { RemoteQueriesSubmission } from "../../../../src/remote-queries/shared/remote-queries";
|
||||
import { readBundledPack } from "../../utils/bundled-pack-helpers";
|
||||
import { RemoteQueriesManager } from "../../../../src/remote-queries/remote-queries-manager";
|
||||
import { Credentials } from "../../../../src/authentication";
|
||||
import {
|
||||
fixWorkspaceReferences,
|
||||
restoreWorkspaceReferences,
|
||||
} from "../global.helper";
|
||||
import { createMockApp } from "../../../__mocks__/appMock";
|
||||
import { App } from "../../../../src/common/app";
|
||||
|
||||
// up to 3 minutes per test
|
||||
jest.setTimeout(3 * 60 * 1000);
|
||||
|
@ -50,6 +51,7 @@ describe("Remote queries", () => {
|
|||
>;
|
||||
let ctx: ExtensionContext;
|
||||
let logger: any;
|
||||
let app: App;
|
||||
let remoteQueriesManager: RemoteQueriesManager;
|
||||
|
||||
let originalDeps: Record<string, string> | undefined;
|
||||
|
@ -74,8 +76,10 @@ describe("Remote queries", () => {
|
|||
ctx = createMockExtensionContext();
|
||||
|
||||
logger = new OutputChannelLogger("test-logger");
|
||||
app = createMockApp({});
|
||||
remoteQueriesManager = new RemoteQueriesManager(
|
||||
ctx,
|
||||
app,
|
||||
cli,
|
||||
"fake-storage-dir",
|
||||
logger,
|
||||
|
@ -104,14 +108,6 @@ describe("Remote queries", () => {
|
|||
"vscode-codeql": ["github/vscode-codeql"],
|
||||
});
|
||||
|
||||
const mockCredentials = {
|
||||
getOctokit: () =>
|
||||
Promise.resolve({
|
||||
request: undefined,
|
||||
}),
|
||||
} as unknown as Credentials;
|
||||
jest.spyOn(Credentials, "initialize").mockResolvedValue(mockCredentials);
|
||||
|
||||
// Only new version support `${workspace}` in qlpack.yml
|
||||
originalDeps = await fixWorkspaceReferences(
|
||||
qlpackFileWithWorkspaceRefs,
|
||||
|
|
|
@ -19,7 +19,6 @@ import {
|
|||
} from "../../../../src/config";
|
||||
import * as ghApiClient from "../../../../src/remote-queries/gh-api/gh-api-client";
|
||||
import * as ghActionsApiClient from "../../../../src/remote-queries/gh-api/gh-actions-api-client";
|
||||
import { Credentials } from "../../../../src/authentication";
|
||||
import * as fs from "fs-extra";
|
||||
import { join } from "path";
|
||||
|
||||
|
@ -58,12 +57,15 @@ import {
|
|||
SortKey,
|
||||
} from "../../../../src/pure/variant-analysis-filter-sort";
|
||||
import { DbManager } from "../../../../src/databases/db-manager";
|
||||
import { App } from "../../../../src/common/app";
|
||||
import { createMockApp } from "../../../__mocks__/appMock";
|
||||
|
||||
// up to 3 minutes per test
|
||||
jest.setTimeout(3 * 60 * 1000);
|
||||
|
||||
describe("Variant Analysis Manager", () => {
|
||||
let cli: CodeQLCliServer;
|
||||
let app: App;
|
||||
let cancellationTokenSource: CancellationTokenSource;
|
||||
let variantAnalysisManager: VariantAnalysisManager;
|
||||
let variantAnalysisResultsManager: VariantAnalysisResultsManager;
|
||||
|
@ -91,12 +93,15 @@ describe("Variant Analysis Manager", () => {
|
|||
)!
|
||||
.activate();
|
||||
cli = extension.cliServer;
|
||||
app = createMockApp({});
|
||||
variantAnalysisResultsManager = new VariantAnalysisResultsManager(
|
||||
app.credentials,
|
||||
cli,
|
||||
extLogger,
|
||||
);
|
||||
variantAnalysisManager = new VariantAnalysisManager(
|
||||
extension.ctx,
|
||||
app,
|
||||
cli,
|
||||
storagePath,
|
||||
variantAnalysisResultsManager,
|
||||
|
@ -127,14 +132,6 @@ describe("Variant Analysis Manager", () => {
|
|||
}
|
||||
|
||||
beforeEach(async () => {
|
||||
const mockCredentials = {
|
||||
getOctokit: () =>
|
||||
Promise.resolve({
|
||||
request: jest.fn(),
|
||||
}),
|
||||
} as unknown as Credentials;
|
||||
jest.spyOn(Credentials, "initialize").mockResolvedValue(mockCredentials);
|
||||
|
||||
// Should not have asked for a language
|
||||
showQuickPickSpy = jest
|
||||
.spyOn(window, "showQuickPick")
|
||||
|
@ -349,14 +346,6 @@ describe("Variant Analysis Manager", () => {
|
|||
let repoStatesPath: string;
|
||||
|
||||
beforeEach(async () => {
|
||||
const mockCredentials = {
|
||||
getOctokit: () =>
|
||||
Promise.resolve({
|
||||
request: jest.fn(),
|
||||
}),
|
||||
} as unknown as Credentials;
|
||||
jest.spyOn(Credentials, "initialize").mockResolvedValue(mockCredentials);
|
||||
|
||||
const sourceFilePath = join(
|
||||
__dirname,
|
||||
"../data/variant-analysis-results.zip",
|
||||
|
@ -612,16 +601,6 @@ describe("Variant Analysis Manager", () => {
|
|||
});
|
||||
|
||||
describe("enqueueDownload", () => {
|
||||
beforeEach(async () => {
|
||||
const mockCredentials = {
|
||||
getOctokit: () =>
|
||||
Promise.resolve({
|
||||
request: jest.fn(),
|
||||
}),
|
||||
} as unknown as Credentials;
|
||||
jest.spyOn(Credentials, "initialize").mockResolvedValue(mockCredentials);
|
||||
});
|
||||
|
||||
it("should pop download tasks off the queue", async () => {
|
||||
const getResultsSpy = jest
|
||||
.spyOn(variantAnalysisManager, "autoDownloadVariantAnalysisResult")
|
||||
|
@ -782,8 +761,6 @@ describe("Variant Analysis Manager", () => {
|
|||
|
||||
let variantAnalysisStorageLocation: string;
|
||||
|
||||
let mockCredentials: Credentials;
|
||||
|
||||
beforeEach(async () => {
|
||||
variantAnalysis = createMockVariantAnalysis({});
|
||||
|
||||
|
@ -797,14 +774,6 @@ describe("Variant Analysis Manager", () => {
|
|||
);
|
||||
await createTimestampFile(variantAnalysisStorageLocation);
|
||||
await variantAnalysisManager.rehydrateVariantAnalysis(variantAnalysis);
|
||||
|
||||
mockCredentials = {
|
||||
getOctokit: () =>
|
||||
Promise.resolve({
|
||||
request: jest.fn(),
|
||||
}),
|
||||
} as unknown as Credentials;
|
||||
jest.spyOn(Credentials, "initialize").mockResolvedValue(mockCredentials);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
@ -842,7 +811,7 @@ describe("Variant Analysis Manager", () => {
|
|||
await variantAnalysisManager.cancelVariantAnalysis(variantAnalysis.id);
|
||||
|
||||
expect(mockCancelVariantAnalysis).toBeCalledWith(
|
||||
mockCredentials,
|
||||
app.credentials,
|
||||
variantAnalysis,
|
||||
);
|
||||
});
|
||||
|
|
|
@ -23,9 +23,9 @@ import {
|
|||
processScannedRepository,
|
||||
processUpdatedVariantAnalysis,
|
||||
} from "../../../../src/remote-queries/variant-analysis-processor";
|
||||
import { Credentials } from "../../../../src/authentication";
|
||||
import { createMockVariantAnalysis } from "../../../factories/remote-queries/shared/variant-analysis";
|
||||
import { VariantAnalysisManager } from "../../../../src/remote-queries/variant-analysis-manager";
|
||||
import { testCredentialsWithStub } from "../../../factories/authentication";
|
||||
|
||||
jest.setTimeout(60_000);
|
||||
|
||||
|
@ -74,14 +74,6 @@ describe("Variant Analysis Monitor", () => {
|
|||
.mockRejectedValue(new Error("Not mocked"));
|
||||
|
||||
limitNumberOfAttemptsToMonitor();
|
||||
|
||||
const mockCredentials = {
|
||||
getOctokit: () =>
|
||||
Promise.resolve({
|
||||
request: jest.fn(),
|
||||
}),
|
||||
} as unknown as Credentials;
|
||||
jest.spyOn(Credentials, "initialize").mockResolvedValue(mockCredentials);
|
||||
});
|
||||
|
||||
it("should return early if variant analysis is cancelled", async () => {
|
||||
|
@ -89,6 +81,7 @@ describe("Variant Analysis Monitor", () => {
|
|||
|
||||
await variantAnalysisMonitor.monitorVariantAnalysis(
|
||||
variantAnalysis,
|
||||
testCredentialsWithStub(),
|
||||
cancellationTokenSource.token,
|
||||
);
|
||||
|
||||
|
@ -100,6 +93,7 @@ describe("Variant Analysis Monitor", () => {
|
|||
|
||||
await variantAnalysisMonitor.monitorVariantAnalysis(
|
||||
variantAnalysis,
|
||||
testCredentialsWithStub(),
|
||||
cancellationTokenSource.token,
|
||||
);
|
||||
|
||||
|
@ -117,6 +111,7 @@ describe("Variant Analysis Monitor", () => {
|
|||
it("should mark as failed and stop monitoring", async () => {
|
||||
await variantAnalysisMonitor.monitorVariantAnalysis(
|
||||
variantAnalysis,
|
||||
testCredentialsWithStub(),
|
||||
cancellationTokenSource.token,
|
||||
);
|
||||
|
||||
|
@ -166,6 +161,7 @@ describe("Variant Analysis Monitor", () => {
|
|||
|
||||
await variantAnalysisMonitor.monitorVariantAnalysis(
|
||||
variantAnalysis,
|
||||
testCredentialsWithStub(),
|
||||
cancellationTokenSource.token,
|
||||
);
|
||||
|
||||
|
@ -184,6 +180,7 @@ describe("Variant Analysis Monitor", () => {
|
|||
it("should download all available results", async () => {
|
||||
await variantAnalysisMonitor.monitorVariantAnalysis(
|
||||
variantAnalysis,
|
||||
testCredentialsWithStub(),
|
||||
cancellationTokenSource.token,
|
||||
);
|
||||
|
||||
|
@ -216,6 +213,7 @@ describe("Variant Analysis Monitor", () => {
|
|||
|
||||
await variantAnalysisMonitor.monitorVariantAnalysis(
|
||||
variantAnalysis,
|
||||
testCredentialsWithStub(),
|
||||
cancellationTokenSource.token,
|
||||
);
|
||||
|
||||
|
@ -225,6 +223,7 @@ describe("Variant Analysis Monitor", () => {
|
|||
it("should not try to download any repos", async () => {
|
||||
await variantAnalysisMonitor.monitorVariantAnalysis(
|
||||
variantAnalysis,
|
||||
testCredentialsWithStub(),
|
||||
cancellationTokenSource.token,
|
||||
);
|
||||
|
||||
|
@ -283,6 +282,7 @@ describe("Variant Analysis Monitor", () => {
|
|||
|
||||
await variantAnalysisMonitor.monitorVariantAnalysis(
|
||||
variantAnalysis,
|
||||
testCredentialsWithStub(),
|
||||
cancellationTokenSource.token,
|
||||
);
|
||||
|
||||
|
@ -301,6 +301,7 @@ describe("Variant Analysis Monitor", () => {
|
|||
it("should not try to download any repos", async () => {
|
||||
await variantAnalysisMonitor.monitorVariantAnalysis(
|
||||
variantAnalysis,
|
||||
testCredentialsWithStub(),
|
||||
cancellationTokenSource.token,
|
||||
);
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { extensions } from "vscode";
|
||||
import { CodeQLExtensionInterface } from "../../../../src/extension";
|
||||
import { extLogger } from "../../../../src/common";
|
||||
import { Credentials } from "../../../../src/authentication";
|
||||
import * as fs from "fs-extra";
|
||||
import { join, resolve } from "path";
|
||||
|
||||
|
@ -15,6 +14,8 @@ import {
|
|||
VariantAnalysisRepositoryTask,
|
||||
VariantAnalysisScannedRepositoryResult,
|
||||
} from "../../../../src/remote-queries/shared/variant-analysis";
|
||||
import { testCredentialsWithStub } from "../../../factories/authentication";
|
||||
import { Credentials } from "../../../../src/common/authentication";
|
||||
|
||||
jest.setTimeout(10_000);
|
||||
|
||||
|
@ -34,12 +35,6 @@ describe(VariantAnalysisResultsManager.name, () => {
|
|||
});
|
||||
|
||||
describe("download", () => {
|
||||
const mockCredentials = {
|
||||
getOctokit: () =>
|
||||
Promise.resolve({
|
||||
request: jest.fn(),
|
||||
}),
|
||||
} as unknown as Credentials;
|
||||
let dummyRepoTask: VariantAnalysisRepositoryTask;
|
||||
let variantAnalysisStoragePath: string;
|
||||
let repoTaskStorageDirectory: string;
|
||||
|
@ -49,6 +44,7 @@ describe(VariantAnalysisResultsManager.name, () => {
|
|||
jest.spyOn(extLogger, "log").mockResolvedValue(undefined);
|
||||
|
||||
variantAnalysisResultsManager = new VariantAnalysisResultsManager(
|
||||
testCredentialsWithStub(),
|
||||
cli,
|
||||
extLogger,
|
||||
);
|
||||
|
@ -90,7 +86,6 @@ describe(VariantAnalysisResultsManager.name, () => {
|
|||
|
||||
await expect(
|
||||
variantAnalysisResultsManager.download(
|
||||
mockCredentials,
|
||||
variantAnalysisId,
|
||||
dummyRepoTask,
|
||||
variantAnalysisStoragePath,
|
||||
|
@ -127,7 +122,6 @@ describe(VariantAnalysisResultsManager.name, () => {
|
|||
|
||||
it("should call the API to download the results", async () => {
|
||||
await variantAnalysisResultsManager.download(
|
||||
mockCredentials,
|
||||
variantAnalysisId,
|
||||
dummyRepoTask,
|
||||
variantAnalysisStoragePath,
|
||||
|
@ -138,7 +132,6 @@ describe(VariantAnalysisResultsManager.name, () => {
|
|||
|
||||
it("should save the results zip file to disk", async () => {
|
||||
await variantAnalysisResultsManager.download(
|
||||
mockCredentials,
|
||||
variantAnalysisId,
|
||||
dummyRepoTask,
|
||||
variantAnalysisStoragePath,
|
||||
|
@ -151,7 +144,6 @@ describe(VariantAnalysisResultsManager.name, () => {
|
|||
|
||||
it("should unzip the results in a `results/` folder", async () => {
|
||||
await variantAnalysisResultsManager.download(
|
||||
mockCredentials,
|
||||
variantAnalysisId,
|
||||
dummyRepoTask,
|
||||
variantAnalysisStoragePath,
|
||||
|
@ -165,7 +157,6 @@ describe(VariantAnalysisResultsManager.name, () => {
|
|||
describe("isVariantAnalysisRepoDownloaded", () => {
|
||||
it("should return true once results are downloaded", async () => {
|
||||
await variantAnalysisResultsManager.download(
|
||||
mockCredentials,
|
||||
variantAnalysisId,
|
||||
dummyRepoTask,
|
||||
variantAnalysisStoragePath,
|
||||
|
@ -194,6 +185,7 @@ describe(VariantAnalysisResultsManager.name, () => {
|
|||
|
||||
beforeEach(() => {
|
||||
variantAnalysisResultsManager = new VariantAnalysisResultsManager(
|
||||
testCredentialsWithStub(),
|
||||
cli,
|
||||
extLogger,
|
||||
);
|
||||
|
|
|
@ -9,11 +9,8 @@ import {
|
|||
window,
|
||||
workspace,
|
||||
} from "vscode";
|
||||
import { Octokit } from "@octokit/rest";
|
||||
import { retry } from "@octokit/plugin-retry";
|
||||
|
||||
import { CodeQLExtensionInterface } from "../../../../src/extension";
|
||||
import { Credentials } from "../../../../src/authentication";
|
||||
import { MockGitHubApiServer } from "../../../../src/mocks/mock-gh-api-server";
|
||||
|
||||
jest.setTimeout(30_000);
|
||||
|
@ -93,11 +90,6 @@ describe("Variant Analysis Submission Integration", () => {
|
|||
},
|
||||
});
|
||||
|
||||
const mockCredentials = {
|
||||
getOctokit: () => Promise.resolve(new Octokit({ retry })),
|
||||
} as unknown as Credentials;
|
||||
jest.spyOn(Credentials, "initialize").mockResolvedValue(mockCredentials);
|
||||
|
||||
quickPickSpy = jest
|
||||
.spyOn(window, "showQuickPick")
|
||||
.mockResolvedValue(undefined);
|
||||
|
|
|
@ -11,7 +11,7 @@ import { Uri } from "vscode";
|
|||
|
||||
import { DatabaseUI } from "../../../src/databases-ui";
|
||||
import { testDisposeHandler } from "../test-dispose-handler";
|
||||
import { Credentials } from "../../../src/authentication";
|
||||
import { createMockApp } from "../../__mocks__/appMock";
|
||||
|
||||
describe("databases-ui", () => {
|
||||
describe("fixDbUri", () => {
|
||||
|
@ -82,7 +82,9 @@ describe("databases-ui", () => {
|
|||
"codeql-database.yml",
|
||||
);
|
||||
|
||||
const app = createMockApp({});
|
||||
const databaseUI = new DatabaseUI(
|
||||
app,
|
||||
{
|
||||
databaseItems: [{ databaseUri: Uri.file(db1) }],
|
||||
onDidChangeDatabaseItem: () => {
|
||||
|
@ -95,7 +97,6 @@ describe("databases-ui", () => {
|
|||
{} as any,
|
||||
storageDir,
|
||||
storageDir,
|
||||
() => Promise.resolve({} as Credentials),
|
||||
);
|
||||
|
||||
await databaseUI.handleRemoveOrphanedDatabases();
|
||||
|
|
|
@ -42,10 +42,12 @@ import { VariantAnalysisHistoryItem } from "../../../../src/query-history/varian
|
|||
import { QueryStatus } from "../../../../src/query-status";
|
||||
import { VariantAnalysisStatus } from "../../../../src/remote-queries/shared/variant-analysis";
|
||||
import * as ghActionsApiClient from "../../../../src/remote-queries/gh-api/gh-actions-api-client";
|
||||
import { Credentials } from "../../../../src/authentication";
|
||||
import { QuickPickItem, TextEditor } from "vscode";
|
||||
import { WebviewReveal } from "../../../../src/interface-utils";
|
||||
import * as helpers from "../../../../src/helpers";
|
||||
import { testCredentialsWithStub } from "../../../factories/authentication";
|
||||
import { Credentials } from "../../../../src/common/authentication";
|
||||
import { createMockApp } from "../../../__mocks__/appMock";
|
||||
|
||||
describe("query-history", () => {
|
||||
const mockExtensionLocation = join(tmpDir.name, "mock-extension-location");
|
||||
|
@ -873,23 +875,13 @@ describe("query-history", () => {
|
|||
});
|
||||
|
||||
describe("handleCancel", () => {
|
||||
let mockCredentials: Credentials;
|
||||
let mockCancelRemoteQuery: jest.SpiedFunction<
|
||||
typeof ghActionsApiClient.cancelRemoteQuery
|
||||
>;
|
||||
const getOctokitStub = jest.fn();
|
||||
const mockCredentials = testCredentialsWithStub(getOctokitStub);
|
||||
|
||||
beforeEach(async () => {
|
||||
mockCredentials = {
|
||||
getOctokit: () =>
|
||||
Promise.resolve({
|
||||
request: getOctokitStub,
|
||||
}),
|
||||
} as unknown as Credentials;
|
||||
jest
|
||||
.spyOn(Credentials, "initialize")
|
||||
.mockResolvedValue(mockCredentials);
|
||||
|
||||
mockCancelRemoteQuery = jest
|
||||
.spyOn(ghActionsApiClient, "cancelRemoteQuery")
|
||||
.mockResolvedValue();
|
||||
|
@ -897,7 +889,10 @@ describe("query-history", () => {
|
|||
|
||||
describe("if the item is in progress", () => {
|
||||
it("should cancel a single local query", async () => {
|
||||
queryHistoryManager = await createMockQueryHistory(localQueryHistory);
|
||||
queryHistoryManager = await createMockQueryHistory(
|
||||
localQueryHistory,
|
||||
mockCredentials,
|
||||
);
|
||||
|
||||
// cancelling the selected item
|
||||
const inProgress1 = localQueryHistory[4];
|
||||
|
@ -908,7 +903,10 @@ describe("query-history", () => {
|
|||
});
|
||||
|
||||
it("should cancel multiple local queries", async () => {
|
||||
queryHistoryManager = await createMockQueryHistory(localQueryHistory);
|
||||
queryHistoryManager = await createMockQueryHistory(
|
||||
localQueryHistory,
|
||||
mockCredentials,
|
||||
);
|
||||
|
||||
// cancelling the selected item
|
||||
const inProgress1 = localQueryHistory[4];
|
||||
|
@ -926,7 +924,10 @@ describe("query-history", () => {
|
|||
});
|
||||
|
||||
it("should cancel a single remote query", async () => {
|
||||
queryHistoryManager = await createMockQueryHistory(allHistory);
|
||||
queryHistoryManager = await createMockQueryHistory(
|
||||
allHistory,
|
||||
mockCredentials,
|
||||
);
|
||||
|
||||
// cancelling the selected item
|
||||
const inProgress1 = remoteQueryHistory[2];
|
||||
|
@ -939,7 +940,10 @@ describe("query-history", () => {
|
|||
});
|
||||
|
||||
it("should cancel multiple remote queries", async () => {
|
||||
queryHistoryManager = await createMockQueryHistory(allHistory);
|
||||
queryHistoryManager = await createMockQueryHistory(
|
||||
allHistory,
|
||||
mockCredentials,
|
||||
);
|
||||
|
||||
// cancelling the selected item
|
||||
const inProgress1 = remoteQueryHistory[2];
|
||||
|
@ -960,7 +964,10 @@ describe("query-history", () => {
|
|||
});
|
||||
|
||||
it("should cancel a single variant analysis", async () => {
|
||||
queryHistoryManager = await createMockQueryHistory(allHistory);
|
||||
queryHistoryManager = await createMockQueryHistory(
|
||||
allHistory,
|
||||
mockCredentials,
|
||||
);
|
||||
|
||||
// cancelling the selected item
|
||||
const inProgress1 = variantAnalysisHistory[1];
|
||||
|
@ -973,7 +980,10 @@ describe("query-history", () => {
|
|||
});
|
||||
|
||||
it("should cancel multiple variant analyses", async () => {
|
||||
queryHistoryManager = await createMockQueryHistory(allHistory);
|
||||
queryHistoryManager = await createMockQueryHistory(
|
||||
allHistory,
|
||||
mockCredentials,
|
||||
);
|
||||
|
||||
// cancelling the selected item
|
||||
const inProgress1 = variantAnalysisHistory[1];
|
||||
|
@ -996,7 +1006,10 @@ describe("query-history", () => {
|
|||
|
||||
describe("if the item is not in progress", () => {
|
||||
it("should not cancel a single local query", async () => {
|
||||
queryHistoryManager = await createMockQueryHistory(localQueryHistory);
|
||||
queryHistoryManager = await createMockQueryHistory(
|
||||
localQueryHistory,
|
||||
mockCredentials,
|
||||
);
|
||||
|
||||
// cancelling the selected item
|
||||
const completed = localQueryHistory[0];
|
||||
|
@ -1007,7 +1020,10 @@ describe("query-history", () => {
|
|||
});
|
||||
|
||||
it("should not cancel multiple local queries", async () => {
|
||||
queryHistoryManager = await createMockQueryHistory(localQueryHistory);
|
||||
queryHistoryManager = await createMockQueryHistory(
|
||||
localQueryHistory,
|
||||
mockCredentials,
|
||||
);
|
||||
|
||||
// cancelling the selected item
|
||||
const completed = localQueryHistory[0];
|
||||
|
@ -1025,7 +1041,10 @@ describe("query-history", () => {
|
|||
});
|
||||
|
||||
it("should not cancel a single remote query", async () => {
|
||||
queryHistoryManager = await createMockQueryHistory(allHistory);
|
||||
queryHistoryManager = await createMockQueryHistory(
|
||||
allHistory,
|
||||
mockCredentials,
|
||||
);
|
||||
|
||||
// cancelling the selected item
|
||||
const completed = remoteQueryHistory[0];
|
||||
|
@ -1038,7 +1057,10 @@ describe("query-history", () => {
|
|||
});
|
||||
|
||||
it("should not cancel multiple remote queries", async () => {
|
||||
queryHistoryManager = await createMockQueryHistory(allHistory);
|
||||
queryHistoryManager = await createMockQueryHistory(
|
||||
allHistory,
|
||||
mockCredentials,
|
||||
);
|
||||
|
||||
// cancelling the selected item
|
||||
const completed = remoteQueryHistory[0];
|
||||
|
@ -1059,7 +1081,10 @@ describe("query-history", () => {
|
|||
});
|
||||
|
||||
it("should not cancel a single variant analysis", async () => {
|
||||
queryHistoryManager = await createMockQueryHistory(allHistory);
|
||||
queryHistoryManager = await createMockQueryHistory(
|
||||
allHistory,
|
||||
mockCredentials,
|
||||
);
|
||||
|
||||
// cancelling the selected item
|
||||
const completedVariantAnalysis = variantAnalysisHistory[0];
|
||||
|
@ -1074,7 +1099,10 @@ describe("query-history", () => {
|
|||
});
|
||||
|
||||
it("should not cancel multiple variant analyses", async () => {
|
||||
queryHistoryManager = await createMockQueryHistory(allHistory);
|
||||
queryHistoryManager = await createMockQueryHistory(
|
||||
allHistory,
|
||||
mockCredentials,
|
||||
);
|
||||
|
||||
// cancelling the selected item
|
||||
const completedVariantAnalysis = variantAnalysisHistory[0];
|
||||
|
@ -1984,8 +2012,12 @@ describe("query-history", () => {
|
|||
});
|
||||
});
|
||||
|
||||
async function createMockQueryHistory(allHistory: QueryHistoryInfo[]) {
|
||||
async function createMockQueryHistory(
|
||||
allHistory: QueryHistoryInfo[],
|
||||
credentials?: Credentials,
|
||||
) {
|
||||
const qhm = new QueryHistoryManager(
|
||||
createMockApp({ credentials }),
|
||||
{} as QueryRunner,
|
||||
{} as DatabaseManager,
|
||||
localQueriesResultsViewStub,
|
||||
|
|
|
@ -21,7 +21,6 @@ import { QueryHistoryConfig } from "../../../../src/config";
|
|||
import { DatabaseManager } from "../../../../src/databases";
|
||||
import { tmpDir, walkDirectory } from "../../../../src/helpers";
|
||||
import { QueryHistoryManager } from "../../../../src/query-history/query-history";
|
||||
import { Credentials } from "../../../../src/authentication";
|
||||
import { AnalysesResultsManager } from "../../../../src/remote-queries/analyses-results-manager";
|
||||
import { RemoteQueryResult } from "../../../../src/remote-queries/shared/remote-query-result";
|
||||
import { DisposableBucket } from "../../disposable-bucket";
|
||||
|
@ -32,6 +31,9 @@ import { ResultsView } from "../../../../src/interface";
|
|||
import { EvalLogViewer } from "../../../../src/eval-log-viewer";
|
||||
import { QueryRunner } from "../../../../src/queryRunner";
|
||||
import { VariantAnalysisManager } from "../../../../src/remote-queries/variant-analysis-manager";
|
||||
import { App } from "../../../../src/common/app";
|
||||
import { createMockApp } from "../../../__mocks__/appMock";
|
||||
import { testCredentialsWithStub } from "../../../factories/authentication";
|
||||
|
||||
// set a higher timeout since recursive delete may take a while, expecially on Windows.
|
||||
jest.setTimeout(120000);
|
||||
|
@ -47,6 +49,8 @@ describe("Remote queries and query history manager", () => {
|
|||
/** noop */
|
||||
};
|
||||
|
||||
const mockOctokit = jest.fn();
|
||||
let app: App;
|
||||
let qhm: QueryHistoryManager;
|
||||
const localQueriesResultsViewStub = {
|
||||
showResults: jest.fn(),
|
||||
|
@ -107,7 +111,9 @@ describe("Remote queries and query history manager", () => {
|
|||
),
|
||||
);
|
||||
|
||||
app = createMockApp({ credentials: testCredentialsWithStub(mockOctokit) });
|
||||
qhm = new QueryHistoryManager(
|
||||
app,
|
||||
{} as QueryRunner,
|
||||
{} as DatabaseManager,
|
||||
localQueriesResultsViewStub,
|
||||
|
@ -256,19 +262,11 @@ describe("Remote queries and query history manager", () => {
|
|||
});
|
||||
|
||||
describe("AnalysisResultsManager", () => {
|
||||
let mockCredentials: any;
|
||||
let mockOctokit: any;
|
||||
let mockLogger: any;
|
||||
let mockCliServer: any;
|
||||
let arm: AnalysesResultsManager;
|
||||
|
||||
beforeEach(() => {
|
||||
mockOctokit = {
|
||||
request: jest.fn(),
|
||||
};
|
||||
mockCredentials = {
|
||||
getOctokit: () => mockOctokit,
|
||||
};
|
||||
mockLogger = {
|
||||
log: jest.fn(),
|
||||
};
|
||||
|
@ -276,9 +274,9 @@ describe("Remote queries and query history manager", () => {
|
|||
bqrsInfo: jest.fn(),
|
||||
bqrsDecode: jest.fn(),
|
||||
};
|
||||
jest.spyOn(Credentials, "initialize").mockResolvedValue(mockCredentials);
|
||||
|
||||
arm = new AnalysesResultsManager(
|
||||
app,
|
||||
mockCliServer,
|
||||
join(STORAGE_DIR, "queries"),
|
||||
mockLogger,
|
||||
|
@ -292,7 +290,7 @@ describe("Remote queries and query history manager", () => {
|
|||
await arm.downloadAnalysisResults(analysisSummary, publisher);
|
||||
|
||||
// Should not have made the request since the analysis result is already on disk
|
||||
expect(mockOctokit.request).not.toBeCalled();
|
||||
expect(mockOctokit).not.toBeCalled();
|
||||
|
||||
// result should have been published twice
|
||||
expect(publisher).toHaveBeenCalledTimes(2);
|
||||
|
|
|
@ -21,6 +21,8 @@ import { ResultsView } from "../../../../src/interface";
|
|||
import { EvalLogViewer } from "../../../../src/eval-log-viewer";
|
||||
import { QueryRunner } from "../../../../src/queryRunner";
|
||||
import { VariantAnalysisManager } from "../../../../src/remote-queries/variant-analysis-manager";
|
||||
import { App } from "../../../../src/common/app";
|
||||
import { createMockApp } from "../../../__mocks__/appMock";
|
||||
|
||||
// set a higher timeout since recursive delete may take a while, expecially on Windows.
|
||||
jest.setTimeout(120000);
|
||||
|
@ -36,6 +38,7 @@ describe("Variant Analyses and QueryHistoryManager", () => {
|
|||
/** noop */
|
||||
};
|
||||
|
||||
let app: App;
|
||||
let qhm: QueryHistoryManager;
|
||||
let rawQueryHistory: any;
|
||||
let disposables: DisposableBucket;
|
||||
|
@ -77,7 +80,10 @@ describe("Variant Analyses and QueryHistoryManager", () => {
|
|||
join(STORAGE_DIR, "workspace-query-history.json"),
|
||||
).queries;
|
||||
|
||||
app = createMockApp({});
|
||||
|
||||
qhm = new QueryHistoryManager(
|
||||
app,
|
||||
{} as QueryRunner,
|
||||
{} as DatabaseManager,
|
||||
localQueriesResultsViewStub,
|
||||
|
|
|
@ -1,17 +1,14 @@
|
|||
import { join } from "path";
|
||||
import { readFile } from "fs-extra";
|
||||
import { Credentials } from "../../../../src/authentication";
|
||||
import * as markdownGenerator from "../../../../src/remote-queries/remote-queries-markdown-generation";
|
||||
import * as ghApiClient from "../../../../src/remote-queries/gh-api/gh-api-client";
|
||||
import { exportRemoteQueryAnalysisResults } from "../../../../src/remote-queries/export-results";
|
||||
import { testCredentialsWithStub } from "../../../factories/authentication";
|
||||
|
||||
describe("export results", () => {
|
||||
describe("exportRemoteQueryAnalysisResults", () => {
|
||||
const mockCredentials = {} as unknown as Credentials;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.spyOn(markdownGenerator, "generateMarkdown").mockReturnValue([]);
|
||||
jest.spyOn(Credentials, "initialize").mockResolvedValue(mockCredentials);
|
||||
});
|
||||
|
||||
it("should call the GitHub Actions API with the correct gist title", async function () {
|
||||
|
@ -43,6 +40,7 @@ describe("export results", () => {
|
|||
query,
|
||||
analysesResults,
|
||||
"gist",
|
||||
testCredentialsWithStub(),
|
||||
);
|
||||
|
||||
expect(mockCreateGist).toHaveBeenCalledTimes(1);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { Credentials } from "../../../../../src/authentication";
|
||||
import {
|
||||
cancelRemoteQuery,
|
||||
cancelVariantAnalysis,
|
||||
|
@ -7,17 +6,16 @@ import {
|
|||
import { RemoteQuery } from "../../../../../src/remote-queries/remote-query";
|
||||
import { createMockVariantAnalysis } from "../../../../factories/remote-queries/shared/variant-analysis";
|
||||
import { VariantAnalysis } from "../../../../../src/remote-queries/shared/variant-analysis";
|
||||
import {
|
||||
testCredentialsWithStub,
|
||||
testCredentialsWithRealOctokit,
|
||||
} from "../../../../factories/authentication";
|
||||
|
||||
jest.setTimeout(10000);
|
||||
|
||||
describe("gh-actions-api-client mock responses", () => {
|
||||
const mockRequest = jest.fn();
|
||||
const mockCredentials = {
|
||||
getOctokit: () =>
|
||||
Promise.resolve({
|
||||
request: mockRequest,
|
||||
}),
|
||||
} as unknown as Credentials;
|
||||
const mockCredentials = testCredentialsWithStub(mockRequest);
|
||||
|
||||
describe("cancelRemoteQuery", () => {
|
||||
it("should cancel a remote query", async () => {
|
||||
|
@ -95,7 +93,7 @@ describe("gh-actions-api-client real responses", () => {
|
|||
return;
|
||||
}
|
||||
|
||||
const credentials = await Credentials.initializeWithToken(
|
||||
const credentials = testCredentialsWithRealOctokit(
|
||||
process.env.VSCODE_CODEQL_GITHUB_TOKEN!,
|
||||
);
|
||||
const stargazers = await getRepositoriesMetadata(
|
||||
|
|
Загрузка…
Ссылка в новой задаче