Subtype GitHub userlikes for Users and Bots (#713)
Userlikes now have an additional piece of data encoded in their address: whether they are a USER or a BOT. Userlikes are still handled identically by the RelationalView, which cuts down on code duplication. I haven't added ORGANIZATIONs but it will be trivial to do once we're interested in tracking them. Note that this is basically the same as how we treat comments: comments are subtyped to review comments, issue comments, and pull comments. This is the initial step towards solving #696. Test plan: Existing unit tests pass (and caught a few bugs during development!). New test cases were added to the parser. Observe that all the snapshot changes make sense. Note: As of this commit, every GitHub userlike is classified as a user, and the subtypes are not used in the application, so this commit causes no change in observable behavior.
This commit is contained in:
parent
a5c909689a
commit
dda9c5feff
|
@ -13,8 +13,9 @@ Array [
|
|||
"sourcecred",
|
||||
"github",
|
||||
"AUTHORS",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"4",
|
||||
"ISSUE",
|
||||
|
@ -30,8 +31,9 @@ Array [
|
|||
"sourcecred",
|
||||
"github",
|
||||
"AUTHORS",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"4",
|
||||
"ISSUE",
|
||||
|
@ -47,8 +49,9 @@ Array [
|
|||
"sourcecred",
|
||||
"github",
|
||||
"AUTHORS",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"4",
|
||||
"ISSUE",
|
||||
|
@ -64,8 +67,9 @@ Array [
|
|||
"sourcecred",
|
||||
"github",
|
||||
"AUTHORS",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"4",
|
||||
"ISSUE",
|
||||
|
@ -81,8 +85,9 @@ Array [
|
|||
"sourcecred",
|
||||
"github",
|
||||
"AUTHORS",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"4",
|
||||
"ISSUE",
|
||||
|
@ -98,8 +103,9 @@ Array [
|
|||
"sourcecred",
|
||||
"github",
|
||||
"AUTHORS",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"4",
|
||||
"ISSUE",
|
||||
|
@ -115,8 +121,9 @@ Array [
|
|||
"sourcecred",
|
||||
"github",
|
||||
"AUTHORS",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"4",
|
||||
"ISSUE",
|
||||
|
@ -132,8 +139,9 @@ Array [
|
|||
"sourcecred",
|
||||
"github",
|
||||
"AUTHORS",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"4",
|
||||
"PULL",
|
||||
|
@ -149,8 +157,9 @@ Array [
|
|||
"sourcecred",
|
||||
"github",
|
||||
"AUTHORS",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"4",
|
||||
"PULL",
|
||||
|
@ -166,8 +175,9 @@ Array [
|
|||
"sourcecred",
|
||||
"github",
|
||||
"AUTHORS",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"4",
|
||||
"PULL",
|
||||
|
@ -183,8 +193,9 @@ Array [
|
|||
"sourcecred",
|
||||
"github",
|
||||
"AUTHORS",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"6",
|
||||
"COMMENT",
|
||||
|
@ -202,8 +213,9 @@ Array [
|
|||
"sourcecred",
|
||||
"github",
|
||||
"AUTHORS",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"6",
|
||||
"COMMENT",
|
||||
|
@ -221,8 +233,9 @@ Array [
|
|||
"sourcecred",
|
||||
"github",
|
||||
"AUTHORS",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"6",
|
||||
"COMMENT",
|
||||
|
@ -240,8 +253,9 @@ Array [
|
|||
"sourcecred",
|
||||
"github",
|
||||
"AUTHORS",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"6",
|
||||
"COMMENT",
|
||||
|
@ -259,8 +273,9 @@ Array [
|
|||
"sourcecred",
|
||||
"github",
|
||||
"AUTHORS",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"6",
|
||||
"COMMENT",
|
||||
|
@ -278,8 +293,9 @@ Array [
|
|||
"sourcecred",
|
||||
"github",
|
||||
"AUTHORS",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"6",
|
||||
"COMMENT",
|
||||
|
@ -297,8 +313,9 @@ Array [
|
|||
"sourcecred",
|
||||
"github",
|
||||
"AUTHORS",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"6",
|
||||
"COMMENT",
|
||||
|
@ -316,8 +333,9 @@ Array [
|
|||
"sourcecred",
|
||||
"github",
|
||||
"AUTHORS",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"6",
|
||||
"COMMENT",
|
||||
|
@ -335,8 +353,9 @@ Array [
|
|||
"sourcecred",
|
||||
"github",
|
||||
"AUTHORS",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"6",
|
||||
"COMMENT",
|
||||
|
@ -354,8 +373,9 @@ Array [
|
|||
"sourcecred",
|
||||
"github",
|
||||
"AUTHORS",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"6",
|
||||
"COMMENT",
|
||||
|
@ -373,8 +393,9 @@ Array [
|
|||
"sourcecred",
|
||||
"github",
|
||||
"AUTHORS",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"6",
|
||||
"COMMENT",
|
||||
|
@ -392,8 +413,9 @@ Array [
|
|||
"sourcecred",
|
||||
"github",
|
||||
"AUTHORS",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"6",
|
||||
"COMMENT",
|
||||
|
@ -411,8 +433,9 @@ Array [
|
|||
"sourcecred",
|
||||
"github",
|
||||
"AUTHORS",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"wchargin",
|
||||
"4",
|
||||
"ISSUE",
|
||||
|
@ -428,8 +451,9 @@ Array [
|
|||
"sourcecred",
|
||||
"github",
|
||||
"AUTHORS",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"wchargin",
|
||||
"4",
|
||||
"PULL",
|
||||
|
@ -445,8 +469,9 @@ Array [
|
|||
"sourcecred",
|
||||
"github",
|
||||
"AUTHORS",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"wchargin",
|
||||
"5",
|
||||
"REVIEW",
|
||||
|
@ -463,8 +488,9 @@ Array [
|
|||
"sourcecred",
|
||||
"github",
|
||||
"AUTHORS",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"wchargin",
|
||||
"5",
|
||||
"REVIEW",
|
||||
|
@ -481,8 +507,9 @@ Array [
|
|||
"sourcecred",
|
||||
"github",
|
||||
"AUTHORS",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"wchargin",
|
||||
"6",
|
||||
"COMMENT",
|
||||
|
@ -500,8 +527,9 @@ Array [
|
|||
"sourcecred",
|
||||
"github",
|
||||
"AUTHORS",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"wchargin",
|
||||
"7",
|
||||
"COMMENT",
|
||||
|
@ -1005,8 +1033,9 @@ Array [
|
|||
"sourcecred",
|
||||
"example-github",
|
||||
"5",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"wchargin",
|
||||
],
|
||||
"dstIndex": 30,
|
||||
|
@ -1135,8 +1164,9 @@ Array [
|
|||
"example-github",
|
||||
"2",
|
||||
"385576273",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"wchargin",
|
||||
],
|
||||
"dstIndex": 30,
|
||||
|
@ -1557,12 +1587,14 @@ Array [
|
|||
"sourcecred",
|
||||
"github",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
],
|
||||
Array [
|
||||
"sourcecred",
|
||||
"github",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"wchargin",
|
||||
],
|
||||
],
|
||||
|
|
|
@ -6,8 +6,9 @@ Object {
|
|||
"sourcecred",
|
||||
"github",
|
||||
"AUTHORS",
|
||||
"2",
|
||||
"3",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
"4",
|
||||
"ISSUE",
|
||||
|
@ -27,6 +28,7 @@ Object {
|
|||
"sourcecred",
|
||||
"github",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
],
|
||||
}
|
||||
|
|
|
@ -183,10 +183,12 @@ Object {
|
|||
"sourcecred",
|
||||
"github",
|
||||
"USERLIKE",
|
||||
"USER",
|
||||
"decentralion",
|
||||
],
|
||||
"structured": Object {
|
||||
"login": "decentralion",
|
||||
"subtype": "USER",
|
||||
"type": "USERLIKE",
|
||||
},
|
||||
}
|
||||
|
|
|
@ -39,7 +39,11 @@ describe("plugins/github/edges", () => {
|
|||
parent: nodeExamples.review(),
|
||||
id: "171460198",
|
||||
}),
|
||||
user: () => ({type: GN.USERLIKE_TYPE, login: "decentralion"}),
|
||||
user: () => ({
|
||||
type: GN.USERLIKE_TYPE,
|
||||
subtype: "USER",
|
||||
login: "decentralion",
|
||||
}),
|
||||
};
|
||||
|
||||
const edgeExamples = {
|
||||
|
|
|
@ -11,8 +11,16 @@ function exampleView() {
|
|||
return new GraphView(exampleGraph());
|
||||
}
|
||||
|
||||
const decentralion = {type: "USERLIKE", login: "decentralion"};
|
||||
const wchargin = {type: "USERLIKE", login: "wchargin"};
|
||||
const decentralion: GN.UserlikeAddress = {
|
||||
type: "USERLIKE",
|
||||
subtype: "USER",
|
||||
login: "decentralion",
|
||||
};
|
||||
const wchargin: GN.UserlikeAddress = {
|
||||
type: "USERLIKE",
|
||||
subtype: "USER",
|
||||
login: "wchargin",
|
||||
};
|
||||
|
||||
describe("plugins/github/graphView", () => {
|
||||
const view = exampleView();
|
||||
|
@ -141,6 +149,7 @@ describe("plugins/github/graphView", () => {
|
|||
describe("invariants", () => {
|
||||
const userlike: GN.UserlikeAddress = {
|
||||
type: "USERLIKE",
|
||||
subtype: "USER",
|
||||
login: "decentralion",
|
||||
};
|
||||
const repo: GN.RepoAddress = {
|
||||
|
@ -232,7 +241,11 @@ describe("plugins/github/graphView", () => {
|
|||
failsForEdge(badEdge);
|
||||
});
|
||||
it("src must be author in edge address", () => {
|
||||
const otherAuthor = {type: "USERLIKE", login: "wchargin"};
|
||||
const otherAuthor = {
|
||||
type: "USERLIKE",
|
||||
subtype: "USER",
|
||||
login: "wchargin",
|
||||
};
|
||||
const authorsEdge = GE.createEdge.authors(otherAuthor, issue);
|
||||
(authorsEdge: any).src = GN.toRaw(userlike);
|
||||
const g = exampleWithParents().addEdge(authorsEdge);
|
||||
|
|
|
@ -15,6 +15,8 @@ export const PULL_TYPE: "PULL" = "PULL";
|
|||
export const REVIEW_TYPE: "REVIEW" = "REVIEW";
|
||||
export const COMMENT_TYPE: "COMMENT" = "COMMENT";
|
||||
export const USERLIKE_TYPE: "USERLIKE" = "USERLIKE";
|
||||
export const USER_SUBTYPE: "USER" = "USER";
|
||||
export const BOT_SUBTYPE: "BOT" = "BOT";
|
||||
|
||||
export const _Prefix = Object.freeze({
|
||||
base: GITHUB_PREFIX,
|
||||
|
@ -24,6 +26,8 @@ export const _Prefix = Object.freeze({
|
|||
review: _githubAddress(REVIEW_TYPE),
|
||||
comment: _githubAddress(COMMENT_TYPE),
|
||||
userlike: _githubAddress(USERLIKE_TYPE),
|
||||
user: _githubAddress(USERLIKE_TYPE, USER_SUBTYPE),
|
||||
bot: _githubAddress(USERLIKE_TYPE, BOT_SUBTYPE),
|
||||
reviewComment: _githubAddress(COMMENT_TYPE, REVIEW_TYPE),
|
||||
issueComment: _githubAddress(COMMENT_TYPE, ISSUE_TYPE),
|
||||
pullComment: _githubAddress(COMMENT_TYPE, PULL_TYPE),
|
||||
|
@ -56,6 +60,7 @@ export type CommentAddress = {|
|
|||
|};
|
||||
export type UserlikeAddress = {|
|
||||
+type: typeof USERLIKE_TYPE,
|
||||
+subtype: typeof USER_SUBTYPE | typeof BOT_SUBTYPE,
|
||||
+login: string,
|
||||
|};
|
||||
|
||||
|
@ -196,11 +201,14 @@ export function fromRaw(x: RawAddress): StructuredAddress {
|
|||
}
|
||||
}
|
||||
case USERLIKE_TYPE: {
|
||||
if (rest.length !== 1) {
|
||||
if (rest.length !== 2) {
|
||||
throw fail();
|
||||
}
|
||||
const [login] = rest;
|
||||
return {type: USERLIKE_TYPE, login};
|
||||
const [subtype, login] = rest;
|
||||
if (subtype !== "USER" && subtype !== "BOT") {
|
||||
throw fail();
|
||||
}
|
||||
return {type: USERLIKE_TYPE, subtype, login};
|
||||
}
|
||||
default:
|
||||
throw fail();
|
||||
|
@ -264,7 +272,14 @@ export function toRaw(x: StructuredAddress): RawAddress {
|
|||
throw new Error(`Bad comment parent type: ${(x.parent.type: empty)}`);
|
||||
}
|
||||
case USERLIKE_TYPE:
|
||||
return NodeAddress.append(_Prefix.userlike, x.login);
|
||||
switch (x.subtype) {
|
||||
case "BOT":
|
||||
return NodeAddress.append(_Prefix.bot, x.login);
|
||||
case "USER":
|
||||
return NodeAddress.append(_Prefix.user, x.login);
|
||||
default:
|
||||
throw new Error((x.subtype: empty));
|
||||
}
|
||||
default:
|
||||
throw new Error(`Unexpected type ${(x.type: empty)}`);
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ describe("plugins/github/nodes", () => {
|
|||
});
|
||||
const user = (): GN.UserlikeAddress => ({
|
||||
type: GN.USERLIKE_TYPE,
|
||||
subtype: "USER",
|
||||
login: "decentralion",
|
||||
});
|
||||
|
||||
|
@ -205,8 +206,13 @@ describe("plugins/github/nodes", () => {
|
|||
});
|
||||
describe("userlike", () => {
|
||||
checkBadCases([
|
||||
{name: "no login", parts: [GN.USERLIKE_TYPE]},
|
||||
{name: "extra parts", parts: ["decentra", "lion"]},
|
||||
{name: "no subtype", parts: [GN.USERLIKE_TYPE]},
|
||||
{name: "bad subtype", parts: [GN.USERLIKE_TYPE, "FOO"]},
|
||||
{name: "no login", parts: [GN.USERLIKE_TYPE, GN.USER_SUBTYPE]},
|
||||
{
|
||||
name: "extra parts",
|
||||
parts: [GN.USERLIKE_TYPE, GN.USER_SUBTYPE, "decentra", "lion"],
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -344,6 +344,8 @@ export class RelationalView {
|
|||
} else {
|
||||
const address: UserlikeAddress = {
|
||||
type: N.USERLIKE_TYPE,
|
||||
// TODO: Detect bots and give them a different subtype (#696)
|
||||
subtype: N.USER_SUBTYPE,
|
||||
login: json.login,
|
||||
};
|
||||
const entry: UserlikeEntry = {address, url: json.url};
|
||||
|
|
Loading…
Reference in New Issue