Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/comments #534

Merged
merged 12 commits into from
Nov 2, 2022
66 changes: 65 additions & 1 deletion src/routes/v2/authenticated/review.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import UsersService from "@root/services/identity/UsersService"
import { isIsomerError, RequestHandler } from "@root/types"
import { ResponseErrorBody } from "@root/types/dto/error"
import {
CommentItem,
DashboardReviewRequestDto,
EditedItemDto,
UpdateReviewRequestDto,
Expand Down Expand Up @@ -634,6 +635,61 @@ export class ReviewsRouter {
return res.status(200).send()
}

getComments: RequestHandler<
{ siteName: string; requestId: number },
CommentItem[],
seaerchin marked this conversation as resolved.
Show resolved Hide resolved
never,
unknown,
{ userWithSiteSessionData: UserWithSiteSessionData }
> = async (req, res) => {
const { siteName, requestId } = req.params
const { userWithSiteSessionData } = res.locals
// Step 1: Check that the site exists
const site = await this.sitesService.getBySiteName(siteName)
if (!site) {
logger.error({
message: "Invalid site requested",
method: "getComments",
meta: {
userId: userWithSiteSessionData.isomerUserId,
email: userWithSiteSessionData.email,
siteName,
},
})
return res.status(404).send({
seaerchin marked this conversation as resolved.
Show resolved Hide resolved
message: "Please ensure that the site exists!",
})
}

// Step 2: Retrieve comments
const comments = await this.reviewRequestService.getComments(
userWithSiteSessionData,
seaerchin marked this conversation as resolved.
Show resolved Hide resolved
site,
requestId
)

return res.status(200).json(comments)
}

createComment: RequestHandler<
{ siteName: string; requestId: number },
string | ResponseErrorBody,
seaerchin marked this conversation as resolved.
Show resolved Hide resolved
{ message: string },
unknown,
{ userWithSiteSessionData: UserWithSiteSessionData }
> = async (req, res) => {
const { requestId } = req.params
const { message } = req.body
const { userWithSiteSessionData } = res.locals
await this.reviewRequestService.createComment(
userWithSiteSessionData,
requestId,
message
)

return res.status(200).send("OK")
}

markReviewRequestCommentsAsViewed: RequestHandler<
{ siteName: string; requestId: number },
string | ResponseErrorBody,
Expand Down Expand Up @@ -794,8 +850,16 @@ export class ReviewsRouter {
"/:requestId/approve",
attachReadRouteHandlerWrapper(this.approveReviewRequest)
)
router.get(
"/:requestId/comments",
attachWriteRouteHandlerWrapper(this.getComments)
)
router.post(
"/:requestId/comments",
attachWriteRouteHandlerWrapper(this.createComment)
)
router.post(
"/:requestId/viewedComments",
"/:requestId/comments/viewedComments",
attachWriteRouteHandlerWrapper(this.markReviewRequestCommentsAsViewed)
)
router.post(
Expand Down
8 changes: 8 additions & 0 deletions src/services/db/GitHubService.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ class GitHubService {
return ReviewApi.approvePullRequest(siteName, pullRequestNumber)
}

async getComments(siteName, pullRequestNumber) {
return ReviewApi.getComments(siteName, pullRequestNumber)
}

async createComment(siteName, pullRequestNumber, user, message) {
return ReviewApi.createComment(siteName, pullRequestNumber, user, message)
}

getFilePath({ siteName, fileName, directoryName }) {
if (!directoryName)
return `${siteName}/contents/${encodeURIComponent(fileName)}`
Expand Down
48 changes: 47 additions & 1 deletion src/services/db/review.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { RawFileChangeInfo, Commit, RawPullRequest } from "@root/types/github"
import _ from "lodash"

import {
RawFileChangeInfo,
Commit,
RawPullRequest,
RawComment,
fromGithubCommitMessage,
} from "@root/types/github"

import { isomerRepoAxiosInstance as axiosInstance } from "../api/AxiosInstance"

Expand Down Expand Up @@ -83,3 +91,41 @@ export const approvePullRequest = (
},
}
)

export const getComments = async (
siteName: string,
pullRequestNumber: number
) => {
const rawComments = await axiosInstance
.get<RawComment[]>(`${siteName}/issues/${pullRequestNumber}/comments`)
.then(({ data }) => data)
return _.compact(
rawComments.map((rawComment) => {
const commentData = fromGithubCommitMessage(rawComment.body)
if (_.isEmpty(commentData)) return null // Will be filtered out by _.compact
const { userId, message } = commentData
if (!userId || !message) return null // Will be filtered out by _.compact
return {
userId,
message,
createdAt: rawComment.created_at,
}
})
Comment on lines +102 to +113
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: might be better off as map -> filter -> map but this is ok as is too

)
}

export const createComment = async (
siteName: string,
pullRequestNumber: number,
userId: string,
message: string
) => {
const stringifiedMessage = JSON.stringify({
userId,
message,
})
return axiosInstance.post<void>(
`${siteName}/issues/${pullRequestNumber}/comments`,
{ body: stringifiedMessage }
)
}
78 changes: 78 additions & 0 deletions src/services/review/ReviewRequestService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { Site } from "@root/database/models/Site"
import { User } from "@root/database/models/User"
import RequestNotFoundError from "@root/errors/RequestNotFoundError"
import {
CommentItem,
DashboardReviewRequestDto,
EditedItemDto,
FileType,
Expand Down Expand Up @@ -125,6 +126,29 @@ export default class ReviewRequestService {
return mappings
}

computeCommentDataMappings = async (
seaerchin marked this conversation as resolved.
Show resolved Hide resolved
comments: {
userId: string
message: string
createdAt: string
}[],
seaerchin marked this conversation as resolved.
Show resolved Hide resolved
viewedTime: Date | null
) => {
const mappings = await Promise.all(
comments.map(async ({ userId, message, createdAt }) => {
const createdTime = new Date(createdAt)
const author = await this.users.findByPk(userId)
return {
user: author?.email || "",
message,
createdAt: createdTime.getTime(),
isRead: viewedTime ? createdTime < viewedTime : false,
}
})
)
return mappings
}

createReviewRequest = async (
sessionData: UserWithSiteSessionData,
reviewers: User[],
Expand Down Expand Up @@ -455,4 +479,58 @@ export default class ReviewRequestService {
reviewRequest.reviewStatus = ReviewRequestStatus.Merged
return reviewRequest.save()
}

createComment = async (
sessionData: UserWithSiteSessionData,
pullRequestNumber: number,
message: string
) => {
const { siteName, isomerUserId } = sessionData

return this.apiService.createComment(
siteName,
pullRequestNumber,
isomerUserId,
message
)
}

getComments = async (
sessionData: UserWithSiteSessionData,
site: Site,
pullRequestNumber: number
): Promise<CommentItem[]> => {
const { siteName, isomerUserId: userId } = sessionData

const comments = await this.apiService.getComments(
siteName,
pullRequestNumber
)

const requestsView = await this.reviewRequestView.findOne({
where: {
siteId: site.id,
userId,
},
include: [
{
model: ReviewRequest,
required: true,
include: [
{
model: ReviewMeta,
required: true,
where: {
pullRequestNumber,
},
},
],
},
],
})

const viewedTime = requestsView ? new Date(requestsView.lastViewedAt) : null

return this.computeCommentDataMappings(comments, viewedTime)
}
}
7 changes: 7 additions & 0 deletions src/types/dto/review.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,10 @@ export interface ReviewRequestDto {
export interface UpdateReviewRequestDto {
reviewers: string[]
}

export interface CommentItem {
user: string
createdAt: number
message: string
isRead: boolean
}
5 changes: 5 additions & 0 deletions src/types/github.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,8 @@ export interface RawPullRequest {
changed_files: number
created_at: string
}

export interface RawComment {
body: string
created_at: string
}