Skip to content

Commit

Permalink
Refinement comment functions (#15)
Browse files Browse the repository at this point in the history
* create get login names function

* add getComments function

* add function to check if the action has already send comment

* return login array when
- the action has not sent comment yet
- the amount of comments has exceeded the threshold

* fix function name

* add message generate function

* add comment post function

* update main

* update

* uninstall unused package

* run bundle

* fix to add '@' to login names
  • Loading branch information
tnyo43 committed Mar 10, 2024
1 parent 1416075 commit f14d8bf
Show file tree
Hide file tree
Showing 10 changed files with 397 additions and 117 deletions.
208 changes: 162 additions & 46 deletions dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 0 additions & 10 deletions dist/licenses.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions src/comments/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const ACTION_IDENTIFY_TEXT =
'<!-- a sentence for identifying bot recommend-mobpro-action -->';
60 changes: 60 additions & 0 deletions src/comments/getCommentContent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import {
type CommentContent,
type Octokit,
type OctokitContext,
type User,
} from './types';
import { getLoginNames } from './getLoginNames';
import { isAlreadyCommented } from './isAlreadyCommented';

type Args = {
threshold: number;
};

export async function getCommentContent(
octokit: Octokit,
octokitContext: OctokitContext,
args: Args,
): Promise<CommentContent | null> {
const { owner, repo, prNumber } = octokitContext;

const comments = (
await octokit.rest.issues.listComments({
owner,
repo,
issue_number: prNumber,
})
).data;

if (isAlreadyCommented(comments)) {
return null;
}

const reviewComments = (
await octokit.rest.pulls.listReviewComments({
owner,
repo,
pull_number: prNumber,
})
).data;

const numberOfComments = comments.length + reviewComments.length;
if (numberOfComments < args.threshold) {
return null;
}

const users1: User[] = comments
.map((comment) => comment.user)
.filter((user): user is Exclude<typeof user, null> => user !== null);
const users2: User[] = reviewComments
.map((comment) => comment.user)
.filter((user): user is Exclude<typeof user, null> => user !== null);

const logins = getLoginNames(users1.concat(users2));

return {
logins,
numberOfComments,
threshold: args.threshold,
};
}
52 changes: 52 additions & 0 deletions src/comments/getLoginNames.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { getLoginNames } from './getLoginNames';

test('if the input is an empty array, the output is also empty', () => {
const result = getLoginNames([]);
expect(result).toStrictEqual([]);
});

describe('if the input is an array without duplicates, the output is a array with the same elements in alphabetical order', () => {
test('in case: ["alice", "bob", "chris"]', () => {
const result = getLoginNames([
{ login: 'alice', type: 'User' },
{ login: 'bob', type: 'User' },
{ login: 'chris', type: 'User' },
]);
expect(result).toStrictEqual(['alice', 'bob', 'chris']);
});

test('in case: ["freddy", "eric", "daniel"]', () => {
const result = getLoginNames([
{ login: 'freddy', type: 'User' },
{ login: 'eric', type: 'User' },
{ login: 'daniel', type: 'User' },
]);
expect(result).toStrictEqual(['daniel', 'eric', 'freddy']);
});
});

describe('if the input is an array containing duplicates, the output is an array where each name appears only once', () => {
test('in case: ["alice", "bob", "chris", "alice", "chris", "alice"]', () => {
const result = getLoginNames([
{ login: 'alice', type: 'User' },
{ login: 'bob', type: 'User' },
{ login: 'chris', type: 'User' },
{ login: 'alice', type: 'User' },
{ login: 'chris', type: 'User' },
{ login: 'alice', type: 'User' },
]);
expect(result).toStrictEqual(['alice', 'bob', 'chris']);
});
});

test('if the input has elements whose "type" property is "Bot", the output is an array without those elements', () => {
const result = getLoginNames([
{ login: 'bot1', type: 'Bot' },
{ login: 'bob', type: 'User' },
{ login: 'chris', type: 'User' },
{ login: 'bot2', type: 'Bot' },
{ login: 'bot3', type: 'Bot' },
{ login: 'bob', type: 'User' },
]);
expect(result).toStrictEqual(['bob', 'chris']);
});
24 changes: 24 additions & 0 deletions src/comments/getLoginNames.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { type User } from './types';

function uniqueStringArray(texts: string[]): string[] {
if (texts.length === 0) return [];

const sorted = texts.sort();
const result = [sorted[0]];

for (let i = 0; i < sorted.length - 1; i++) {
if (sorted[i + 1] !== sorted[i]) {
result.push(sorted[i + 1]);
}
}

return result;
}

export function getLoginNames(users: User[]): string[] {
const loginNameArray = users
.filter((user) => user.type === 'User')
.map((user) => user.login);

return uniqueStringArray(loginNameArray);
}
8 changes: 8 additions & 0 deletions src/comments/isAlreadyCommented.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { type Comment } from './types';
import { ACTION_IDENTIFY_TEXT } from './constants';

export function isAlreadyCommented(comments: Comment[]): boolean {
return comments.some((comment) =>
comment.body?.startsWith(ACTION_IDENTIFY_TEXT),
);
}
Loading

0 comments on commit f14d8bf

Please sign in to comment.