Merge pull request #3299 from github/robertbrignull/releases_tests

Use slightly more realistic tests data for ReleasesApiConsumer
This commit is contained in:
Robert
2024-02-01 13:00:28 +00:00
committed by GitHub
2 changed files with 88 additions and 107 deletions

View File

@@ -191,7 +191,7 @@ export interface GithubRelease {
*
* This type must match the format of the GitHub API and is not intended to be used outside of this file except for tests. Please use the `ReleaseAsset` type instead.
*/
export interface GithubReleaseAsset {
interface GithubReleaseAsset {
id: number;
name: string;
size: number;

View File

@@ -1,88 +1,96 @@
import { Response } from "node-fetch";
import { Range } from "semver";
import type {
GithubRelease,
GithubReleaseAsset,
} from "../../../../src/codeql-cli/distribution/releases-api-consumer";
import type { GithubRelease } from "../../../../src/codeql-cli/distribution/releases-api-consumer";
import { ReleasesApiConsumer } from "../../../../src/codeql-cli/distribution/releases-api-consumer";
describe("Releases API consumer", () => {
const repositoryNwo = "someowner/somerepo";
const unconstrainedVersionRange = new Range("*");
describe("picking the latest release", () => {
const sampleReleaseResponse: GithubRelease[] = [
{
assets: [],
created_at: "2019-09-01T00:00:00Z",
id: 1,
name: "",
prerelease: false,
tag_name: "v2.1.0",
},
{
assets: [],
created_at: "2019-08-10T00:00:00Z",
id: 2,
name: "",
prerelease: false,
tag_name: "v3.1.1",
},
{
assets: [
{
id: 1,
name: "exampleAsset.txt",
size: 1,
},
],
created_at: "2019-09-05T00:00:00Z",
id: 3,
name: "",
prerelease: false,
tag_name: "v2.0.0",
},
{
assets: [],
created_at: "2019-08-11T00:00:00Z",
id: 4,
name: "",
prerelease: true,
tag_name: "v3.1.2-pre-1.1",
},
// Release ID 5 is older than release ID 4 but its version has a higher precedence, so release
// ID 5 should be picked over release ID 4.
{
assets: [],
created_at: "2019-08-09T00:00:00Z",
id: 5,
name: "",
prerelease: true,
tag_name: "v3.1.2-pre-2.0",
},
// Has a tag_name that is not valid semver
{
assets: [],
created_at: "2019-08-010T00:00:00Z",
id: 6,
name: "",
prerelease: true,
tag_name: "codeql-bundle-20231220",
},
];
const sampleReleaseResponse: GithubRelease[] = [
{
assets: [],
created_at: "2019-09-01T00:00:00Z",
id: 1,
name: "v2.1.0",
prerelease: false,
tag_name: "v2.1.0",
},
{
assets: [
{
id: 1,
name: "firstAsset",
size: 11,
},
{
id: 2,
name: "secondAsset",
size: 12,
},
],
created_at: "2019-08-10T00:00:00Z",
id: 2,
name: "v3.1.1",
prerelease: false,
tag_name: "v3.1.1",
},
{
assets: [
{
id: 1,
name: "exampleAsset.txt",
size: 1,
},
],
created_at: "2019-09-05T00:00:00Z",
id: 3,
name: "v2.0.0",
prerelease: false,
tag_name: "v2.0.0",
},
{
assets: [],
created_at: "2019-08-11T00:00:00Z",
id: 4,
name: "v3.1.2-pre-1.1",
prerelease: true,
tag_name: "v3.1.2-pre-1.1",
},
// Release ID 5 is older than release ID 4 but its version has a higher precedence, so release
// ID 5 should be picked over release ID 4.
{
assets: [],
created_at: "2019-08-09T00:00:00Z",
id: 5,
name: "v3.1.2-pre-2.0",
prerelease: true,
tag_name: "v3.1.2-pre-2.0",
},
// Has a tag_name that is not valid semver
{
assets: [],
created_at: "2019-08-010T00:00:00Z",
id: 6,
name: "codeql-bundle-20231220",
prerelease: true,
tag_name: "codeql-bundle-20231220",
},
];
class MockReleasesApiConsumer extends ReleasesApiConsumer {
protected async makeApiCall(apiPath: string): Promise<Response> {
if (apiPath === `/repos/${repositoryNwo}/releases`) {
return Promise.resolve(
new Response(JSON.stringify(sampleReleaseResponse)),
);
}
return Promise.reject(new Error(`Unknown API path: ${apiPath}`));
class MockReleasesApiConsumer extends ReleasesApiConsumer {
protected async makeApiCall(apiPath: string): Promise<Response> {
if (apiPath === `/repos/${repositoryNwo}/releases`) {
return Promise.resolve(
new Response(JSON.stringify(sampleReleaseResponse)),
);
}
return Promise.reject(new Error(`Unknown API path: ${apiPath}`));
}
}
describe("picking the latest release", () => {
it("picked release is non-prerelease with the highest semver", async () => {
const consumer = new MockReleasesApiConsumer(repositoryNwo);
@@ -167,7 +175,12 @@ describe("Releases API consumer", () => {
});
it("gets correct assets for a release", async () => {
const expectedAssets: GithubReleaseAsset[] = [
const consumer = new MockReleasesApiConsumer(repositoryNwo);
const assets = (await consumer.getLatestRelease(unconstrainedVersionRange))
.assets;
expect(assets).toEqual([
{
id: 1,
name: "firstAsset",
@@ -178,38 +191,6 @@ describe("Releases API consumer", () => {
name: "secondAsset",
size: 12,
},
];
class MockReleasesApiConsumer extends ReleasesApiConsumer {
protected async makeApiCall(apiPath: string): Promise<Response> {
if (apiPath === `/repos/${repositoryNwo}/releases`) {
const responseBody: GithubRelease[] = [
{
assets: expectedAssets,
created_at: "2019-09-01T00:00:00Z",
id: 1,
name: "Release 1",
prerelease: false,
tag_name: "v2.0.0",
},
];
return Promise.resolve(new Response(JSON.stringify(responseBody)));
}
return Promise.reject(new Error(`Unknown API path: ${apiPath}`));
}
}
const consumer = new MockReleasesApiConsumer(repositoryNwo);
const assets = (await consumer.getLatestRelease(unconstrainedVersionRange))
.assets;
expect(assets.length).toBe(expectedAssets.length);
expectedAssets.map((expectedAsset, index) => {
expect(assets[index].id).toBe(expectedAsset.id);
expect(assets[index].name).toBe(expectedAsset.name);
expect(assets[index].size).toBe(expectedAsset.size);
});
]);
});
});