Skip to content

Commit

Permalink
Merge pull request #189 from lerna/nm-handle-401-responses
Browse files Browse the repository at this point in the history
Abort process when github response is not OK
Turbo87 authored Dec 16, 2019

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
2 parents aaf93c8 + cccc244 commit b22c6fb
Showing 7 changed files with 254 additions and 127 deletions.
21 changes: 18 additions & 3 deletions src/__mocks__/fetch.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,31 @@
"use strict";

let mockResponses: { [url: string]: string } = {};
type Json = { [key: string]: unknown };
type MockResponse = { status: number; statusText: string; ok: boolean; body: Json };

let mockResponses: { [url: string]: Partial<MockResponse> } = {};

const defaultMockResponseParams = {
status: 200,
statusText: "OK",
ok: true,
};

export default async function fetch(url: string) {
const mockResponse = mockResponses[url];
if (mockResponse) {
return { json: () => mockResponse };
const fullMockResponse = { ...defaultMockResponseParams, ...mockResponse };
return {
status: fullMockResponse.status,
statusText: fullMockResponse.statusText,
ok: fullMockResponse.ok,
json: () => Promise.resolve(fullMockResponse.body),
};
}
throw new Error(`Unknown URL: ${url}`);
}

export function __setMockResponses(newMockResponses: { [url: string]: string }) {
export function __setMockResponses(newMockResponses: { [url: string]: Partial<MockResponse> }) {
mockResponses = newMockResponses;
}

50 changes: 31 additions & 19 deletions src/changelog.spec.ts
Original file line number Diff line number Diff line change
@@ -69,17 +69,21 @@ describe("Changelog", () => {

const usersCache = {
"https://api.github.com/users/test-user": {
login: "test-user",
html_url: "https://github.com/test-user",
name: "Test User",
body: {
login: "test-user",
html_url: "https://github.com/test-user",
name: "Test User",
},
},
};
const issuesCache = {
"https://api.github.com/repos/lerna/lerna-changelog/issues/2": {
number: 2,
title: "This is the commit title for the issue (#2)",
labels: [{ name: "Type: New Feature" }, { name: "Status: In Progress" }],
user: usersCache["https://api.github.com/users/test-user"],
body: {
number: 2,
title: "This is the commit title for the issue (#2)",
labels: [{ name: "Type: New Feature" }, { name: "Status: In Progress" }],
user: usersCache["https://api.github.com/users/test-user"].body,
},
},
};
require("./fetch").__setMockResponses({
@@ -107,24 +111,32 @@ describe("Changelog", () => {

const usersCache = {
"https://api.github.com/users/test-user": {
login: "test-user",
html_url: "https://github.com/test-user",
name: "Test User",
body: {
login: "test-user",
html_url: "https://github.com/test-user",
name: "Test User",
},
},
"https://api.github.com/users/test-user-1": {
login: "test-user-1",
html_url: "https://github.com/test-user-1",
name: "Test User 1",
body: {
login: "test-user-1",
html_url: "https://github.com/test-user-1",
name: "Test User 1",
},
},
"https://api.github.com/users/test-user-2": {
login: "test-user-2",
html_url: "https://github.com/test-user-2",
name: "Test User 2",
body: {
login: "test-user-2",
html_url: "https://github.com/test-user-2",
name: "Test User 2",
},
},
"https://api.github.com/users/user-bot": {
login: "user-bot",
html_url: "https://github.com/user-bot",
name: "User Bot",
body: {
login: "user-bot",
html_url: "https://github.com/user-bot",
name: "User Bot",
},
},
};
require("./fetch").__setMockResponses(usersCache);
24 changes: 13 additions & 11 deletions src/changelog.ts
Original file line number Diff line number Diff line change
@@ -215,17 +215,19 @@ export default class Changelog {
private async fillInPackages(commits: CommitInfo[]) {
progressBar.init("Mapping commits to packages…", commits.length);

await pMap(
commits,
async (commit: CommitInfo) => {
commit.packages = await this.getListOfUniquePackages(commit.commitSHA);

progressBar.tick();
},
{ concurrency: 5 }
);

progressBar.terminate();
try {
await pMap(
commits,
async (commit: CommitInfo) => {
commit.packages = await this.getListOfUniquePackages(commit.commitSHA);

progressBar.tick();
},
{ concurrency: 5 }
);
} finally {
progressBar.terminate();
}
}

private async fillInContributors(releases: Release[]) {
2 changes: 2 additions & 0 deletions src/cli.ts
Original file line number Diff line number Diff line change
@@ -88,5 +88,7 @@ export async function run() {
} else {
console.log(chalk.red(e.stack));
}

process.exitCode = 1;
}
}
66 changes: 39 additions & 27 deletions src/functional/markdown-empty.spec.ts
Original file line number Diff line number Diff line change
@@ -50,48 +50,60 @@ const listOfFileForEachCommit: { [id: string]: string[] } = {

const usersCache = {
"https://api.github.com/users/luke": {
login: "luke",
html_url: "https://github.com/luke",
name: "Luke Skywalker",
body: {
login: "luke",
html_url: "https://github.com/luke",
name: "Luke Skywalker",
},
},
"https://api.github.com/users/vader": {
login: "vader",
html_url: "https://github.com/vader",
name: "Darth Vader",
body: {
login: "vader",
html_url: "https://github.com/vader",
name: "Darth Vader",
},
},
"https://api.github.com/users/gtarkin": {
login: "gtarkin",
html_url: "https://github.com/gtarkin",
name: "Governor Tarkin",
body: {
login: "gtarkin",
html_url: "https://github.com/gtarkin",
name: "Governor Tarkin",
},
},
};
const issuesCache = {
"https://api.github.com/repos/lerna/lerna-changelog/issues/1": {
number: 1,
title: "feat: May the force be with you",
labels: [{ name: "Type: New Feature" }],
pull_request: {
html_url: "https://github.com/lerna/lerna-changelog/pull/1",
body: {
number: 1,
title: "feat: May the force be with you",
labels: [{ name: "Type: New Feature" }],
pull_request: {
html_url: "https://github.com/lerna/lerna-changelog/pull/1",
},
user: usersCache["https://api.github.com/users/luke"],
},
user: usersCache["https://api.github.com/users/luke"],
},
"https://api.github.com/repos/lerna/lerna-changelog/issues/2": {
number: 2,
title: "chore: Terminate her... immediately!",
labels: [{ name: "Type: Breaking Change" }],
pull_request: {
html_url: "https://github.com/lerna/lerna-changelog/pull/2",
body: {
number: 2,
title: "chore: Terminate her... immediately!",
labels: [{ name: "Type: Breaking Change" }],
pull_request: {
html_url: "https://github.com/lerna/lerna-changelog/pull/2",
},
user: usersCache["https://api.github.com/users/gtarkin"],
},
user: usersCache["https://api.github.com/users/gtarkin"],
},
"https://api.github.com/repos/lerna/lerna-changelog/issues/3": {
number: 3,
title: "fix: Get me the rebels base!",
labels: [{ name: "Type: Bug" }],
pull_request: {
html_url: "https://github.com/lerna/lerna-changelog/pull/3",
body: {
number: 3,
title: "fix: Get me the rebels base!",
labels: [{ name: "Type: Bug" }],
pull_request: {
html_url: "https://github.com/lerna/lerna-changelog/pull/3",
},
user: usersCache["https://api.github.com/users/vader"],
},
user: usersCache["https://api.github.com/users/vader"],
},
};

212 changes: 146 additions & 66 deletions src/functional/markdown-full.spec.ts
Original file line number Diff line number Diff line change
@@ -141,109 +141,139 @@ const listOfFileForEachCommit: { [id: string]: string[] } = {

const usersCache = {
"https://api.github.com/users/luke": {
login: "luke",
html_url: "https://github.com/luke",
name: "Luke Skywalker",
body: {
login: "luke",
html_url: "https://github.com/luke",
name: "Luke Skywalker",
},
},
"https://api.github.com/users/princess-leia": {
login: "princess-leia",
html_url: "https://github.com/princess-leia",
name: "Princess Leia Organa",
body: {
login: "princess-leia",
html_url: "https://github.com/princess-leia",
name: "Princess Leia Organa",
},
},
"https://api.github.com/users/vader": {
login: "vader",
html_url: "https://github.com/vader",
name: "Darth Vader",
body: {
login: "vader",
html_url: "https://github.com/vader",
name: "Darth Vader",
},
},
"https://api.github.com/users/gtarkin": {
login: "gtarkin",
html_url: "https://github.com/gtarkin",
name: "Governor Tarkin",
body: {
login: "gtarkin",
html_url: "https://github.com/gtarkin",
name: "Governor Tarkin",
},
},
"https://api.github.com/users/han-solo": {
login: "han-solo",
html_url: "https://github.com/han-solo",
name: "Han Solo",
body: {
login: "han-solo",
html_url: "https://github.com/han-solo",
name: "Han Solo",
},
},
"https://api.github.com/users/chewbacca": {
login: "chewbacca",
html_url: "https://github.com/chewbacca",
name: "Chwebacca",
body: {
login: "chewbacca",
html_url: "https://github.com/chewbacca",
name: "Chwebacca",
},
},
"https://api.github.com/users/rd-d2": {
login: "rd-d2",
html_url: "https://github.com/rd-d2",
name: "R2-D2",
body: {
login: "rd-d2",
html_url: "https://github.com/rd-d2",
name: "R2-D2",
},
},
"https://api.github.com/users/c-3po": {
login: "c-3po",
html_url: "https://github.com/c-3po",
name: "C-3PO",
body: {
login: "c-3po",
html_url: "https://github.com/c-3po",
name: "C-3PO",
},
},
};
const issuesCache = {
"https://api.github.com/repos/lerna/lerna-changelog/issues/1": {
number: 1,
title: "feat: May the force be with you",
labels: [{ name: "Type: New Feature" }],
pull_request: {
html_url: "https://github.com/lerna/lerna-changelog/pull/1",
body: {
number: 1,
title: "feat: May the force be with you",
labels: [{ name: "Type: New Feature" }],
pull_request: {
html_url: "https://github.com/lerna/lerna-changelog/pull/1",
},
user: usersCache["https://api.github.com/users/luke"].body,
},
user: usersCache["https://api.github.com/users/luke"],
},
"https://api.github.com/repos/lerna/lerna-changelog/issues/2": {
number: 2,
title: "chore: Terminate her... immediately!",
labels: [{ name: "Type: Breaking Change" }],
pull_request: {
html_url: "https://github.com/lerna/lerna-changelog/pull/2",
body: {
number: 2,
title: "chore: Terminate her... immediately!",
labels: [{ name: "Type: Breaking Change" }],
pull_request: {
html_url: "https://github.com/lerna/lerna-changelog/pull/2",
},
user: usersCache["https://api.github.com/users/gtarkin"].body,
},
user: usersCache["https://api.github.com/users/gtarkin"],
},
"https://api.github.com/repos/lerna/lerna-changelog/issues/3": {
number: 3,
title: "fix: Get me the rebels base!",
labels: [{ name: "Type: Bug" }],
pull_request: {
html_url: "https://github.com/lerna/lerna-changelog/pull/3",
body: {
number: 3,
title: "fix: Get me the rebels base!",
labels: [{ name: "Type: Bug" }],
pull_request: {
html_url: "https://github.com/lerna/lerna-changelog/pull/3",
},
user: usersCache["https://api.github.com/users/vader"].body,
},
user: usersCache["https://api.github.com/users/vader"],
},
"https://api.github.com/repos/lerna/lerna-changelog/issues/4": {
number: 4,
title: "fix: RRRAARRWHHGWWR",
labels: [{ name: "Type: Bug" }, { name: "Type: Maintenance" }],
pull_request: {
html_url: "https://github.com/lerna/lerna-changelog/pull/4",
body: {
number: 4,
title: "fix: RRRAARRWHHGWWR",
labels: [{ name: "Type: Bug" }, { name: "Type: Maintenance" }],
pull_request: {
html_url: "https://github.com/lerna/lerna-changelog/pull/4",
},
user: usersCache["https://api.github.com/users/chewbacca"].body,
},
user: usersCache["https://api.github.com/users/chewbacca"],
},
"https://api.github.com/repos/lerna/lerna-changelog/issues/5": {
number: 5,
title: "feat: I am your father",
labels: [{ name: "Type: New Feature" }],
pull_request: {
html_url: "https://github.com/lerna/lerna-changelog/pull/5",
body: {
number: 5,
title: "feat: I am your father",
labels: [{ name: "Type: New Feature" }],
pull_request: {
html_url: "https://github.com/lerna/lerna-changelog/pull/5",
},
user: usersCache["https://api.github.com/users/vader"].body,
},
user: usersCache["https://api.github.com/users/vader"],
},
"https://api.github.com/repos/lerna/lerna-changelog/issues/6": {
number: 6,
title: "refactor: he is my brother",
labels: [{ name: "Type: Enhancement" }],
pull_request: {
html_url: "https://github.com/lerna/lerna-changelog/pull/6",
body: {
number: 6,
title: "refactor: he is my brother",
labels: [{ name: "Type: Enhancement" }],
pull_request: {
html_url: "https://github.com/lerna/lerna-changelog/pull/6",
},
user: usersCache["https://api.github.com/users/princess-leia"].body,
},
user: usersCache["https://api.github.com/users/princess-leia"],
},
"https://api.github.com/repos/lerna/lerna-changelog/issues/7": {
number: 7,
title: "feat: that is not how the Force works!",
labels: [{ name: "Type: New Feature" }, { name: "Type: Enhancement" }],
pull_request: {
html_url: "https://github.com/lerna/lerna-changelog/pull/7",
body: {
number: 7,
title: "feat: that is not how the Force works!",
labels: [{ name: "Type: New Feature" }, { name: "Type: Enhancement" }],
pull_request: {
html_url: "https://github.com/lerna/lerna-changelog/pull/7",
},
user: usersCache["https://api.github.com/users/han-solo"].body,
},
user: usersCache["https://api.github.com/users/han-solo"],
},
};

@@ -351,4 +381,54 @@ describe("createMarkdown", () => {
expect(markdown).toMatchSnapshot();
});
});

describe("authentication", () => {
describe("when github token is not valid", () => {
const badCredentials = {
message: "Bad credentials",
documentation_url: "https://developer.github.com/v3",
};
beforeEach(() => {
require("../git").changedPaths.mockImplementation((sha: string) => listOfFileForEachCommit[sha]);
require("../git").lastTag.mockImplementation(() => "v8.0.0");
require("../git").listCommits.mockImplementation(() => listOfCommits);
require("../git").listTagNames.mockImplementation(() => listOfTags);

const unauthorized = {
status: 401,
statusText: "Unauthorized",
ok: false,
body: badCredentials,
};
require("../fetch").__setMockResponses({
...usersCache,
...Object.keys(issuesCache).reduce(
(unauthorizedIssues, issue) => ({
...unauthorizedIssues,
[issue]: unauthorized,
}),
{}
),
});
});
afterEach(() => {
jest.resetAllMocks();
});
it("should abort with a proper error message", async () => {
const MockedChangelog = require("../changelog").default;
const changelog = new MockedChangelog();
expect.assertions(2);
try {
await changelog.createMarkdown();
} catch (error) {
expect(error).toEqual(
expect.objectContaining({ message: expect.stringContaining("Fetch error: Unauthorized") })
);
expect(error).toEqual(
expect.objectContaining({ message: expect.stringContaining(JSON.stringify(badCredentials)) })
);
}
});
});
});
});
6 changes: 5 additions & 1 deletion src/github-api.ts
Original file line number Diff line number Diff line change
@@ -61,7 +61,11 @@ export default class GithubAPI {
Authorization: `token ${this.auth}`,
},
});
return res.json();
const parsedResponse = await res.json();
if (res.ok) {
return parsedResponse;
}
throw new ConfigurationError(`Fetch error: ${res.statusText}.\n${JSON.stringify(parsedResponse)}`);
}

private getAuthToken(): string {

0 comments on commit b22c6fb

Please sign in to comment.