This commit is contained in:
Robert 2023-01-18 17:36:38 +00:00
Родитель 13389fd35f
Коммит 03993f376f
34 изменённых файлов: 256 добавлений и 259 удалений

Просмотреть файл

@ -1,6 +1,7 @@
import * as vscode from "vscode"; import * as vscode from "vscode";
import * as Octokit from "@octokit/rest"; import * as Octokit from "@octokit/rest";
import { retry } from "@octokit/plugin-retry"; import { retry } from "@octokit/plugin-retry";
import { Credentials } from "./common/authentication";
const GITHUB_AUTH_PROVIDER_ID = "github"; 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). * 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. * A specific octokit to return, otherwise a new authenticated octokit will be created when needed.
*/ */
private octokit: Octokit.Octokit | undefined; 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. * Creates or returns an instance of Octokit.
* *

Просмотреть файл

@ -27,7 +27,7 @@ import { Logger, ProgressReporter } from "./common";
import { CompilationMessage } from "./pure/legacy-messages"; import { CompilationMessage } from "./pure/legacy-messages";
import { sarifParser } from "./sarif-parser"; import { sarifParser } from "./sarif-parser";
import { dbSchemeToLanguage, walkDirectory } from "./helpers"; import { dbSchemeToLanguage, walkDirectory } from "./helpers";
import { Credentials } from "./authentication"; import { App } from "./common/app";
/** /**
* The version of the SARIF format that we are using. * The version of the SARIF format that we are using.
@ -197,6 +197,7 @@ export class CodeQLCliServer implements Disposable {
public quiet = false; public quiet = false;
constructor( constructor(
private readonly app: App,
private distributionProvider: DistributionProvider, private distributionProvider: DistributionProvider,
private cliConfig: CliConfig, private cliConfig: CliConfig,
private logger: Logger, private logger: Logger,
@ -618,9 +619,7 @@ export class CodeQLCliServer implements Disposable {
addFormat = true, addFormat = true,
progressReporter?: ProgressReporter, progressReporter?: ProgressReporter,
): Promise<OutputType> { ): Promise<OutputType> {
const credentials = await Credentials.initialize(); const accessToken = await this.app.credentials.getExistingAccessToken();
const accessToken = await credentials.getExistingAccessToken();
const extraArgs = accessToken ? ["--github-auth-stdin"] : []; const extraArgs = accessToken ? ["--github-auth-stdin"] : [];
@ -633,7 +632,7 @@ export class CodeQLCliServer implements Disposable {
async (line) => { async (line) => {
if (line.startsWith("Enter value for --github-auth-stdin")) { if (line.startsWith("Enter value for --github-auth-stdin")) {
try { try {
return await credentials.getAccessToken(); return await this.app.credentials.getAccessToken();
} catch (e) { } catch (e) {
// If the user cancels the authentication prompt, we still need to give a value to the CLI. // 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 // 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 { Disposable } from "../pure/disposable-object";
import { AppEventEmitter } from "./events"; import { AppEventEmitter } from "./events";
import { Logger } from "./logging"; import { Logger } from "./logging";
@ -13,6 +14,7 @@ export interface App {
readonly globalStoragePath: string; readonly globalStoragePath: string;
readonly workspaceStoragePath?: string; readonly workspaceStoragePath?: string;
readonly workspaceState: Memento; readonly workspaceState: Memento;
readonly credentials: Credentials;
} }
export enum AppMode { export enum AppMode {

Просмотреть файл

@ -0,0 +1,14 @@
import * as Octokit from "@octokit/rest";
export interface Credentials {
/**
* Creates or returns an instance of Octokit.
*
* @returns An instance of Octokit.
*/
getOctokit(): Promise<Octokit.Octokit>;
getAccessToken(): Promise<string>;
getExistingAccessToken(): Promise<string | undefined>;
}

Просмотреть файл

@ -1,4 +1,5 @@
import * as vscode from "vscode"; import * as vscode from "vscode";
import { VSCodeCredentials } from "../../authentication";
import { Disposable } from "../../pure/disposable-object"; import { Disposable } from "../../pure/disposable-object";
import { App, AppMode } from "../app"; import { App, AppMode } from "../app";
import { AppEventEmitter } from "../events"; import { AppEventEmitter } from "../events";
@ -7,9 +8,13 @@ import { Memento } from "../memento";
import { VSCodeAppEventEmitter } from "./events"; import { VSCodeAppEventEmitter } from "./events";
export class ExtensionApp implements App { export class ExtensionApp implements App {
public readonly credentials: VSCodeCredentials;
public constructor( public constructor(
public readonly extensionContext: vscode.ExtensionContext, public readonly extensionContext: vscode.ExtensionContext,
) {} ) {
this.credentials = new VSCodeCredentials();
}
public get extensionPath(): string { public get extensionPath(): string {
return this.extensionContext.extensionPath; return this.extensionContext.extensionPath;

Просмотреть файл

@ -20,12 +20,12 @@ import { DatabaseManager, DatabaseItem } from "./databases";
import { showAndLogInformationMessage, tmpDir } from "./helpers"; import { showAndLogInformationMessage, tmpDir } from "./helpers";
import { reportStreamProgress, ProgressCallback } from "./commandRunner"; import { reportStreamProgress, ProgressCallback } from "./commandRunner";
import { extLogger } from "./common"; import { extLogger } from "./common";
import { Credentials } from "./authentication";
import { getErrorMessage } from "./pure/helpers-pure"; import { getErrorMessage } from "./pure/helpers-pure";
import { import {
getNwoFromGitHubUrl, getNwoFromGitHubUrl,
isValidGitHubNwo, isValidGitHubNwo,
} from "./common/github-url-identifier-helper"; } 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. * 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, promptImportInternetDatabase,
} from "./databaseFetcher"; } from "./databaseFetcher";
import { asyncFilter, getErrorMessage } from "./pure/helpers-pure"; import { asyncFilter, getErrorMessage } from "./pure/helpers-pure";
import { Credentials } from "./authentication";
import { QueryRunner } from "./queryRunner"; import { QueryRunner } from "./queryRunner";
import { isCanary } from "./config"; import { isCanary } from "./config";
import { App } from "./common/app";
import { Credentials } from "./common/authentication";
type ThemableIconPath = { light: string; dark: string } | string; type ThemableIconPath = { light: string; dark: string } | string;
@ -220,11 +221,11 @@ export class DatabaseUI extends DisposableObject {
private treeDataProvider: DatabaseTreeDataProvider; private treeDataProvider: DatabaseTreeDataProvider;
public constructor( public constructor(
private app: App,
private databaseManager: DatabaseManager, private databaseManager: DatabaseManager,
private readonly queryServer: QueryRunner | undefined, private readonly queryServer: QueryRunner | undefined,
private readonly storagePath: string, private readonly storagePath: string,
readonly extensionPath: string, readonly extensionPath: string,
private readonly getCredentials: () => Promise<Credentials>,
) { ) {
super(); super();
@ -297,9 +298,7 @@ export class DatabaseUI extends DisposableObject {
commandRunnerWithProgress( commandRunnerWithProgress(
"codeQLDatabases.chooseDatabaseGithub", "codeQLDatabases.chooseDatabaseGithub",
async (progress: ProgressCallback, token: CancellationToken) => { async (progress: ProgressCallback, token: CancellationToken) => {
const credentials = isCanary() const credentials = isCanary() ? this.app.credentials : undefined;
? await this.getCredentials()
: undefined;
await this.handleChooseDatabaseGithub(credentials, progress, token); await this.handleChooseDatabaseGithub(credentials, progress, token);
}, },
{ {

Просмотреть файл

@ -102,7 +102,6 @@ import {
} from "./commandRunner"; } from "./commandRunner";
import { CodeQlStatusBarHandler } from "./status-bar"; import { CodeQlStatusBarHandler } from "./status-bar";
import { Credentials } from "./authentication";
import { RemoteQueriesManager } from "./remote-queries/remote-queries-manager"; import { RemoteQueriesManager } from "./remote-queries/remote-queries-manager";
import { RemoteQueryResult } from "./remote-queries/remote-query-result"; import { RemoteQueryResult } from "./remote-queries/remote-query-result";
import { URLSearchParams } from "url"; import { URLSearchParams } from "url";
@ -546,6 +545,8 @@ async function activateWithInstalledDistribution(
// of activation. // of activation.
errorStubs.forEach((stub) => stub.dispose()); errorStubs.forEach((stub) => stub.dispose());
const app = new ExtensionApp(ctx);
void extLogger.log("Initializing configuration listener..."); void extLogger.log("Initializing configuration listener...");
const qlConfigurationListener = const qlConfigurationListener =
await QueryServerConfigListener.createQueryServerConfigListener( await QueryServerConfigListener.createQueryServerConfigListener(
@ -555,6 +556,7 @@ async function activateWithInstalledDistribution(
void extLogger.log("Initializing CodeQL cli server..."); void extLogger.log("Initializing CodeQL cli server...");
const cliServer = new CodeQLCliServer( const cliServer = new CodeQLCliServer(
app,
distributionManager, distributionManager,
new CliConfigListener(), new CliConfigListener(),
extLogger, extLogger,
@ -587,11 +589,11 @@ async function activateWithInstalledDistribution(
ctx.subscriptions.push(dbm); ctx.subscriptions.push(dbm);
void extLogger.log("Initializing database panel."); void extLogger.log("Initializing database panel.");
const databaseUI = new DatabaseUI( const databaseUI = new DatabaseUI(
app,
dbm, dbm,
qs, qs,
getContextStoragePath(ctx), getContextStoragePath(ctx),
ctx.extensionPath, ctx.extensionPath,
() => Credentials.initialize(),
); );
databaseUI.init(); databaseUI.init();
ctx.subscriptions.push(databaseUI); ctx.subscriptions.push(databaseUI);
@ -623,8 +625,6 @@ async function activateWithInstalledDistribution(
void extLogger.log("Initializing variant analysis manager."); void extLogger.log("Initializing variant analysis manager.");
const app = new ExtensionApp(ctx);
const dbModule = await DbModule.initialize(app); const dbModule = await DbModule.initialize(app);
const variantAnalysisStorageDir = join( const variantAnalysisStorageDir = join(
@ -633,12 +633,14 @@ async function activateWithInstalledDistribution(
); );
await ensureDir(variantAnalysisStorageDir); await ensureDir(variantAnalysisStorageDir);
const variantAnalysisResultsManager = new VariantAnalysisResultsManager( const variantAnalysisResultsManager = new VariantAnalysisResultsManager(
app.credentials,
cliServer, cliServer,
extLogger, extLogger,
); );
const variantAnalysisManager = new VariantAnalysisManager( const variantAnalysisManager = new VariantAnalysisManager(
ctx, ctx,
app,
cliServer, cliServer,
variantAnalysisStorageDir, variantAnalysisStorageDir,
variantAnalysisResultsManager, variantAnalysisResultsManager,
@ -656,6 +658,7 @@ async function activateWithInstalledDistribution(
void extLogger.log("Initializing remote queries manager."); void extLogger.log("Initializing remote queries manager.");
const rqm = new RemoteQueriesManager( const rqm = new RemoteQueriesManager(
ctx, ctx,
app,
cliServer, cliServer,
queryStorageDir, queryStorageDir,
extLogger, extLogger,
@ -664,6 +667,7 @@ async function activateWithInstalledDistribution(
void extLogger.log("Initializing query history."); void extLogger.log("Initializing query history.");
const qhm = new QueryHistoryManager( const qhm = new QueryHistoryManager(
app,
qs, qs,
dbm, dbm,
localQueryResultsView, localQueryResultsView,
@ -1245,7 +1249,7 @@ async function activateWithInstalledDistribution(
commandRunner( commandRunner(
"codeQL.exportRemoteQueryResults", "codeQL.exportRemoteQueryResults",
async (queryId: string) => { async (queryId: string) => {
await exportRemoteQueryResults(qhm, rqm, queryId); await exportRemoteQueryResults(qhm, rqm, queryId, app.credentials);
}, },
), ),
); );
@ -1263,6 +1267,7 @@ async function activateWithInstalledDistribution(
variantAnalysisManager, variantAnalysisManager,
variantAnalysisId, variantAnalysisId,
filterSort, filterSort,
app.credentials,
progress, progress,
token, token,
); );
@ -1363,9 +1368,7 @@ async function activateWithInstalledDistribution(
commandRunnerWithProgress( commandRunnerWithProgress(
"codeQL.chooseDatabaseGithub", "codeQL.chooseDatabaseGithub",
async (progress: ProgressCallback, token: CancellationToken) => { async (progress: ProgressCallback, token: CancellationToken) => {
const credentials = isCanary() const credentials = isCanary() ? app.credentials : undefined;
? await Credentials.initialize()
: undefined;
await databaseUI.handleChooseDatabaseGithub( await databaseUI.handleChooseDatabaseGithub(
credentials, credentials,
progress, progress,
@ -1419,8 +1422,7 @@ async function activateWithInstalledDistribution(
* Credentials for authenticating to GitHub. * Credentials for authenticating to GitHub.
* These are used when making API calls. * These are used when making API calls.
*/ */
const credentials = await Credentials.initialize(); const octokit = await app.credentials.getOctokit();
const octokit = await credentials.getOctokit();
const userInfo = await octokit.users.getAuthenticated(); const userInfo = await octokit.users.getAuthenticated();
void showAndLogInformationMessage( void showAndLogInformationMessage(
`Authenticated to GitHub as user: ${userInfo.data.login}`, `Authenticated to GitHub as user: ${userInfo.data.login}`,

Просмотреть файл

@ -55,7 +55,6 @@ import {
import { pathExists } from "fs-extra"; import { pathExists } from "fs-extra";
import { CliVersionConstraint } from "./cli"; import { CliVersionConstraint } from "./cli";
import { HistoryItemLabelProvider } from "./history-item-label-provider"; import { HistoryItemLabelProvider } from "./history-item-label-provider";
import { Credentials } from "./authentication";
import { cancelRemoteQuery } from "./remote-queries/gh-api/gh-actions-api-client"; import { cancelRemoteQuery } from "./remote-queries/gh-api/gh-actions-api-client";
import { RemoteQueriesManager } from "./remote-queries/remote-queries-manager"; import { RemoteQueriesManager } from "./remote-queries/remote-queries-manager";
import { RemoteQueryHistoryItem } from "./remote-queries/remote-query-history-item"; import { RemoteQueryHistoryItem } from "./remote-queries/remote-query-history-item";
@ -69,6 +68,7 @@ import { QueryRunner } from "./queryRunner";
import { VariantAnalysisManager } from "./remote-queries/variant-analysis-manager"; import { VariantAnalysisManager } from "./remote-queries/variant-analysis-manager";
import { VariantAnalysisHistoryItem } from "./remote-queries/variant-analysis-history-item"; import { VariantAnalysisHistoryItem } from "./remote-queries/variant-analysis-history-item";
import { getTotalResultCount } from "./remote-queries/shared/variant-analysis"; import { getTotalResultCount } from "./remote-queries/shared/variant-analysis";
import { App } from "./common/app";
/** /**
* query-history.ts * query-history.ts
@ -394,6 +394,7 @@ export class QueryHistoryManager extends DisposableObject {
readonly onDidCompleteQuery = this._onDidCompleteQuery.event; readonly onDidCompleteQuery = this._onDidCompleteQuery.event;
constructor( constructor(
private readonly app: App,
private readonly qs: QueryRunner, private readonly qs: QueryRunner,
private readonly dbm: DatabaseManager, private readonly dbm: DatabaseManager,
private readonly localQueriesResultsView: ResultsView, private readonly localQueriesResultsView: ResultsView,
@ -636,10 +637,6 @@ export class QueryHistoryManager extends DisposableObject {
this._onDidCompleteQuery.fire(info); this._onDidCompleteQuery.fire(info);
} }
private getCredentials() {
return Credentials.initialize();
}
/** /**
* Register and create the history scrubber. * Register and create the history scrubber.
*/ */
@ -1346,8 +1343,7 @@ export class QueryHistoryManager extends DisposableObject {
void showAndLogInformationMessage( void showAndLogInformationMessage(
"Cancelling variant analysis. This may take a while.", "Cancelling variant analysis. This may take a while.",
); );
const credentials = await this.getCredentials(); await cancelRemoteQuery(this.app.credentials, item.remoteQuery);
await cancelRemoteQuery(credentials, item.remoteQuery);
} else if (item.t === "variant-analysis") { } else if (item.t === "variant-analysis") {
await commands.executeCommand( await commands.executeCommand(
"codeQL.cancelVariantAnalysis", "codeQL.cancelVariantAnalysis",

Просмотреть файл

@ -3,7 +3,6 @@ import { EOL } from "os";
import { extname } from "path"; import { extname } from "path";
import { CancellationToken } from "vscode"; import { CancellationToken } from "vscode";
import { Credentials } from "../authentication";
import { Logger } from "../common"; import { Logger } from "../common";
import { downloadArtifactFromLink } from "./gh-api/gh-actions-api-client"; import { downloadArtifactFromLink } from "./gh-api/gh-actions-api-client";
import { AnalysisSummary } from "./shared/remote-query-result"; import { AnalysisSummary } from "./shared/remote-query-result";
@ -19,6 +18,7 @@ import { CodeQLCliServer } from "../cli";
import { extractRawResults } from "./bqrs-processing"; import { extractRawResults } from "./bqrs-processing";
import { asyncFilter, getErrorMessage } from "../pure/helpers-pure"; import { asyncFilter, getErrorMessage } from "../pure/helpers-pure";
import { createDownloadPath } from "./download-link"; import { createDownloadPath } from "./download-link";
import { App } from "../common/app";
export class AnalysesResultsManager { export class AnalysesResultsManager {
// Store for the results of various analyses for each remote query. // Store for the results of various analyses for each remote query.
@ -26,6 +26,7 @@ export class AnalysesResultsManager {
private readonly analysesResults: Map<string, AnalysisResults[]>; private readonly analysesResults: Map<string, AnalysisResults[]>;
constructor( constructor(
private readonly app: App,
private readonly cliServer: CodeQLCliServer, private readonly cliServer: CodeQLCliServer,
readonly storagePath: string, readonly storagePath: string,
private readonly logger: Logger, private readonly logger: Logger,
@ -42,17 +43,11 @@ export class AnalysesResultsManager {
return; return;
} }
const credentials = await Credentials.initialize();
void this.logger.log( void this.logger.log(
`Downloading and processing results for ${analysisSummary.nwo}`, `Downloading and processing results for ${analysisSummary.nwo}`,
); );
await this.downloadSingleAnalysisResults( await this.downloadSingleAnalysisResults(analysisSummary, publishResults);
analysisSummary,
credentials,
publishResults,
);
} }
/** /**
@ -76,8 +71,6 @@ export class AnalysesResultsManager {
(x) => !this.isAnalysisInMemory(x), (x) => !this.isAnalysisInMemory(x),
); );
const credentials = await Credentials.initialize();
void this.logger.log("Downloading and processing analyses results"); void this.logger.log("Downloading and processing analyses results");
const batchSize = 3; const batchSize = 3;
@ -94,11 +87,7 @@ export class AnalysesResultsManager {
const batch = analysesToDownload.slice(i, i + batchSize); const batch = analysesToDownload.slice(i, i + batchSize);
const batchTasks = batch.map((analysis) => const batchTasks = batch.map((analysis) =>
this.downloadSingleAnalysisResults( this.downloadSingleAnalysisResults(analysis, publishResults),
analysis,
credentials,
publishResults,
),
); );
const nwos = batch.map((a) => a.nwo).join(", "); const nwos = batch.map((a) => a.nwo).join(", ");
@ -138,7 +127,6 @@ export class AnalysesResultsManager {
private async downloadSingleAnalysisResults( private async downloadSingleAnalysisResults(
analysis: AnalysisSummary, analysis: AnalysisSummary,
credentials: Credentials,
publishResults: (analysesResults: AnalysisResults[]) => Promise<void>, publishResults: (analysesResults: AnalysisResults[]) => Promise<void>,
): Promise<void> { ): Promise<void> {
const analysisResults: AnalysisResults = { const analysisResults: AnalysisResults = {
@ -159,7 +147,7 @@ export class AnalysesResultsManager {
let artifactPath; let artifactPath;
try { try {
artifactPath = await downloadArtifactFromLink( artifactPath = await downloadArtifactFromLink(
credentials, this.app.credentials,
this.storagePath, this.storagePath,
analysis.downloadLink, analysis.downloadLink,
); );

Просмотреть файл

@ -9,7 +9,6 @@ import {
window, window,
workspace, workspace,
} from "vscode"; } from "vscode";
import { Credentials } from "../authentication";
import { ProgressCallback, UserCancellationException } from "../commandRunner"; import { ProgressCallback, UserCancellationException } from "../commandRunner";
import { showInformationMessageWithAction } from "../helpers"; import { showInformationMessageWithAction } from "../helpers";
import { extLogger } from "../common"; import { extLogger } from "../common";
@ -37,6 +36,7 @@ import {
filterAndSortRepositoriesWithResults, filterAndSortRepositoriesWithResults,
RepositoriesFilterSortStateWithIds, RepositoriesFilterSortStateWithIds,
} from "../pure/variant-analysis-filter-sort"; } from "../pure/variant-analysis-filter-sort";
import { Credentials } from "../common/authentication";
/** /**
* Exports the results of the currently-selected remote query or variant analysis. * Exports the results of the currently-selected remote query or variant analysis.
@ -74,6 +74,7 @@ export async function exportRemoteQueryResults(
queryHistoryManager: QueryHistoryManager, queryHistoryManager: QueryHistoryManager,
remoteQueriesManager: RemoteQueriesManager, remoteQueriesManager: RemoteQueriesManager,
queryId: string, queryId: string,
credentials: Credentials,
): Promise<void> { ): Promise<void> {
const queryHistoryItem = queryHistoryManager.getRemoteQueryById(queryId); const queryHistoryItem = queryHistoryManager.getRemoteQueryById(queryId);
if (!queryHistoryItem) { if (!queryHistoryItem) {
@ -109,6 +110,7 @@ export async function exportRemoteQueryResults(
query, query,
analysesResults, analysesResults,
exportFormat, exportFormat,
credentials,
); );
} }
@ -117,6 +119,7 @@ export async function exportRemoteQueryAnalysisResults(
query: RemoteQuery, query: RemoteQuery,
analysesResults: AnalysisResults[], analysesResults: AnalysisResults[],
exportFormat: "gist" | "local", exportFormat: "gist" | "local",
credentials: Credentials,
) { ) {
const description = buildGistDescription(query, analysesResults); const description = buildGistDescription(query, analysesResults);
const markdownFiles = generateMarkdown(query, analysesResults, exportFormat); const markdownFiles = generateMarkdown(query, analysesResults, exportFormat);
@ -126,6 +129,7 @@ export async function exportRemoteQueryAnalysisResults(
description, description,
markdownFiles, markdownFiles,
exportFormat, exportFormat,
credentials,
); );
} }
@ -139,6 +143,7 @@ export async function exportVariantAnalysisResults(
variantAnalysisManager: VariantAnalysisManager, variantAnalysisManager: VariantAnalysisManager,
variantAnalysisId: number, variantAnalysisId: number,
filterSort: RepositoriesFilterSortStateWithIds | undefined, filterSort: RepositoriesFilterSortStateWithIds | undefined,
credentials: Credentials,
progress: ProgressCallback, progress: ProgressCallback,
token: CancellationToken, token: CancellationToken,
): Promise<void> { ): Promise<void> {
@ -238,6 +243,7 @@ export async function exportVariantAnalysisResults(
getAnalysesResults(), getAnalysesResults(),
repositories?.length ?? 0, repositories?.length ?? 0,
exportFormat, exportFormat,
credentials,
progress, progress,
token, token,
); );
@ -251,6 +257,7 @@ export async function exportVariantAnalysisAnalysisResults(
>, >,
expectedAnalysesResultsCount: number, expectedAnalysesResultsCount: number,
exportFormat: "gist" | "local", exportFormat: "gist" | "local",
credentials: Credentials,
progress: ProgressCallback, progress: ProgressCallback,
token: CancellationToken, token: CancellationToken,
) { ) {
@ -280,6 +287,7 @@ export async function exportVariantAnalysisAnalysisResults(
description, description,
markdownFiles, markdownFiles,
exportFormat, exportFormat,
credentials,
progress, progress,
token, token,
); );
@ -323,6 +331,7 @@ export async function exportResults(
description: string, description: string,
markdownFiles: MarkdownFile[], markdownFiles: MarkdownFile[],
exportFormat: "gist" | "local", exportFormat: "gist" | "local",
credentials: Credentials,
progress?: ProgressCallback, progress?: ProgressCallback,
token?: CancellationToken, token?: CancellationToken,
) { ) {
@ -331,7 +340,13 @@ export async function exportResults(
} }
if (exportFormat === "gist") { if (exportFormat === "gist") {
await exportToGist(description, markdownFiles, progress, token); await exportToGist(
description,
markdownFiles,
credentials,
progress,
token,
);
} else if (exportFormat === "local") { } else if (exportFormat === "local") {
await exportToLocalMarkdown( await exportToLocalMarkdown(
exportedResultsPath, exportedResultsPath,
@ -345,6 +360,7 @@ export async function exportResults(
export async function exportToGist( export async function exportToGist(
description: string, description: string,
markdownFiles: MarkdownFile[], markdownFiles: MarkdownFile[],
credentials: Credentials,
progress?: ProgressCallback, progress?: ProgressCallback,
token?: CancellationToken, token?: CancellationToken,
) { ) {
@ -354,8 +370,6 @@ export async function exportToGist(
message: "Creating Gist", message: "Creating Gist",
}); });
const credentials = await Credentials.initialize();
if (token?.isCancellationRequested) { if (token?.isCancellationRequested) {
throw new UserCancellationException("Cancelled"); throw new UserCancellationException("Cancelled");
} }

Просмотреть файл

@ -5,7 +5,7 @@ import {
showAndLogWarningMessage, showAndLogWarningMessage,
tmpDir, tmpDir,
} from "../../helpers"; } from "../../helpers";
import { Credentials } from "../../authentication"; import { Credentials } from "../../common/authentication";
import { extLogger } from "../../common"; import { extLogger } from "../../common";
import { RemoteQueryWorkflowResult } from "../remote-query-workflow-result"; import { RemoteQueryWorkflowResult } from "../remote-query-workflow-result";
import { DownloadLink, createDownloadPath } from "../download-link"; import { DownloadLink, createDownloadPath } from "../download-link";

Просмотреть файл

@ -1,5 +1,5 @@
import { Credentials } from "../../authentication";
import { OctokitResponse } from "@octokit/types/dist-types"; import { OctokitResponse } from "@octokit/types/dist-types";
import { Credentials } from "../../common/authentication";
import { RemoteQueriesSubmission } from "../shared/remote-queries"; import { RemoteQueriesSubmission } from "../shared/remote-queries";
import { VariantAnalysisSubmission } from "../shared/variant-analysis"; import { VariantAnalysisSubmission } from "../shared/variant-analysis";
import { import {

Просмотреть файл

@ -1,5 +1,5 @@
import { EOL } from "os"; import { EOL } from "os";
import { Credentials } from "../authentication"; import { Credentials } from "../common/authentication";
import { RepositorySelection } from "./repository-selection"; import { RepositorySelection } from "./repository-selection";
import { Repository } from "./shared/repository"; import { Repository } from "./shared/repository";
import { RemoteQueriesResponse } from "./gh-api/remote-queries"; import { RemoteQueriesResponse } from "./gh-api/remote-queries";

Просмотреть файл

@ -11,7 +11,6 @@ import { join } from "path";
import { writeFile, readFile, remove, pathExists } from "fs-extra"; import { writeFile, readFile, remove, pathExists } from "fs-extra";
import { EOL } from "os"; import { EOL } from "os";
import { Credentials } from "../authentication";
import { CodeQLCliServer } from "../cli"; import { CodeQLCliServer } from "../cli";
import { ProgressCallback } from "../commandRunner"; import { ProgressCallback } from "../commandRunner";
import { import {
@ -42,6 +41,7 @@ import { QueryStatus } from "../query-status";
import { DisposableObject } from "../pure/disposable-object"; import { DisposableObject } from "../pure/disposable-object";
import { AnalysisResults } from "./shared/analysis-result"; import { AnalysisResults } from "./shared/analysis-result";
import { runRemoteQueriesApiRequest } from "./remote-queries-api"; import { runRemoteQueriesApiRequest } from "./remote-queries-api";
import { App } from "../common/app";
const autoDownloadMaxSize = 300 * 1024; const autoDownloadMaxSize = 300 * 1024;
const autoDownloadMaxCount = 100; const autoDownloadMaxCount = 100;
@ -82,12 +82,14 @@ export class RemoteQueriesManager extends DisposableObject {
constructor( constructor(
ctx: ExtensionContext, ctx: ExtensionContext,
private readonly app: App,
private readonly cliServer: CodeQLCliServer, private readonly cliServer: CodeQLCliServer,
private readonly storagePath: string, private readonly storagePath: string,
logger: Logger, logger: Logger,
) { ) {
super(); super();
this.analysesResultsManager = new AnalysesResultsManager( this.analysesResultsManager = new AnalysesResultsManager(
app,
cliServer, cliServer,
storagePath, storagePath,
logger, logger,
@ -159,8 +161,6 @@ export class RemoteQueriesManager extends DisposableObject {
progress: ProgressCallback, progress: ProgressCallback,
token: CancellationToken, token: CancellationToken,
): Promise<void> { ): Promise<void> {
const credentials = await Credentials.initialize();
const { const {
actionBranch, actionBranch,
base64Pack, base64Pack,
@ -172,14 +172,14 @@ export class RemoteQueriesManager extends DisposableObject {
language, language,
} = await prepareRemoteQueryRun( } = await prepareRemoteQueryRun(
this.cliServer, this.cliServer,
credentials, this.app.credentials,
uri, uri,
progress, progress,
token, token,
); );
const apiResponse = await runRemoteQueriesApiRequest( const apiResponse = await runRemoteQueriesApiRequest(
credentials, this.app.credentials,
actionBranch, actionBranch,
language, language,
repoSelection, repoSelection,
@ -217,10 +217,9 @@ export class RemoteQueriesManager extends DisposableObject {
remoteQuery: RemoteQuery, remoteQuery: RemoteQuery,
cancellationToken: CancellationToken, cancellationToken: CancellationToken,
): Promise<void> { ): Promise<void> {
const credentials = await Credentials.initialize();
const queryWorkflowResult = await this.remoteQueriesMonitor.monitorQuery( const queryWorkflowResult = await this.remoteQueriesMonitor.monitorQuery(
remoteQuery, remoteQuery,
this.app.credentials,
cancellationToken, cancellationToken,
); );
@ -230,7 +229,6 @@ export class RemoteQueriesManager extends DisposableObject {
await this.downloadAvailableResults( await this.downloadAvailableResults(
queryId, queryId,
remoteQuery, remoteQuery,
credentials,
executionEndTime, executionEndTime,
); );
} else if (queryWorkflowResult.status === "CompletedUnsuccessfully") { } else if (queryWorkflowResult.status === "CompletedUnsuccessfully") {
@ -244,7 +242,6 @@ export class RemoteQueriesManager extends DisposableObject {
await this.downloadAvailableResults( await this.downloadAvailableResults(
queryId, queryId,
remoteQuery, remoteQuery,
credentials,
executionEndTime, executionEndTime,
); );
void showAndLogInformationMessage("Variant analysis was cancelled"); void showAndLogInformationMessage("Variant analysis was cancelled");
@ -267,7 +264,6 @@ export class RemoteQueriesManager extends DisposableObject {
await this.downloadAvailableResults( await this.downloadAvailableResults(
queryId, queryId,
remoteQuery, remoteQuery,
credentials,
executionEndTime, executionEndTime,
); );
void showAndLogInformationMessage("Variant analysis was cancelled"); void showAndLogInformationMessage("Variant analysis was cancelled");
@ -444,15 +440,14 @@ export class RemoteQueriesManager extends DisposableObject {
private async downloadAvailableResults( private async downloadAvailableResults(
queryId: string, queryId: string,
remoteQuery: RemoteQuery, remoteQuery: RemoteQuery,
credentials: Credentials,
executionEndTime: number, executionEndTime: number,
): Promise<void> { ): Promise<void> {
const resultIndex = await getRemoteQueryIndex(credentials, remoteQuery); const resultIndex = await getRemoteQueryIndex(
this.app.credentials,
remoteQuery,
);
if (resultIndex) { if (resultIndex) {
const metadata = await this.getRepositoriesMetadata( const metadata = await this.getRepositoriesMetadata(resultIndex);
resultIndex,
credentials,
);
const queryResult = this.mapQueryResult( const queryResult = this.mapQueryResult(
executionEndTime, executionEndTime,
resultIndex, resultIndex,
@ -494,12 +489,9 @@ export class RemoteQueriesManager extends DisposableObject {
} }
} }
private async getRepositoriesMetadata( private async getRepositoriesMetadata(resultIndex: RemoteQueryResultIndex) {
resultIndex: RemoteQueryResultIndex,
credentials: Credentials,
) {
const nwos = resultIndex.successes.map((s) => s.nwo); 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 // Pulled from the analysis results manager, so that we can get access to

Просмотреть файл

@ -1,6 +1,6 @@
import * as vscode from "vscode"; import * as vscode from "vscode";
import { Credentials } from "../authentication";
import { Logger } from "../common"; import { Logger } from "../common";
import { Credentials } from "../common/authentication";
import { sleep } from "../pure/time"; import { sleep } from "../pure/time";
import { import {
getWorkflowStatus, getWorkflowStatus,
@ -20,10 +20,9 @@ export class RemoteQueriesMonitor {
public async monitorQuery( public async monitorQuery(
remoteQuery: RemoteQuery, remoteQuery: RemoteQuery,
credentials: Credentials,
cancellationToken: vscode.CancellationToken, cancellationToken: vscode.CancellationToken,
): Promise<RemoteQueryWorkflowResult> { ): Promise<RemoteQueryWorkflowResult> {
const credentials = await Credentials.initialize();
let attemptCount = 0; let attemptCount = 0;
while (attemptCount <= RemoteQueriesMonitor.maxAttemptCount) { while (attemptCount <= RemoteQueriesMonitor.maxAttemptCount) {

Просмотреть файл

@ -10,7 +10,7 @@ import {
tryGetQueryMetadata, tryGetQueryMetadata,
tmpDir, tmpDir,
} from "../helpers"; } from "../helpers";
import { Credentials } from "../authentication"; import { Credentials } from "../common/authentication";
import * as cli from "../cli"; import * as cli from "../cli";
import { extLogger } from "../common"; import { extLogger } from "../common";
import { import {

Просмотреть файл

@ -16,7 +16,6 @@ import {
workspace, workspace,
} from "vscode"; } from "vscode";
import { DisposableObject } from "../pure/disposable-object"; import { DisposableObject } from "../pure/disposable-object";
import { Credentials } from "../authentication";
import { VariantAnalysisMonitor } from "./variant-analysis-monitor"; import { VariantAnalysisMonitor } from "./variant-analysis-monitor";
import { import {
getActionsWorkflowRunUrl, getActionsWorkflowRunUrl,
@ -62,6 +61,7 @@ import {
import { URLSearchParams } from "url"; import { URLSearchParams } from "url";
import { DbManager } from "../databases/db-manager"; import { DbManager } from "../databases/db-manager";
import { isVariantAnalysisReposPanelEnabled } from "../config"; import { isVariantAnalysisReposPanelEnabled } from "../config";
import { App } from "../common/app";
export class VariantAnalysisManager export class VariantAnalysisManager
extends DisposableObject extends DisposableObject
@ -100,6 +100,7 @@ export class VariantAnalysisManager
constructor( constructor(
private readonly ctx: ExtensionContext, private readonly ctx: ExtensionContext,
private readonly app: App,
private readonly cliServer: CodeQLCliServer, private readonly cliServer: CodeQLCliServer,
private readonly storagePath: string, private readonly storagePath: string,
private readonly variantAnalysisResultsManager: VariantAnalysisResultsManager, private readonly variantAnalysisResultsManager: VariantAnalysisResultsManager,
@ -126,8 +127,6 @@ export class VariantAnalysisManager
progress: ProgressCallback, progress: ProgressCallback,
token: CancellationToken, token: CancellationToken,
): Promise<void> { ): Promise<void> {
const credentials = await Credentials.initialize();
const { const {
actionBranch, actionBranch,
base64Pack, base64Pack,
@ -139,7 +138,7 @@ export class VariantAnalysisManager
language, language,
} = await prepareRemoteQueryRun( } = await prepareRemoteQueryRun(
this.cliServer, this.cliServer,
credentials, this.app.credentials,
uri, uri,
progress, progress,
token, token,
@ -175,7 +174,7 @@ export class VariantAnalysisManager
}; };
const variantAnalysisResponse = await submitVariantAnalysis( const variantAnalysisResponse = await submitVariantAnalysis(
credentials, this.app.credentials,
variantAnalysisSubmission, variantAnalysisSubmission,
); );
@ -456,6 +455,7 @@ export class VariantAnalysisManager
): Promise<void> { ): Promise<void> {
await this.variantAnalysisMonitor.monitorVariantAnalysis( await this.variantAnalysisMonitor.monitorVariantAnalysis(
variantAnalysis, variantAnalysis,
this.app.credentials,
cancellationToken, cancellationToken,
); );
} }
@ -480,8 +480,6 @@ export class VariantAnalysisManager
await this.onRepoStateUpdated(variantAnalysis.id, repoState); await this.onRepoStateUpdated(variantAnalysis.id, repoState);
const credentials = await Credentials.initialize();
if (cancellationToken && cancellationToken.isCancellationRequested) { if (cancellationToken && cancellationToken.isCancellationRequested) {
repoState.downloadStatus = repoState.downloadStatus =
VariantAnalysisScannedRepositoryDownloadStatus.Failed; VariantAnalysisScannedRepositoryDownloadStatus.Failed;
@ -492,7 +490,7 @@ export class VariantAnalysisManager
let repoTask: VariantAnalysisRepositoryTask; let repoTask: VariantAnalysisRepositoryTask;
try { try {
const repoTaskResponse = await getVariantAnalysisRepo( const repoTaskResponse = await getVariantAnalysisRepo(
credentials, this.app.credentials,
variantAnalysis.controllerRepo.id, variantAnalysis.controllerRepo.id,
variantAnalysis.id, variantAnalysis.id,
scannedRepo.repository.id, scannedRepo.repository.id,
@ -517,7 +515,6 @@ export class VariantAnalysisManager
try { try {
await this.variantAnalysisResultsManager.download( await this.variantAnalysisResultsManager.download(
credentials,
variantAnalysis.id, variantAnalysis.id,
repoTask, repoTask,
this.getVariantAnalysisStorageLocation(variantAnalysis.id), this.getVariantAnalysisStorageLocation(variantAnalysis.id),
@ -578,12 +575,10 @@ export class VariantAnalysisManager
); );
} }
const credentials = await Credentials.initialize();
void showAndLogInformationMessage( void showAndLogInformationMessage(
"Cancelling variant analysis. This may take a while.", "Cancelling variant analysis. This may take a while.",
); );
await cancelVariantAnalysis(credentials, variantAnalysis); await cancelVariantAnalysis(this.app.credentials, variantAnalysis);
} }
public async openVariantAnalysisLogs(variantAnalysisId: number) { public async openVariantAnalysisLogs(variantAnalysisId: number) {

Просмотреть файл

@ -1,5 +1,4 @@
import { CancellationToken, commands, EventEmitter } from "vscode"; import { CancellationToken, commands, EventEmitter } from "vscode";
import { Credentials } from "../authentication";
import { getVariantAnalysis } from "./gh-api/gh-api-client"; import { getVariantAnalysis } from "./gh-api/gh-api-client";
import { import {
@ -14,6 +13,7 @@ import { DisposableObject } from "../pure/disposable-object";
import { sleep } from "../pure/time"; import { sleep } from "../pure/time";
import { getErrorMessage } from "../pure/helpers-pure"; import { getErrorMessage } from "../pure/helpers-pure";
import { showAndLogWarningMessage } from "../helpers"; import { showAndLogWarningMessage } from "../helpers";
import { Credentials } from "../common/authentication";
export class VariantAnalysisMonitor extends DisposableObject { export class VariantAnalysisMonitor extends DisposableObject {
// With a sleep of 5 seconds, the maximum number of attempts takes // With a sleep of 5 seconds, the maximum number of attempts takes
@ -36,10 +36,9 @@ export class VariantAnalysisMonitor extends DisposableObject {
public async monitorVariantAnalysis( public async monitorVariantAnalysis(
variantAnalysis: VariantAnalysis, variantAnalysis: VariantAnalysis,
credentials: Credentials,
cancellationToken: CancellationToken, cancellationToken: CancellationToken,
): Promise<void> { ): Promise<void> {
const credentials = await Credentials.initialize();
let attemptCount = 0; let attemptCount = 0;
const scannedReposDownloaded: number[] = []; const scannedReposDownloaded: number[] = [];

Просмотреть файл

@ -8,7 +8,7 @@ import {
import { EOL } from "os"; import { EOL } from "os";
import { join } from "path"; import { join } from "path";
import { Credentials } from "../authentication"; import { Credentials } from "../common/authentication";
import { Logger } from "../common"; import { Logger } from "../common";
import { AnalysisAlert, AnalysisRawResults } from "./shared/analysis-result"; import { AnalysisAlert, AnalysisRawResults } from "./shared/analysis-result";
import { sarifParser } from "../sarif-parser"; import { sarifParser } from "../sarif-parser";
@ -63,6 +63,7 @@ export class VariantAnalysisResultsManager extends DisposableObject {
readonly onResultLoaded = this._onResultLoaded.event; readonly onResultLoaded = this._onResultLoaded.event;
constructor( constructor(
private readonly credentials: Credentials,
private readonly cliServer: CodeQLCliServer, private readonly cliServer: CodeQLCliServer,
private readonly logger: Logger, private readonly logger: Logger,
) { ) {
@ -71,7 +72,6 @@ export class VariantAnalysisResultsManager extends DisposableObject {
} }
public async download( public async download(
credentials: Credentials,
variantAnalysisId: number, variantAnalysisId: number,
repoTask: VariantAnalysisRepositoryTask, repoTask: VariantAnalysisRepositoryTask,
variantAnalysisStoragePath: string, variantAnalysisStoragePath: string,
@ -86,7 +86,7 @@ export class VariantAnalysisResultsManager extends DisposableObject {
); );
const result = await getVariantAnalysisRepoResult( const result = await getVariantAnalysisRepoResult(
credentials, this.credentials,
repoTask.artifactUrl, repoTask.artifactUrl,
); );

Просмотреть файл

@ -4,6 +4,8 @@ import { Memento } from "../../src/common/memento";
import { Disposable } from "../../src/pure/disposable-object"; import { Disposable } from "../../src/pure/disposable-object";
import { createMockLogger } from "./loggerMock"; import { createMockLogger } from "./loggerMock";
import { createMockMemento } from "../mock-memento"; import { createMockMemento } from "../mock-memento";
import { testCredentialsWithStub } from "../factories/authentication";
import { Credentials } from "../../src/common/authentication";
export function createMockApp({ export function createMockApp({
extensionPath = "/mock/extension/path", extensionPath = "/mock/extension/path",
@ -12,6 +14,7 @@ export function createMockApp({
createEventEmitter = <T>() => new MockAppEventEmitter<T>(), createEventEmitter = <T>() => new MockAppEventEmitter<T>(),
executeCommand = jest.fn(() => Promise.resolve()), executeCommand = jest.fn(() => Promise.resolve()),
workspaceState = createMockMemento(), workspaceState = createMockMemento(),
credentials = testCredentialsWithStub(),
}: { }: {
extensionPath?: string; extensionPath?: string;
workspaceStoragePath?: string; workspaceStoragePath?: string;
@ -19,6 +22,7 @@ export function createMockApp({
createEventEmitter?: <T>() => AppEventEmitter<T>; createEventEmitter?: <T>() => AppEventEmitter<T>;
executeCommand?: () => Promise<void>; executeCommand?: () => Promise<void>;
workspaceState?: Memento; workspaceState?: Memento;
credentials?: Credentials;
}): App { }): App {
return { return {
mode: AppMode.Test, mode: AppMode.Test,
@ -30,6 +34,7 @@ export function createMockApp({
workspaceState, workspaceState,
createEventEmitter, createEventEmitter,
executeCommand, executeCommand,
credentials,
}; };
} }

Просмотреть файл

@ -0,0 +1,38 @@
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",
);
},
};
}
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);
}
export function testCredentialsWithUnauthenticatedOctokit(): Credentials {
return makeTestOctokit(new Octokit.Octokit({ retry }));
}
export function testCredentialsWithToken(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 { faker } from "@faker-js/faker";
import { import {
@ -10,17 +7,15 @@ import {
getVariantAnalysisRepoResult, getVariantAnalysisRepoResult,
submitVariantAnalysis, submitVariantAnalysis,
} from "../../../../src/remote-queries/gh-api/gh-api-client"; } 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 { createMockSubmission } from "../../../factories/remote-queries/shared/variant-analysis-submission";
import { MockGitHubApiServer } from "../../../../src/mocks/mock-gh-api-server"; import { MockGitHubApiServer } from "../../../../src/mocks/mock-gh-api-server";
import { response } from "../../../../src/mocks/scenarios/problem-query-success/0-getRepo.json"; 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 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"; import { response as variantAnalysisRepoJson_response } from "../../../../src/mocks/scenarios/problem-query-success/9-getVariantAnalysisRepo.json";
import { testCredentialsWithUnauthenticatedOctokit } from "../../../factories/authentication";
const mockCredentials = { const mockCredentials = testCredentialsWithUnauthenticatedOctokit();
getOctokit: () => Promise.resolve(new Octokit_Octokit({ retry })),
} as unknown as Credentials;
const mockServer = new MockGitHubApiServer(); const mockServer = new MockGitHubApiServer();
beforeAll(() => mockServer.startServer()); beforeAll(() => mockServer.startServer());

Просмотреть файл

@ -25,11 +25,12 @@ import { OutputChannelLogger } from "../../../../src/common";
import { RemoteQueriesSubmission } from "../../../../src/remote-queries/shared/remote-queries"; import { RemoteQueriesSubmission } from "../../../../src/remote-queries/shared/remote-queries";
import { readBundledPack } from "../../utils/bundled-pack-helpers"; import { readBundledPack } from "../../utils/bundled-pack-helpers";
import { RemoteQueriesManager } from "../../../../src/remote-queries/remote-queries-manager"; import { RemoteQueriesManager } from "../../../../src/remote-queries/remote-queries-manager";
import { Credentials } from "../../../../src/authentication";
import { import {
fixWorkspaceReferences, fixWorkspaceReferences,
restoreWorkspaceReferences, restoreWorkspaceReferences,
} from "../global.helper"; } from "../global.helper";
import { createMockApp } from "../../../__mocks__/appMock";
import { App } from "../../../../src/common/app";
// up to 3 minutes per test // up to 3 minutes per test
jest.setTimeout(3 * 60 * 1000); jest.setTimeout(3 * 60 * 1000);
@ -50,6 +51,7 @@ describe("Remote queries", () => {
>; >;
let ctx: ExtensionContext; let ctx: ExtensionContext;
let logger: any; let logger: any;
let app: App;
let remoteQueriesManager: RemoteQueriesManager; let remoteQueriesManager: RemoteQueriesManager;
let originalDeps: Record<string, string> | undefined; let originalDeps: Record<string, string> | undefined;
@ -74,8 +76,10 @@ describe("Remote queries", () => {
ctx = createMockExtensionContext(); ctx = createMockExtensionContext();
logger = new OutputChannelLogger("test-logger"); logger = new OutputChannelLogger("test-logger");
app = createMockApp({});
remoteQueriesManager = new RemoteQueriesManager( remoteQueriesManager = new RemoteQueriesManager(
ctx, ctx,
app,
cli, cli,
"fake-storage-dir", "fake-storage-dir",
logger, logger,
@ -104,14 +108,6 @@ describe("Remote queries", () => {
"vscode-codeql": ["github/vscode-codeql"], "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 // Only new version support `${workspace}` in qlpack.yml
originalDeps = await fixWorkspaceReferences( originalDeps = await fixWorkspaceReferences(
qlpackFileWithWorkspaceRefs, qlpackFileWithWorkspaceRefs,

Просмотреть файл

@ -19,7 +19,6 @@ import {
} from "../../../../src/config"; } from "../../../../src/config";
import * as ghApiClient from "../../../../src/remote-queries/gh-api/gh-api-client"; 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 * as ghActionsApiClient from "../../../../src/remote-queries/gh-api/gh-actions-api-client";
import { Credentials } from "../../../../src/authentication";
import * as fs from "fs-extra"; import * as fs from "fs-extra";
import { join } from "path"; import { join } from "path";
@ -58,12 +57,15 @@ import {
SortKey, SortKey,
} from "../../../../src/pure/variant-analysis-filter-sort"; } from "../../../../src/pure/variant-analysis-filter-sort";
import { DbManager } from "../../../../src/databases/db-manager"; import { DbManager } from "../../../../src/databases/db-manager";
import { App } from "../../../../src/common/app";
import { createMockApp } from "../../../__mocks__/appMock";
// up to 3 minutes per test // up to 3 minutes per test
jest.setTimeout(3 * 60 * 1000); jest.setTimeout(3 * 60 * 1000);
describe("Variant Analysis Manager", () => { describe("Variant Analysis Manager", () => {
let cli: CodeQLCliServer; let cli: CodeQLCliServer;
let app: App;
let cancellationTokenSource: CancellationTokenSource; let cancellationTokenSource: CancellationTokenSource;
let variantAnalysisManager: VariantAnalysisManager; let variantAnalysisManager: VariantAnalysisManager;
let variantAnalysisResultsManager: VariantAnalysisResultsManager; let variantAnalysisResultsManager: VariantAnalysisResultsManager;
@ -91,12 +93,15 @@ describe("Variant Analysis Manager", () => {
)! )!
.activate(); .activate();
cli = extension.cliServer; cli = extension.cliServer;
app = createMockApp({});
variantAnalysisResultsManager = new VariantAnalysisResultsManager( variantAnalysisResultsManager = new VariantAnalysisResultsManager(
app.credentials,
cli, cli,
extLogger, extLogger,
); );
variantAnalysisManager = new VariantAnalysisManager( variantAnalysisManager = new VariantAnalysisManager(
extension.ctx, extension.ctx,
app,
cli, cli,
storagePath, storagePath,
variantAnalysisResultsManager, variantAnalysisResultsManager,
@ -127,14 +132,6 @@ describe("Variant Analysis Manager", () => {
} }
beforeEach(async () => { 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 // Should not have asked for a language
showQuickPickSpy = jest showQuickPickSpy = jest
.spyOn(window, "showQuickPick") .spyOn(window, "showQuickPick")
@ -349,14 +346,6 @@ describe("Variant Analysis Manager", () => {
let repoStatesPath: string; let repoStatesPath: string;
beforeEach(async () => { beforeEach(async () => {
const mockCredentials = {
getOctokit: () =>
Promise.resolve({
request: jest.fn(),
}),
} as unknown as Credentials;
jest.spyOn(Credentials, "initialize").mockResolvedValue(mockCredentials);
const sourceFilePath = join( const sourceFilePath = join(
__dirname, __dirname,
"../data/variant-analysis-results.zip", "../data/variant-analysis-results.zip",
@ -612,16 +601,6 @@ describe("Variant Analysis Manager", () => {
}); });
describe("enqueueDownload", () => { 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 () => { it("should pop download tasks off the queue", async () => {
const getResultsSpy = jest const getResultsSpy = jest
.spyOn(variantAnalysisManager, "autoDownloadVariantAnalysisResult") .spyOn(variantAnalysisManager, "autoDownloadVariantAnalysisResult")
@ -782,8 +761,6 @@ describe("Variant Analysis Manager", () => {
let variantAnalysisStorageLocation: string; let variantAnalysisStorageLocation: string;
let mockCredentials: Credentials;
beforeEach(async () => { beforeEach(async () => {
variantAnalysis = createMockVariantAnalysis({}); variantAnalysis = createMockVariantAnalysis({});
@ -797,14 +774,6 @@ describe("Variant Analysis Manager", () => {
); );
await createTimestampFile(variantAnalysisStorageLocation); await createTimestampFile(variantAnalysisStorageLocation);
await variantAnalysisManager.rehydrateVariantAnalysis(variantAnalysis); await variantAnalysisManager.rehydrateVariantAnalysis(variantAnalysis);
mockCredentials = {
getOctokit: () =>
Promise.resolve({
request: jest.fn(),
}),
} as unknown as Credentials;
jest.spyOn(Credentials, "initialize").mockResolvedValue(mockCredentials);
}); });
afterEach(() => { afterEach(() => {
@ -842,7 +811,7 @@ describe("Variant Analysis Manager", () => {
await variantAnalysisManager.cancelVariantAnalysis(variantAnalysis.id); await variantAnalysisManager.cancelVariantAnalysis(variantAnalysis.id);
expect(mockCancelVariantAnalysis).toBeCalledWith( expect(mockCancelVariantAnalysis).toBeCalledWith(
mockCredentials, app.credentials,
variantAnalysis, variantAnalysis,
); );
}); });

Просмотреть файл

@ -23,9 +23,9 @@ import {
processScannedRepository, processScannedRepository,
processUpdatedVariantAnalysis, processUpdatedVariantAnalysis,
} from "../../../../src/remote-queries/variant-analysis-processor"; } from "../../../../src/remote-queries/variant-analysis-processor";
import { Credentials } from "../../../../src/authentication";
import { createMockVariantAnalysis } from "../../../factories/remote-queries/shared/variant-analysis"; import { createMockVariantAnalysis } from "../../../factories/remote-queries/shared/variant-analysis";
import { VariantAnalysisManager } from "../../../../src/remote-queries/variant-analysis-manager"; import { VariantAnalysisManager } from "../../../../src/remote-queries/variant-analysis-manager";
import { testCredentialsWithStub } from "../../../factories/authentication";
jest.setTimeout(60_000); jest.setTimeout(60_000);
@ -74,14 +74,6 @@ describe("Variant Analysis Monitor", () => {
.mockRejectedValue(new Error("Not mocked")); .mockRejectedValue(new Error("Not mocked"));
limitNumberOfAttemptsToMonitor(); 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 () => { it("should return early if variant analysis is cancelled", async () => {
@ -89,6 +81,7 @@ describe("Variant Analysis Monitor", () => {
await variantAnalysisMonitor.monitorVariantAnalysis( await variantAnalysisMonitor.monitorVariantAnalysis(
variantAnalysis, variantAnalysis,
testCredentialsWithStub(),
cancellationTokenSource.token, cancellationTokenSource.token,
); );
@ -100,6 +93,7 @@ describe("Variant Analysis Monitor", () => {
await variantAnalysisMonitor.monitorVariantAnalysis( await variantAnalysisMonitor.monitorVariantAnalysis(
variantAnalysis, variantAnalysis,
testCredentialsWithStub(),
cancellationTokenSource.token, cancellationTokenSource.token,
); );
@ -117,6 +111,7 @@ describe("Variant Analysis Monitor", () => {
it("should mark as failed and stop monitoring", async () => { it("should mark as failed and stop monitoring", async () => {
await variantAnalysisMonitor.monitorVariantAnalysis( await variantAnalysisMonitor.monitorVariantAnalysis(
variantAnalysis, variantAnalysis,
testCredentialsWithStub(),
cancellationTokenSource.token, cancellationTokenSource.token,
); );
@ -166,6 +161,7 @@ describe("Variant Analysis Monitor", () => {
await variantAnalysisMonitor.monitorVariantAnalysis( await variantAnalysisMonitor.monitorVariantAnalysis(
variantAnalysis, variantAnalysis,
testCredentialsWithStub(),
cancellationTokenSource.token, cancellationTokenSource.token,
); );
@ -184,6 +180,7 @@ describe("Variant Analysis Monitor", () => {
it("should download all available results", async () => { it("should download all available results", async () => {
await variantAnalysisMonitor.monitorVariantAnalysis( await variantAnalysisMonitor.monitorVariantAnalysis(
variantAnalysis, variantAnalysis,
testCredentialsWithStub(),
cancellationTokenSource.token, cancellationTokenSource.token,
); );
@ -216,6 +213,7 @@ describe("Variant Analysis Monitor", () => {
await variantAnalysisMonitor.monitorVariantAnalysis( await variantAnalysisMonitor.monitorVariantAnalysis(
variantAnalysis, variantAnalysis,
testCredentialsWithStub(),
cancellationTokenSource.token, cancellationTokenSource.token,
); );
@ -225,6 +223,7 @@ describe("Variant Analysis Monitor", () => {
it("should not try to download any repos", async () => { it("should not try to download any repos", async () => {
await variantAnalysisMonitor.monitorVariantAnalysis( await variantAnalysisMonitor.monitorVariantAnalysis(
variantAnalysis, variantAnalysis,
testCredentialsWithStub(),
cancellationTokenSource.token, cancellationTokenSource.token,
); );
@ -283,6 +282,7 @@ describe("Variant Analysis Monitor", () => {
await variantAnalysisMonitor.monitorVariantAnalysis( await variantAnalysisMonitor.monitorVariantAnalysis(
variantAnalysis, variantAnalysis,
testCredentialsWithStub(),
cancellationTokenSource.token, cancellationTokenSource.token,
); );
@ -301,6 +301,7 @@ describe("Variant Analysis Monitor", () => {
it("should not try to download any repos", async () => { it("should not try to download any repos", async () => {
await variantAnalysisMonitor.monitorVariantAnalysis( await variantAnalysisMonitor.monitorVariantAnalysis(
variantAnalysis, variantAnalysis,
testCredentialsWithStub(),
cancellationTokenSource.token, cancellationTokenSource.token,
); );

Просмотреть файл

@ -1,7 +1,6 @@
import { extensions } from "vscode"; import { extensions } from "vscode";
import { CodeQLExtensionInterface } from "../../../../src/extension"; import { CodeQLExtensionInterface } from "../../../../src/extension";
import { extLogger } from "../../../../src/common"; import { extLogger } from "../../../../src/common";
import { Credentials } from "../../../../src/authentication";
import * as fs from "fs-extra"; import * as fs from "fs-extra";
import { join, resolve } from "path"; import { join, resolve } from "path";
@ -15,6 +14,8 @@ import {
VariantAnalysisRepositoryTask, VariantAnalysisRepositoryTask,
VariantAnalysisScannedRepositoryResult, VariantAnalysisScannedRepositoryResult,
} from "../../../../src/remote-queries/shared/variant-analysis"; } from "../../../../src/remote-queries/shared/variant-analysis";
import { testCredentialsWithStub } from "../../../factories/authentication";
import { Credentials } from "../../../../src/common/authentication";
jest.setTimeout(10_000); jest.setTimeout(10_000);
@ -34,12 +35,6 @@ describe(VariantAnalysisResultsManager.name, () => {
}); });
describe("download", () => { describe("download", () => {
const mockCredentials = {
getOctokit: () =>
Promise.resolve({
request: jest.fn(),
}),
} as unknown as Credentials;
let dummyRepoTask: VariantAnalysisRepositoryTask; let dummyRepoTask: VariantAnalysisRepositoryTask;
let variantAnalysisStoragePath: string; let variantAnalysisStoragePath: string;
let repoTaskStorageDirectory: string; let repoTaskStorageDirectory: string;
@ -49,6 +44,7 @@ describe(VariantAnalysisResultsManager.name, () => {
jest.spyOn(extLogger, "log").mockResolvedValue(undefined); jest.spyOn(extLogger, "log").mockResolvedValue(undefined);
variantAnalysisResultsManager = new VariantAnalysisResultsManager( variantAnalysisResultsManager = new VariantAnalysisResultsManager(
testCredentialsWithStub(),
cli, cli,
extLogger, extLogger,
); );
@ -90,7 +86,6 @@ describe(VariantAnalysisResultsManager.name, () => {
await expect( await expect(
variantAnalysisResultsManager.download( variantAnalysisResultsManager.download(
mockCredentials,
variantAnalysisId, variantAnalysisId,
dummyRepoTask, dummyRepoTask,
variantAnalysisStoragePath, variantAnalysisStoragePath,
@ -127,7 +122,6 @@ describe(VariantAnalysisResultsManager.name, () => {
it("should call the API to download the results", async () => { it("should call the API to download the results", async () => {
await variantAnalysisResultsManager.download( await variantAnalysisResultsManager.download(
mockCredentials,
variantAnalysisId, variantAnalysisId,
dummyRepoTask, dummyRepoTask,
variantAnalysisStoragePath, variantAnalysisStoragePath,
@ -138,7 +132,6 @@ describe(VariantAnalysisResultsManager.name, () => {
it("should save the results zip file to disk", async () => { it("should save the results zip file to disk", async () => {
await variantAnalysisResultsManager.download( await variantAnalysisResultsManager.download(
mockCredentials,
variantAnalysisId, variantAnalysisId,
dummyRepoTask, dummyRepoTask,
variantAnalysisStoragePath, variantAnalysisStoragePath,
@ -151,7 +144,6 @@ describe(VariantAnalysisResultsManager.name, () => {
it("should unzip the results in a `results/` folder", async () => { it("should unzip the results in a `results/` folder", async () => {
await variantAnalysisResultsManager.download( await variantAnalysisResultsManager.download(
mockCredentials,
variantAnalysisId, variantAnalysisId,
dummyRepoTask, dummyRepoTask,
variantAnalysisStoragePath, variantAnalysisStoragePath,
@ -165,7 +157,6 @@ describe(VariantAnalysisResultsManager.name, () => {
describe("isVariantAnalysisRepoDownloaded", () => { describe("isVariantAnalysisRepoDownloaded", () => {
it("should return true once results are downloaded", async () => { it("should return true once results are downloaded", async () => {
await variantAnalysisResultsManager.download( await variantAnalysisResultsManager.download(
mockCredentials,
variantAnalysisId, variantAnalysisId,
dummyRepoTask, dummyRepoTask,
variantAnalysisStoragePath, variantAnalysisStoragePath,
@ -194,6 +185,7 @@ describe(VariantAnalysisResultsManager.name, () => {
beforeEach(() => { beforeEach(() => {
variantAnalysisResultsManager = new VariantAnalysisResultsManager( variantAnalysisResultsManager = new VariantAnalysisResultsManager(
testCredentialsWithStub(),
cli, cli,
extLogger, extLogger,
); );

Просмотреть файл

@ -9,11 +9,8 @@ import {
window, window,
workspace, workspace,
} from "vscode"; } from "vscode";
import { Octokit } from "@octokit/rest";
import { retry } from "@octokit/plugin-retry";
import { CodeQLExtensionInterface } from "../../../../src/extension"; import { CodeQLExtensionInterface } from "../../../../src/extension";
import { Credentials } from "../../../../src/authentication";
import { MockGitHubApiServer } from "../../../../src/mocks/mock-gh-api-server"; import { MockGitHubApiServer } from "../../../../src/mocks/mock-gh-api-server";
jest.setTimeout(30_000); 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 quickPickSpy = jest
.spyOn(window, "showQuickPick") .spyOn(window, "showQuickPick")
.mockResolvedValue(undefined); .mockResolvedValue(undefined);

Просмотреть файл

@ -11,7 +11,7 @@ import { Uri } from "vscode";
import { DatabaseUI } from "../../../src/databases-ui"; import { DatabaseUI } from "../../../src/databases-ui";
import { testDisposeHandler } from "../test-dispose-handler"; import { testDisposeHandler } from "../test-dispose-handler";
import { Credentials } from "../../../src/authentication"; import { createMockApp } from "../../__mocks__/appMock";
describe("databases-ui", () => { describe("databases-ui", () => {
describe("fixDbUri", () => { describe("fixDbUri", () => {
@ -82,7 +82,9 @@ describe("databases-ui", () => {
"codeql-database.yml", "codeql-database.yml",
); );
const app = createMockApp({});
const databaseUI = new DatabaseUI( const databaseUI = new DatabaseUI(
app,
{ {
databaseItems: [{ databaseUri: Uri.file(db1) }], databaseItems: [{ databaseUri: Uri.file(db1) }],
onDidChangeDatabaseItem: () => { onDidChangeDatabaseItem: () => {
@ -95,7 +97,6 @@ describe("databases-ui", () => {
{} as any, {} as any,
storageDir, storageDir,
storageDir, storageDir,
() => Promise.resolve({} as Credentials),
); );
await databaseUI.handleRemoveOrphanedDatabases(); await databaseUI.handleRemoveOrphanedDatabases();

Просмотреть файл

@ -42,10 +42,12 @@ import { VariantAnalysisHistoryItem } from "../../../src/remote-queries/variant-
import { QueryStatus } from "../../../src/query-status"; import { QueryStatus } from "../../../src/query-status";
import { VariantAnalysisStatus } from "../../../src/remote-queries/shared/variant-analysis"; import { VariantAnalysisStatus } from "../../../src/remote-queries/shared/variant-analysis";
import * as ghActionsApiClient from "../../../src/remote-queries/gh-api/gh-actions-api-client"; import * as ghActionsApiClient from "../../../src/remote-queries/gh-api/gh-actions-api-client";
import { Credentials } from "../../../src/authentication";
import { QuickPickItem, TextEditor } from "vscode"; import { QuickPickItem, TextEditor } from "vscode";
import { WebviewReveal } from "../../../src/interface-utils"; import { WebviewReveal } from "../../../src/interface-utils";
import * as helpers from "../../../src/helpers"; import * as helpers from "../../../src/helpers";
import { testCredentialsWithStub } from "../../factories/authentication";
import { createMockApp } from "../../__mocks__/appMock";
import { Credentials } from "../../../src/common/authentication";
describe("query-history", () => { describe("query-history", () => {
const mockExtensionLocation = join(tmpDir.name, "mock-extension-location"); const mockExtensionLocation = join(tmpDir.name, "mock-extension-location");
@ -873,23 +875,13 @@ describe("query-history", () => {
}); });
describe("handleCancel", () => { describe("handleCancel", () => {
let mockCredentials: Credentials;
let mockCancelRemoteQuery: jest.SpiedFunction< let mockCancelRemoteQuery: jest.SpiedFunction<
typeof ghActionsApiClient.cancelRemoteQuery typeof ghActionsApiClient.cancelRemoteQuery
>; >;
const getOctokitStub = jest.fn(); const getOctokitStub = jest.fn();
const mockCredentials = testCredentialsWithStub(getOctokitStub);
beforeEach(async () => { beforeEach(async () => {
mockCredentials = {
getOctokit: () =>
Promise.resolve({
request: getOctokitStub,
}),
} as unknown as Credentials;
jest
.spyOn(Credentials, "initialize")
.mockResolvedValue(mockCredentials);
mockCancelRemoteQuery = jest mockCancelRemoteQuery = jest
.spyOn(ghActionsApiClient, "cancelRemoteQuery") .spyOn(ghActionsApiClient, "cancelRemoteQuery")
.mockResolvedValue(); .mockResolvedValue();
@ -897,7 +889,10 @@ describe("query-history", () => {
describe("if the item is in progress", () => { describe("if the item is in progress", () => {
it("should cancel a single local query", async () => { it("should cancel a single local query", async () => {
queryHistoryManager = await createMockQueryHistory(localQueryHistory); queryHistoryManager = await createMockQueryHistory(
localQueryHistory,
mockCredentials,
);
// cancelling the selected item // cancelling the selected item
const inProgress1 = localQueryHistory[4]; const inProgress1 = localQueryHistory[4];
@ -908,7 +903,10 @@ describe("query-history", () => {
}); });
it("should cancel multiple local queries", async () => { it("should cancel multiple local queries", async () => {
queryHistoryManager = await createMockQueryHistory(localQueryHistory); queryHistoryManager = await createMockQueryHistory(
localQueryHistory,
mockCredentials,
);
// cancelling the selected item // cancelling the selected item
const inProgress1 = localQueryHistory[4]; const inProgress1 = localQueryHistory[4];
@ -926,7 +924,10 @@ describe("query-history", () => {
}); });
it("should cancel a single remote query", async () => { it("should cancel a single remote query", async () => {
queryHistoryManager = await createMockQueryHistory(allHistory); queryHistoryManager = await createMockQueryHistory(
allHistory,
mockCredentials,
);
// cancelling the selected item // cancelling the selected item
const inProgress1 = remoteQueryHistory[2]; const inProgress1 = remoteQueryHistory[2];
@ -939,7 +940,10 @@ describe("query-history", () => {
}); });
it("should cancel multiple remote queries", async () => { it("should cancel multiple remote queries", async () => {
queryHistoryManager = await createMockQueryHistory(allHistory); queryHistoryManager = await createMockQueryHistory(
allHistory,
mockCredentials,
);
// cancelling the selected item // cancelling the selected item
const inProgress1 = remoteQueryHistory[2]; const inProgress1 = remoteQueryHistory[2];
@ -960,7 +964,10 @@ describe("query-history", () => {
}); });
it("should cancel a single variant analysis", async () => { it("should cancel a single variant analysis", async () => {
queryHistoryManager = await createMockQueryHistory(allHistory); queryHistoryManager = await createMockQueryHistory(
allHistory,
mockCredentials,
);
// cancelling the selected item // cancelling the selected item
const inProgress1 = variantAnalysisHistory[1]; const inProgress1 = variantAnalysisHistory[1];
@ -973,7 +980,10 @@ describe("query-history", () => {
}); });
it("should cancel multiple variant analyses", async () => { it("should cancel multiple variant analyses", async () => {
queryHistoryManager = await createMockQueryHistory(allHistory); queryHistoryManager = await createMockQueryHistory(
allHistory,
mockCredentials,
);
// cancelling the selected item // cancelling the selected item
const inProgress1 = variantAnalysisHistory[1]; const inProgress1 = variantAnalysisHistory[1];
@ -996,7 +1006,10 @@ describe("query-history", () => {
describe("if the item is not in progress", () => { describe("if the item is not in progress", () => {
it("should not cancel a single local query", async () => { it("should not cancel a single local query", async () => {
queryHistoryManager = await createMockQueryHistory(localQueryHistory); queryHistoryManager = await createMockQueryHistory(
localQueryHistory,
mockCredentials,
);
// cancelling the selected item // cancelling the selected item
const completed = localQueryHistory[0]; const completed = localQueryHistory[0];
@ -1007,7 +1020,10 @@ describe("query-history", () => {
}); });
it("should not cancel multiple local queries", async () => { it("should not cancel multiple local queries", async () => {
queryHistoryManager = await createMockQueryHistory(localQueryHistory); queryHistoryManager = await createMockQueryHistory(
localQueryHistory,
mockCredentials,
);
// cancelling the selected item // cancelling the selected item
const completed = localQueryHistory[0]; const completed = localQueryHistory[0];
@ -1025,7 +1041,10 @@ describe("query-history", () => {
}); });
it("should not cancel a single remote query", async () => { it("should not cancel a single remote query", async () => {
queryHistoryManager = await createMockQueryHistory(allHistory); queryHistoryManager = await createMockQueryHistory(
allHistory,
mockCredentials,
);
// cancelling the selected item // cancelling the selected item
const completed = remoteQueryHistory[0]; const completed = remoteQueryHistory[0];
@ -1038,7 +1057,10 @@ describe("query-history", () => {
}); });
it("should not cancel multiple remote queries", async () => { it("should not cancel multiple remote queries", async () => {
queryHistoryManager = await createMockQueryHistory(allHistory); queryHistoryManager = await createMockQueryHistory(
allHistory,
mockCredentials,
);
// cancelling the selected item // cancelling the selected item
const completed = remoteQueryHistory[0]; const completed = remoteQueryHistory[0];
@ -1059,7 +1081,10 @@ describe("query-history", () => {
}); });
it("should not cancel a single variant analysis", async () => { it("should not cancel a single variant analysis", async () => {
queryHistoryManager = await createMockQueryHistory(allHistory); queryHistoryManager = await createMockQueryHistory(
allHistory,
mockCredentials,
);
// cancelling the selected item // cancelling the selected item
const completedVariantAnalysis = variantAnalysisHistory[0]; const completedVariantAnalysis = variantAnalysisHistory[0];
@ -1074,7 +1099,10 @@ describe("query-history", () => {
}); });
it("should not cancel multiple variant analyses", async () => { it("should not cancel multiple variant analyses", async () => {
queryHistoryManager = await createMockQueryHistory(allHistory); queryHistoryManager = await createMockQueryHistory(
allHistory,
mockCredentials,
);
// cancelling the selected item // cancelling the selected item
const completedVariantAnalysis = variantAnalysisHistory[0]; const completedVariantAnalysis = variantAnalysisHistory[0];
@ -1985,8 +2013,12 @@ describe("query-history", () => {
}); });
}); });
async function createMockQueryHistory(allHistory: QueryHistoryInfo[]) { async function createMockQueryHistory(
allHistory: QueryHistoryInfo[],
credentials?: Credentials,
) {
const qhm = new QueryHistoryManager( const qhm = new QueryHistoryManager(
createMockApp({ credentials }),
{} as QueryRunner, {} as QueryRunner,
{} as DatabaseManager, {} as DatabaseManager,
localQueriesResultsViewStub, localQueriesResultsViewStub,

Просмотреть файл

@ -1,17 +1,14 @@
import { join } from "path"; import { join } from "path";
import { readFile } from "fs-extra"; import { readFile } from "fs-extra";
import { Credentials } from "../../../../src/authentication";
import * as markdownGenerator from "../../../../src/remote-queries/remote-queries-markdown-generation"; import * as markdownGenerator from "../../../../src/remote-queries/remote-queries-markdown-generation";
import * as ghApiClient from "../../../../src/remote-queries/gh-api/gh-api-client"; import * as ghApiClient from "../../../../src/remote-queries/gh-api/gh-api-client";
import { exportRemoteQueryAnalysisResults } from "../../../../src/remote-queries/export-results"; import { exportRemoteQueryAnalysisResults } from "../../../../src/remote-queries/export-results";
import { testCredentialsWithStub } from "../../../factories/authentication";
describe("export results", () => { describe("export results", () => {
describe("exportRemoteQueryAnalysisResults", () => { describe("exportRemoteQueryAnalysisResults", () => {
const mockCredentials = {} as unknown as Credentials;
beforeEach(() => { beforeEach(() => {
jest.spyOn(markdownGenerator, "generateMarkdown").mockReturnValue([]); 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 () { it("should call the GitHub Actions API with the correct gist title", async function () {
@ -43,6 +40,7 @@ describe("export results", () => {
query, query,
analysesResults, analysesResults,
"gist", "gist",
testCredentialsWithStub(),
); );
expect(mockCreateGist).toHaveBeenCalledTimes(1); expect(mockCreateGist).toHaveBeenCalledTimes(1);

Просмотреть файл

@ -1,4 +1,3 @@
import { Credentials } from "../../../../../src/authentication";
import { import {
cancelRemoteQuery, cancelRemoteQuery,
cancelVariantAnalysis, cancelVariantAnalysis,
@ -7,17 +6,16 @@ import {
import { RemoteQuery } from "../../../../../src/remote-queries/remote-query"; import { RemoteQuery } from "../../../../../src/remote-queries/remote-query";
import { createMockVariantAnalysis } from "../../../../factories/remote-queries/shared/variant-analysis"; import { createMockVariantAnalysis } from "../../../../factories/remote-queries/shared/variant-analysis";
import { VariantAnalysis } from "../../../../../src/remote-queries/shared/variant-analysis"; import { VariantAnalysis } from "../../../../../src/remote-queries/shared/variant-analysis";
import {
testCredentialsWithStub,
testCredentialsWithToken,
} from "../../../../factories/authentication";
jest.setTimeout(10000); jest.setTimeout(10000);
describe("gh-actions-api-client mock responses", () => { describe("gh-actions-api-client mock responses", () => {
const mockRequest = jest.fn(); const mockRequest = jest.fn();
const mockCredentials = { const mockCredentials = testCredentialsWithStub(mockRequest);
getOctokit: () =>
Promise.resolve({
request: mockRequest,
}),
} as unknown as Credentials;
describe("cancelRemoteQuery", () => { describe("cancelRemoteQuery", () => {
it("should cancel a remote query", async () => { it("should cancel a remote query", async () => {
@ -95,7 +93,7 @@ describe("gh-actions-api-client real responses", () => {
return; return;
} }
const credentials = await Credentials.initializeWithToken( const credentials = testCredentialsWithToken(
process.env.VSCODE_CODEQL_GITHUB_TOKEN!, process.env.VSCODE_CODEQL_GITHUB_TOKEN!,
); );
const stargazers = await getRepositoriesMetadata( const stargazers = await getRepositoriesMetadata(

Просмотреть файл

@ -21,7 +21,6 @@ import { QueryHistoryConfig } from "../../../../src/config";
import { DatabaseManager } from "../../../../src/databases"; import { DatabaseManager } from "../../../../src/databases";
import { tmpDir, walkDirectory } from "../../../../src/helpers"; import { tmpDir, walkDirectory } from "../../../../src/helpers";
import { QueryHistoryManager } from "../../../../src/query-history"; import { QueryHistoryManager } from "../../../../src/query-history";
import { Credentials } from "../../../../src/authentication";
import { AnalysesResultsManager } from "../../../../src/remote-queries/analyses-results-manager"; import { AnalysesResultsManager } from "../../../../src/remote-queries/analyses-results-manager";
import { RemoteQueryResult } from "../../../../src/remote-queries/shared/remote-query-result"; import { RemoteQueryResult } from "../../../../src/remote-queries/shared/remote-query-result";
import { DisposableBucket } from "../../disposable-bucket"; import { DisposableBucket } from "../../disposable-bucket";
@ -32,6 +31,9 @@ import { ResultsView } from "../../../../src/interface";
import { EvalLogViewer } from "../../../../src/eval-log-viewer"; import { EvalLogViewer } from "../../../../src/eval-log-viewer";
import { QueryRunner } from "../../../../src/queryRunner"; import { QueryRunner } from "../../../../src/queryRunner";
import { VariantAnalysisManager } from "../../../../src/remote-queries/variant-analysis-manager"; 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. // set a higher timeout since recursive delete may take a while, expecially on Windows.
jest.setTimeout(120000); jest.setTimeout(120000);
@ -47,6 +49,8 @@ describe("Remote queries and query history manager", () => {
/** noop */ /** noop */
}; };
const mockOctokit = jest.fn();
let app: App;
let qhm: QueryHistoryManager; let qhm: QueryHistoryManager;
const localQueriesResultsViewStub = { const localQueriesResultsViewStub = {
showResults: jest.fn(), showResults: jest.fn(),
@ -107,7 +111,9 @@ describe("Remote queries and query history manager", () => {
), ),
); );
app = createMockApp({ credentials: testCredentialsWithStub(mockOctokit) });
qhm = new QueryHistoryManager( qhm = new QueryHistoryManager(
app,
{} as QueryRunner, {} as QueryRunner,
{} as DatabaseManager, {} as DatabaseManager,
localQueriesResultsViewStub, localQueriesResultsViewStub,
@ -256,19 +262,11 @@ describe("Remote queries and query history manager", () => {
}); });
describe("AnalysisResultsManager", () => { describe("AnalysisResultsManager", () => {
let mockCredentials: any;
let mockOctokit: any;
let mockLogger: any; let mockLogger: any;
let mockCliServer: any; let mockCliServer: any;
let arm: AnalysesResultsManager; let arm: AnalysesResultsManager;
beforeEach(() => { beforeEach(() => {
mockOctokit = {
request: jest.fn(),
};
mockCredentials = {
getOctokit: () => mockOctokit,
};
mockLogger = { mockLogger = {
log: jest.fn(), log: jest.fn(),
}; };
@ -276,9 +274,9 @@ describe("Remote queries and query history manager", () => {
bqrsInfo: jest.fn(), bqrsInfo: jest.fn(),
bqrsDecode: jest.fn(), bqrsDecode: jest.fn(),
}; };
jest.spyOn(Credentials, "initialize").mockResolvedValue(mockCredentials);
arm = new AnalysesResultsManager( arm = new AnalysesResultsManager(
app,
mockCliServer, mockCliServer,
join(STORAGE_DIR, "queries"), join(STORAGE_DIR, "queries"),
mockLogger, mockLogger,
@ -292,7 +290,7 @@ describe("Remote queries and query history manager", () => {
await arm.downloadAnalysisResults(analysisSummary, publisher); await arm.downloadAnalysisResults(analysisSummary, publisher);
// Should not have made the request since the analysis result is already on disk // 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 // result should have been published twice
expect(publisher).toHaveBeenCalledTimes(2); expect(publisher).toHaveBeenCalledTimes(2);

Просмотреть файл

@ -21,6 +21,8 @@ import { ResultsView } from "../../../../src/interface";
import { EvalLogViewer } from "../../../../src/eval-log-viewer"; import { EvalLogViewer } from "../../../../src/eval-log-viewer";
import { QueryRunner } from "../../../../src/queryRunner"; import { QueryRunner } from "../../../../src/queryRunner";
import { VariantAnalysisManager } from "../../../../src/remote-queries/variant-analysis-manager"; 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. // set a higher timeout since recursive delete may take a while, expecially on Windows.
jest.setTimeout(120000); jest.setTimeout(120000);
@ -36,6 +38,7 @@ describe("Variant Analyses and QueryHistoryManager", () => {
/** noop */ /** noop */
}; };
let app: App;
let qhm: QueryHistoryManager; let qhm: QueryHistoryManager;
let rawQueryHistory: any; let rawQueryHistory: any;
let disposables: DisposableBucket; let disposables: DisposableBucket;
@ -77,7 +80,10 @@ describe("Variant Analyses and QueryHistoryManager", () => {
join(STORAGE_DIR, "workspace-query-history.json"), join(STORAGE_DIR, "workspace-query-history.json"),
).queries; ).queries;
app = createMockApp({});
qhm = new QueryHistoryManager( qhm = new QueryHistoryManager(
app,
{} as QueryRunner, {} as QueryRunner,
{} as DatabaseManager, {} as DatabaseManager,
localQueriesResultsViewStub, localQueriesResultsViewStub,