mirror of
https://github.com/status-im/sourcecred.git
synced 2025-02-21 08:48:14 +00:00
Add PR reviews and comments to GitHub api (#179)
Also, a slight re-organization of the GitHub api test code.
This commit is contained in:
parent
16e8e399e6
commit
a1d072846d
@ -1,8 +1,8 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`GitHub porcelain API Author 1`] = `2`;
|
exports[`GitHub porcelain API has wrappers for Authors 1`] = `2`;
|
||||||
|
|
||||||
exports[`GitHub porcelain API Author 2`] = `
|
exports[`GitHub porcelain API has wrappers for Authors 2`] = `
|
||||||
Object {
|
Object {
|
||||||
"address": Object {
|
"address": Object {
|
||||||
"id": "https://github.com/decentralion",
|
"id": "https://github.com/decentralion",
|
||||||
@ -18,9 +18,9 @@ Object {
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`GitHub porcelain API Comment 1`] = `3`;
|
exports[`GitHub porcelain API has wrappers for Comments 1`] = `3`;
|
||||||
|
|
||||||
exports[`GitHub porcelain API Comment 2`] = `
|
exports[`GitHub porcelain API has wrappers for Comments 2`] = `
|
||||||
Object {
|
Object {
|
||||||
"address": Object {
|
"address": Object {
|
||||||
"id": "https://github.com/sourcecred/example-repo/issues/6#issuecomment-373768442",
|
"id": "https://github.com/sourcecred/example-repo/issues/6#issuecomment-373768442",
|
||||||
@ -35,7 +35,7 @@ Object {
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`GitHub porcelain API Issue 1`] = `
|
exports[`GitHub porcelain API has wrappers for Issues 1`] = `
|
||||||
Object {
|
Object {
|
||||||
"address": Object {
|
"address": Object {
|
||||||
"id": "https://github.com/sourcecred/example-repo/issues/1",
|
"id": "https://github.com/sourcecred/example-repo/issues/1",
|
||||||
@ -52,7 +52,7 @@ Object {
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`GitHub porcelain API PullRequest 1`] = `
|
exports[`GitHub porcelain API has wrappers for PullRequests 1`] = `
|
||||||
Object {
|
Object {
|
||||||
"address": Object {
|
"address": Object {
|
||||||
"id": "https://github.com/sourcecred/example-repo/pull/3",
|
"id": "https://github.com/sourcecred/example-repo/pull/3",
|
||||||
|
@ -11,6 +11,9 @@ import type {
|
|||||||
NodeType,
|
NodeType,
|
||||||
IssueNodePayload,
|
IssueNodePayload,
|
||||||
PullRequestNodePayload,
|
PullRequestNodePayload,
|
||||||
|
PullRequestReviewNodePayload,
|
||||||
|
PullRequestReviewCommentNodePayload,
|
||||||
|
PullRequestReviewState,
|
||||||
CommentNodePayload,
|
CommentNodePayload,
|
||||||
AuthorNodePayload,
|
AuthorNodePayload,
|
||||||
AuthorSubtype,
|
AuthorSubtype,
|
||||||
@ -23,9 +26,17 @@ import {
|
|||||||
AUTHOR_NODE_TYPE,
|
AUTHOR_NODE_TYPE,
|
||||||
ISSUE_NODE_TYPE,
|
ISSUE_NODE_TYPE,
|
||||||
PULL_REQUEST_NODE_TYPE,
|
PULL_REQUEST_NODE_TYPE,
|
||||||
|
PULL_REQUEST_REVIEW_NODE_TYPE,
|
||||||
|
PULL_REQUEST_REVIEW_COMMENT_NODE_TYPE,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
export type Entity = Issue | PullRequest | Comment | Author;
|
export type Entity =
|
||||||
|
| Issue
|
||||||
|
| PullRequest
|
||||||
|
| Comment
|
||||||
|
| Author
|
||||||
|
| PullRequestReview
|
||||||
|
| PullRequestReviewComment;
|
||||||
|
|
||||||
function assertEntityType(e: Entity, t: NodeType) {
|
function assertEntityType(e: Entity, t: NodeType) {
|
||||||
if (e.type() !== t) {
|
if (e.type() !== t) {
|
||||||
@ -105,7 +116,12 @@ class GithubEntity<T: NodePayload> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Post<
|
class Post<
|
||||||
T: IssueNodePayload | PullRequestNodePayload | CommentNodePayload
|
T:
|
||||||
|
| IssueNodePayload
|
||||||
|
| PullRequestNodePayload
|
||||||
|
| CommentNodePayload
|
||||||
|
| PullRequestReviewNodePayload
|
||||||
|
| PullRequestReviewCommentNodePayload
|
||||||
> extends GithubEntity<T> {
|
> extends GithubEntity<T> {
|
||||||
authors(): Author[] {
|
authors(): Author[] {
|
||||||
return this.graph
|
return this.graph
|
||||||
@ -159,6 +175,14 @@ export class PullRequest extends Commentable<PullRequestNodePayload> {
|
|||||||
title(): string {
|
title(): string {
|
||||||
return this.node().payload.title;
|
return this.node().payload.title;
|
||||||
}
|
}
|
||||||
|
reviews(): PullRequestReview[] {
|
||||||
|
return this.graph
|
||||||
|
.neighborhood(this.nodeAddress, {
|
||||||
|
edgeType: CONTAINS_EDGE_TYPE,
|
||||||
|
nodeType: PULL_REQUEST_REVIEW_NODE_TYPE,
|
||||||
|
})
|
||||||
|
.map(({neighbor}) => new PullRequestReview(this.graph, neighbor));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Issue extends Commentable<IssueNodePayload> {
|
export class Issue extends Commentable<IssueNodePayload> {
|
||||||
@ -180,3 +204,31 @@ export class Comment extends Post<CommentNodePayload> {
|
|||||||
return (e: any);
|
return (e: any);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class PullRequestReview extends Post<PullRequestReviewNodePayload> {
|
||||||
|
static from(e: Entity): PullRequestReview {
|
||||||
|
assertEntityType(e, PULL_REQUEST_REVIEW_NODE_TYPE);
|
||||||
|
return (e: any);
|
||||||
|
}
|
||||||
|
state(): PullRequestReviewState {
|
||||||
|
return this.node().payload.state;
|
||||||
|
}
|
||||||
|
|
||||||
|
comments(): PullRequestReviewComment[] {
|
||||||
|
return this.graph
|
||||||
|
.neighborhood(this.nodeAddress, {
|
||||||
|
edgeType: CONTAINS_EDGE_TYPE,
|
||||||
|
nodeType: PULL_REQUEST_REVIEW_COMMENT_NODE_TYPE,
|
||||||
|
})
|
||||||
|
.map(({neighbor}) => new PullRequestReviewComment(this.graph, neighbor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PullRequestReviewComment extends Post<
|
||||||
|
PullRequestReviewCommentNodePayload
|
||||||
|
> {
|
||||||
|
static from(e: Entity): PullRequestReviewComment {
|
||||||
|
assertEntityType(e, PULL_REQUEST_REVIEW_COMMENT_NODE_TYPE);
|
||||||
|
return (e: any);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -19,8 +19,8 @@ describe("GitHub porcelain API", () => {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
describe("has wrappers for", () => {
|
||||||
it("Issue", () => {
|
it("Issues", () => {
|
||||||
const issue = issueOrPRByNumber(1);
|
const issue = issueOrPRByNumber(1);
|
||||||
expect(issue.title()).toBe("An example issue.");
|
expect(issue.title()).toBe("An example issue.");
|
||||||
expect(issue.body()).toBe("This is just an example issue.");
|
expect(issue.body()).toBe("This is just an example issue.");
|
||||||
@ -34,9 +34,10 @@ describe("GitHub porcelain API", () => {
|
|||||||
expect(issue.authors().map((x) => x.login())).toEqual(["decentralion"]);
|
expect(issue.authors().map((x) => x.login())).toEqual(["decentralion"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("PullRequest", () => {
|
it("PullRequests", () => {
|
||||||
const pullRequest = issueOrPRByNumber(3);
|
const pullRequest = issueOrPRByNumber(3);
|
||||||
expect(pullRequest.body()).toBe("Oh look, it's a pull request.");
|
expect(pullRequest.body()).toBe("Oh look, it's a pull request.");
|
||||||
|
expect(pullRequest.title()).toBe("Add README, merge via PR.");
|
||||||
expect(pullRequest.url()).toBe(
|
expect(pullRequest.url()).toBe(
|
||||||
"https://github.com/sourcecred/example-repo/pull/3"
|
"https://github.com/sourcecred/example-repo/pull/3"
|
||||||
);
|
);
|
||||||
@ -46,7 +47,29 @@ describe("GitHub porcelain API", () => {
|
|||||||
expect(pullRequest.address()).toEqual(pullRequest.node().address);
|
expect(pullRequest.address()).toEqual(pullRequest.node().address);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Comment", () => {
|
it("Pull Request Reviews", () => {
|
||||||
|
const pr = PullRequest.from(issueOrPRByNumber(5));
|
||||||
|
const reviews = pr.reviews();
|
||||||
|
expect(reviews).toHaveLength(2);
|
||||||
|
expect(reviews[0].state()).toBe("CHANGES_REQUESTED");
|
||||||
|
expect(reviews[1].state()).toBe("APPROVED");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Pull Request Review Comments", () => {
|
||||||
|
const pr = PullRequest.from(issueOrPRByNumber(5));
|
||||||
|
const reviews = pr.reviews();
|
||||||
|
expect(reviews).toHaveLength(2);
|
||||||
|
const comments = reviews[0].comments();
|
||||||
|
expect(comments).toHaveLength(1);
|
||||||
|
const comment = comments[0];
|
||||||
|
expect(comment.url()).toBe(
|
||||||
|
"https://github.com/sourcecred/example-repo/pull/5#discussion_r171460198"
|
||||||
|
);
|
||||||
|
expect(comment.body()).toBe("seems a bit capricious");
|
||||||
|
expect(comment.authors().map((a) => a.login())).toEqual(["wchargin"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Comments", () => {
|
||||||
const issue = issueOrPRByNumber(6);
|
const issue = issueOrPRByNumber(6);
|
||||||
const comments = issue.comments();
|
const comments = issue.comments();
|
||||||
expect(comments.length).toMatchSnapshot();
|
expect(comments.length).toMatchSnapshot();
|
||||||
@ -61,7 +84,7 @@ describe("GitHub porcelain API", () => {
|
|||||||
expect(comment.authors().map((x) => x.login())).toEqual(["decentralion"]);
|
expect(comment.authors().map((x) => x.login())).toEqual(["decentralion"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Author", () => {
|
it("Authors", () => {
|
||||||
const authors = repo.authors();
|
const authors = repo.authors();
|
||||||
// So we don't need to manually update the test if a new person posts
|
// So we don't need to manually update the test if a new person posts
|
||||||
expect(authors.length).toMatchSnapshot();
|
expect(authors.length).toMatchSnapshot();
|
||||||
@ -76,9 +99,10 @@ describe("GitHub porcelain API", () => {
|
|||||||
expect(decentralion.node()).toMatchSnapshot();
|
expect(decentralion.node()).toMatchSnapshot();
|
||||||
expect(decentralion.address()).toEqual(decentralion.node().address);
|
expect(decentralion.address()).toEqual(decentralion.node().address);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("type coercion", () => {
|
describe("has type coercion that", () => {
|
||||||
it("type coercion works when typed correctly", () => {
|
it("allows refining types when correct", () => {
|
||||||
const _unused_issue: Issue = Issue.from(issueOrPRByNumber(1));
|
const _unused_issue: Issue = Issue.from(issueOrPRByNumber(1));
|
||||||
const _unused_pr: PullRequest = PullRequest.from(issueOrPRByNumber(3));
|
const _unused_pr: PullRequest = PullRequest.from(issueOrPRByNumber(3));
|
||||||
const _unused_author: Author = Author.from(
|
const _unused_author: Author = Author.from(
|
||||||
@ -88,7 +112,7 @@ describe("GitHub porcelain API", () => {
|
|||||||
issueOrPRByNumber(2).comments()[0]
|
issueOrPRByNumber(2).comments()[0]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it("type coercion throws error when typed incorrectly", () => {
|
it("throws an error on bad type refinement", () => {
|
||||||
expect(() => PullRequest.from(issueOrPRByNumber(1))).toThrowError(
|
expect(() => PullRequest.from(issueOrPRByNumber(1))).toThrowError(
|
||||||
"to have type PULL_REQUEST"
|
"to have type PULL_REQUEST"
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user