Merge pull request #3074 from github/koesie10/octokit-rest-codeql-databases
Use Octokit REST for listing CodeQL databases
This commit is contained in:
12
extensions/ql-vscode/package-lock.json
generated
12
extensions/ql-vscode/package-lock.json
generated
@@ -4392,9 +4392,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/openapi-types": {
|
||||
"version": "19.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.0.0.tgz",
|
||||
"integrity": "sha512-PclQ6JGMTE9iUStpzMkwLCISFn/wDeRjkZFIKALpvJQNBGwDoYYi2fFvuHwssoQ1rXI5mfh6jgTgWuddeUzfWw=="
|
||||
"version": "19.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.0.2.tgz",
|
||||
"integrity": "sha512-8li32fUDUeml/ACRp/njCWTsk5t17cfTM1jp9n08pBrqs5cDFJubtjsSnuz56r5Tad6jdEPJld7LxNp9dNcyjQ=="
|
||||
},
|
||||
"node_modules/@octokit/plugin-paginate-rest": {
|
||||
"version": "9.0.0",
|
||||
@@ -35269,9 +35269,9 @@
|
||||
}
|
||||
},
|
||||
"@octokit/openapi-types": {
|
||||
"version": "19.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.0.0.tgz",
|
||||
"integrity": "sha512-PclQ6JGMTE9iUStpzMkwLCISFn/wDeRjkZFIKALpvJQNBGwDoYYi2fFvuHwssoQ1rXI5mfh6jgTgWuddeUzfWw=="
|
||||
"version": "19.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.0.2.tgz",
|
||||
"integrity": "sha512-8li32fUDUeml/ACRp/njCWTsk5t17cfTM1jp9n08pBrqs5cDFJubtjsSnuz56r5Tad6jdEPJld7LxNp9dNcyjQ=="
|
||||
},
|
||||
"@octokit/plugin-paginate-rest": {
|
||||
"version": "9.0.0",
|
||||
|
||||
@@ -562,10 +562,10 @@ export async function convertGithubNwoToDatabaseUrl(
|
||||
try {
|
||||
const [owner, repo] = nwo.split("/");
|
||||
|
||||
const response = await octokit.request(
|
||||
"GET /repos/:owner/:repo/code-scanning/codeql/databases",
|
||||
{ owner, repo },
|
||||
);
|
||||
const response = await octokit.rest.codeScanning.listCodeqlDatabases({
|
||||
owner,
|
||||
repo,
|
||||
});
|
||||
|
||||
const languages = response.data.map((db: any) => db.language);
|
||||
|
||||
@@ -584,12 +584,12 @@ export async function convertGithubNwoToDatabaseUrl(
|
||||
}
|
||||
|
||||
return {
|
||||
databaseUrl: `https://api.github.com/repos/${owner}/${repo}/code-scanning/codeql/databases/${language}`,
|
||||
databaseUrl: databaseForLanguage.url,
|
||||
owner,
|
||||
name: repo,
|
||||
databaseId: databaseForLanguage.id,
|
||||
databaseCreatedAt: databaseForLanguage.created_at,
|
||||
commitOid: databaseForLanguage.commit_oid,
|
||||
commitOid: databaseForLanguage.commit_oid ?? null,
|
||||
};
|
||||
} catch (e) {
|
||||
void extLogger.log(`Error: ${getErrorMessage(e)}`);
|
||||
|
||||
@@ -8,7 +8,11 @@ import {
|
||||
findDirWithFile,
|
||||
} from "../../../../src/databases/database-fetcher";
|
||||
import * as Octokit from "@octokit/rest";
|
||||
import { mockedQuickPickItem } from "../../utils/mocking.helpers";
|
||||
import {
|
||||
mockedObject,
|
||||
mockedOctokitFunction,
|
||||
mockedQuickPickItem,
|
||||
} from "../../utils/mocking.helpers";
|
||||
|
||||
// These tests make API calls and may need extra time to complete.
|
||||
jest.setTimeout(10000);
|
||||
@@ -18,10 +22,17 @@ describe("database-fetcher", () => {
|
||||
let quickPickSpy: jest.SpiedFunction<typeof window.showQuickPick>;
|
||||
|
||||
const progressSpy = jest.fn();
|
||||
const mockRequest = jest.fn();
|
||||
const octokit: Octokit.Octokit = {
|
||||
request: mockRequest,
|
||||
} as unknown as Octokit.Octokit;
|
||||
const mockListCodeqlDatabases = mockedOctokitFunction<
|
||||
"codeScanning",
|
||||
"listCodeqlDatabases"
|
||||
>();
|
||||
const octokit = mockedObject<Octokit.Octokit>({
|
||||
rest: {
|
||||
codeScanning: {
|
||||
listCodeqlDatabases: mockListCodeqlDatabases,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// We can't make the real octokit request (since we need credentials), so we mock the response.
|
||||
const successfullMockApiResponse = {
|
||||
@@ -72,7 +83,7 @@ describe("database-fetcher", () => {
|
||||
});
|
||||
|
||||
it("should convert a GitHub nwo to a database url", async () => {
|
||||
mockRequest.mockResolvedValue(successfullMockApiResponse);
|
||||
mockListCodeqlDatabases.mockResolvedValue(successfullMockApiResponse);
|
||||
quickPickSpy.mockResolvedValue(
|
||||
mockedQuickPickItem({
|
||||
label: "JavaScript",
|
||||
@@ -93,7 +104,7 @@ describe("database-fetcher", () => {
|
||||
const { databaseUrl, name, owner } = result;
|
||||
|
||||
expect(databaseUrl).toBe(
|
||||
"https://api.github.com/repos/github/codeql/code-scanning/codeql/databases/javascript",
|
||||
"https://api.github.com/repositories/143040428/code-scanning/codeql/databases/javascript",
|
||||
);
|
||||
expect(name).toBe("codeql");
|
||||
expect(owner).toBe("github");
|
||||
@@ -128,7 +139,7 @@ describe("database-fetcher", () => {
|
||||
},
|
||||
status: 404,
|
||||
};
|
||||
mockRequest.mockResolvedValue(mockApiResponse);
|
||||
mockListCodeqlDatabases.mockResolvedValue(mockApiResponse);
|
||||
const githubRepo = "foo/bar-not-real";
|
||||
await expect(
|
||||
convertGithubNwoToDatabaseUrl(githubRepo, octokit, progressSpy),
|
||||
@@ -142,7 +153,7 @@ describe("database-fetcher", () => {
|
||||
data: [],
|
||||
};
|
||||
|
||||
mockRequest.mockResolvedValue(mockApiResponse);
|
||||
mockListCodeqlDatabases.mockResolvedValue(mockApiResponse);
|
||||
const githubRepo = "foo/bar-with-no-dbs";
|
||||
await expect(
|
||||
convertGithubNwoToDatabaseUrl(githubRepo, octokit, progressSpy),
|
||||
@@ -153,7 +164,7 @@ describe("database-fetcher", () => {
|
||||
describe("when language is already provided", () => {
|
||||
describe("when language is valid", () => {
|
||||
it("should not prompt the user", async () => {
|
||||
mockRequest.mockResolvedValue(successfullMockApiResponse);
|
||||
mockListCodeqlDatabases.mockResolvedValue(successfullMockApiResponse);
|
||||
const githubRepo = "github/codeql";
|
||||
await convertGithubNwoToDatabaseUrl(
|
||||
githubRepo,
|
||||
@@ -167,7 +178,7 @@ describe("database-fetcher", () => {
|
||||
|
||||
describe("when language is invalid", () => {
|
||||
it("should prompt for language", async () => {
|
||||
mockRequest.mockResolvedValue(successfullMockApiResponse);
|
||||
mockListCodeqlDatabases.mockResolvedValue(successfullMockApiResponse);
|
||||
const githubRepo = "github/codeql";
|
||||
await convertGithubNwoToDatabaseUrl(
|
||||
githubRepo,
|
||||
@@ -182,7 +193,7 @@ describe("database-fetcher", () => {
|
||||
|
||||
describe("when language is not provided", () => {
|
||||
it("should prompt for language", async () => {
|
||||
mockRequest.mockResolvedValue(successfullMockApiResponse);
|
||||
mockListCodeqlDatabases.mockResolvedValue(successfullMockApiResponse);
|
||||
const githubRepo = "github/codeql";
|
||||
await convertGithubNwoToDatabaseUrl(githubRepo, octokit, progressSpy);
|
||||
expect(quickPickSpy).toHaveBeenCalled();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { QuickPickItem, window, Uri } from "vscode";
|
||||
import { DatabaseItem } from "../../../src/databases/local-databases";
|
||||
import * as Octokit from "@octokit/rest";
|
||||
|
||||
export type DeepPartial<T> = T extends object
|
||||
? {
|
||||
@@ -57,6 +58,14 @@ export function mockedObject<T extends object>(
|
||||
});
|
||||
}
|
||||
|
||||
export function mockedOctokitFunction<
|
||||
Namespace extends keyof Octokit.Octokit["rest"],
|
||||
Name extends keyof Octokit.Octokit["rest"][Namespace],
|
||||
>(): Octokit.Octokit["rest"][Namespace][Name] & jest.Mock {
|
||||
const fn = jest.fn();
|
||||
return fn as unknown as Octokit.Octokit["rest"][Namespace][Name] & jest.Mock;
|
||||
}
|
||||
|
||||
export function mockDatabaseItem(
|
||||
props: DeepPartial<DatabaseItem> = {},
|
||||
): DatabaseItem {
|
||||
|
||||
Reference in New Issue
Block a user