Skip to content

Commit

Permalink
Feat/send email on rr creation (#1125)
Browse files Browse the repository at this point in the history
* feat: send email on rr creation

* fix: email formatting

* fix: tests

* fix: formatting

* fix: spacing

* fix: copy
  • Loading branch information
alexanderleegs authored Feb 15, 2024
1 parent 912a887 commit fd20e45
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 3 deletions.
5 changes: 5 additions & 0 deletions src/integration/NotificationOnEditHandler.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import { FooterYmlService } from "@root/services/fileServices/YmlFileServices/Fo
import DeploymentsService from "@root/services/identity/DeploymentsService"
import PreviewService from "@root/services/identity/PreviewService"
import { SitesCacheService } from "@root/services/identity/SitesCacheService"
import MailClient from "@root/services/utilServices/MailClient"
import RepoService from "@services/db/RepoService"
import { ConfigYmlService } from "@services/fileServices/YmlFileServices/ConfigYmlService"
import { getUsersService, notificationsService } from "@services/identity"
Expand All @@ -62,6 +63,9 @@ const mockGithubService = {
getComments: jest.fn(),
getCommitDiff: jest.fn(),
}
const mockMailer = ({
sendMail: jest.fn(),
} as unknown) as MailClient
const usersService = getUsersService(sequelize)
const footerYmlService = new FooterYmlService({
gitHubService: mockGithubService,
Expand Down Expand Up @@ -114,6 +118,7 @@ const pageService = new PageService({
const configService = new ConfigService()
const reviewRequestService = new ReviewRequestService(
(mockGithubService as unknown) as RepoService,
mockMailer,
User,
ReviewRequest,
Reviewer,
Expand Down
5 changes: 5 additions & 0 deletions src/integration/Notifications.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import PreviewService from "@root/services/identity/PreviewService"
import { SitesCacheService } from "@root/services/identity/SitesCacheService"
import SitesService from "@root/services/identity/SitesService"
import ReviewRequestService from "@root/services/review/ReviewRequestService"
import MailClient from "@root/services/utilServices/MailClient"
import { isomerRepoAxiosInstance } from "@services/api/AxiosInstance"
import GitFileSystemService from "@services/db/GitFileSystemService"
import RepoService from "@services/db/RepoService"
Expand All @@ -68,6 +69,9 @@ const MOCK_SITE = "mockSite"
const MOCK_SITE_ID = "1"
const MOCK_SITE_MEMBER_ID = "1"

const mockMailer = ({
sendMail: jest.fn(),
} as unknown) as MailClient
const gitFileSystemService = new GitFileSystemService(simpleGit())
const gitFileCommitService = new GitFileCommitService(gitFileSystemService)
const gitHubService = new RepoService({
Expand Down Expand Up @@ -116,6 +120,7 @@ const pageService = new PageService({
const configService = new ConfigService()
const reviewRequestService = new ReviewRequestService(
(gitHubService as unknown) as RepoService,
mockMailer,
User,
ReviewRequest,
Reviewer,
Expand Down
5 changes: 5 additions & 0 deletions src/integration/Privatisation.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ import DeploymentsService from "@root/services/identity/DeploymentsService"
import PreviewService from "@root/services/identity/PreviewService"
import { SitesCacheService } from "@root/services/identity/SitesCacheService"
import AuthorizationMiddlewareService from "@root/services/middlewareServices/AuthorizationMiddlewareService"
import MailClient from "@root/services/utilServices/MailClient"
import { isomerRepoAxiosInstance } from "@services/api/AxiosInstance"
import GitFileSystemService from "@services/db/GitFileSystemService"
import RepoService from "@services/db/RepoService"
Expand Down Expand Up @@ -97,6 +98,9 @@ jest.mock("../services/identity/DeploymentClient", () =>
.mockImplementation(() => ok(mockDeleteInput)),
}))
)
const mockMailer = ({
sendMail: jest.fn(),
} as unknown) as MailClient
const gitFileSystemService = new GitFileSystemService(simpleGit())
const gitFileCommitService = new GitFileCommitService(gitFileSystemService)

Expand Down Expand Up @@ -146,6 +150,7 @@ const pageService = new PageService({
const configService = new ConfigService()
const reviewRequestService = new ReviewRequestService(
(gitHubService as unknown) as RepoService,
mockMailer,
User,
ReviewRequest,
Reviewer,
Expand Down
6 changes: 6 additions & 0 deletions src/integration/Reviews.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ import { FooterYmlService } from "@root/services/fileServices/YmlFileServices/Fo
import DeploymentsService from "@root/services/identity/DeploymentsService"
import PreviewService from "@root/services/identity/PreviewService"
import { SitesCacheService } from "@root/services/identity/SitesCacheService"
import MailClient from "@root/services/utilServices/MailClient"
import { ReviewRequestDto } from "@root/types/dto/review"
import { isomerRepoAxiosInstance } from "@services/api/AxiosInstance"
import GitFileSystemService from "@services/db/GitFileSystemService"
Expand All @@ -102,6 +103,10 @@ import SitesService from "@services/identity/SitesService"
import ReviewRequestService from "@services/review/ReviewRequestService"
import { sequelize } from "@tests/database"

const mockMailer = ({
sendMail: jest.fn(),
} as unknown) as MailClient

const gitFileSystemService = new GitFileSystemService(simpleGit())
const gitFileCommitService = new GitFileCommitService(gitFileSystemService)

Expand Down Expand Up @@ -151,6 +156,7 @@ const pageService = new PageService({
const configService = new ConfigService()
const reviewRequestService = new ReviewRequestService(
(gitHubService as unknown) as RepoService,
mockMailer,
User,
ReviewRequest,
Reviewer,
Expand Down
5 changes: 5 additions & 0 deletions src/integration/Sites.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import DynamoDBService from "@root/services/infra/DynamoDBService"
import InfraService from "@root/services/infra/InfraService"
import StepFunctionsService from "@root/services/infra/StepFunctionsService"
import ReviewRequestService from "@root/services/review/ReviewRequestService"
import MailClient from "@root/services/utilServices/MailClient"
import GitFileSystemService from "@services/db/GitFileSystemService"
import RepoService from "@services/db/RepoService"
import { getIdentityAuthService, getUsersService } from "@services/identity"
Expand All @@ -65,6 +66,9 @@ const mockUpdatedAt = "now"
const mockPermissions = { push: true }
const mockPrivate = true

const mockMailer = ({
sendMail: jest.fn(),
} as unknown) as MailClient
const gitFileSystemService = new GitFileSystemService(simpleGit())

const gitFileCommitService = new GitFileCommitService(gitFileSystemService)
Expand Down Expand Up @@ -114,6 +118,7 @@ const pageService = new PageService({
const configService = new ConfigService()
const reviewRequestService = new ReviewRequestService(
gitHubService,
mockMailer,
User,
ReviewRequest,
Reviewer,
Expand Down
2 changes: 2 additions & 0 deletions src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ import SitesService from "@services/identity/SitesService"
import InfraService from "@services/infra/InfraService"
import StepFunctionsService from "@services/infra/StepFunctionsService"
import ReviewRequestService from "@services/review/ReviewRequestService"
import { mailer } from "@services/utilServices/MailClient"

import { apiLogger } from "./middleware/apiLogger"
import { NotificationOnEditHandler } from "./middleware/notificationOnEditHandler"
Expand Down Expand Up @@ -216,6 +217,7 @@ const pageService = new PageService({
})
const reviewRequestService = new ReviewRequestService(
gitHubService,
mailer,
User,
ReviewRequest,
Reviewer,
Expand Down
26 changes: 23 additions & 3 deletions src/services/review/ReviewRequestService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import RepoService from "../db/RepoService"
import { PageService } from "../fileServices/MdPageServices/PageService"
import PlaceholderService from "../fileServices/utils/PlaceholderService"
import { ConfigService } from "../fileServices/YmlFileServices/ConfigService"
import MailClient from "../utilServices/MailClient"

const injectDefaultEditMeta = ({
path,
Expand Down Expand Up @@ -82,6 +83,8 @@ const injectDefaultEditMeta = ({
export default class ReviewRequestService {
private readonly apiService: RepoService

private readonly mailer: MailClient

private readonly repository: ModelStatic<ReviewRequest>

private readonly users: ModelStatic<User>
Expand All @@ -100,6 +103,7 @@ export default class ReviewRequestService {

constructor(
apiService: RepoService,
mailer: MailClient,
users: ModelStatic<User>,
repository: ModelStatic<ReviewRequest>,
reviewers: ModelStatic<Reviewer>,
Expand All @@ -110,6 +114,7 @@ export default class ReviewRequestService {
sequelize: Sequelize
) {
this.apiService = apiService
this.mailer = mailer
this.users = users
this.repository = repository
this.reviewers = reviewers
Expand Down Expand Up @@ -349,13 +354,28 @@ export default class ReviewRequestService {
requestorId: requestor.id,
siteId: site.id,
})
const subject = `[${siteName}] You've been requested to review some changes`
const emailBody = `<p>Hi there,</p>
<p>${requestor.email} has requested you to review and approve changes made to ${siteName}. You can see the changes and approve them, or add comments for site collaborators to see.</p>
<br />
<p><a href="https://cms.isomer.gov.sg/sites/${siteName}/review/${pullRequestNumber}" target="_blank">Click to see the review request on IsomerCMS</a></p>
<br />
<p>If this is your first time approving or publishing a review request, <a href="https://guide.isomer.gov.sg/publish-changes-and-site-launch/for-email-login-users/approve-and-publish-a-review-request" target="_blank">this article from our Isomer Guide</a> might help.</p>
<br />
<p>Best,<br />
The Isomer Team</p>`
await Promise.all(
reviewers.map(({ id }) =>
this.reviewers.create({
reviewers.map(async ({ id, email: reviewerEmail }) => {
await this.reviewers.create({
requestId: reviewRequest.id,
reviewerId: id,
})
)
if (!reviewerEmail) {
// Should not reach here
throw new Error(`Reviewer with id ${id} has no email`)
}
await this.mailer.sendMail(reviewerEmail, subject, emailBody)
})
)

await this.reviewMeta.create({
Expand Down
6 changes: 6 additions & 0 deletions src/services/review/__tests__/ReviewRequestService.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import {
import { mockUserWithSiteSessionData } from "@root/fixtures/sessionData"
import { PageService } from "@root/services/fileServices/MdPageServices/PageService"
import { ConfigService } from "@root/services/fileServices/YmlFileServices/ConfigService"
import MailClient from "@root/services/utilServices/MailClient"
import { GithubCommentData } from "@root/types/dto/review"
import { Commit } from "@root/types/github"
import RepoService from "@services/db/RepoService"
Expand Down Expand Up @@ -119,8 +120,13 @@ const MockSequelize = {
transaction: jest.fn((transaction) => transaction()),
}

const mockMailer = ({
sendMail: jest.fn(),
} as unknown) as MailClient

const ReviewRequestService = new _ReviewRequestService(
(MockReviewApi as unknown) as RepoService,
mockMailer,
(MockUsersRepository as unknown) as ModelStatic<User>,
(MockReviewRequestRepository as unknown) as ModelStatic<ReviewRequest>,
(MockReviewersRepository as unknown) as ModelStatic<Reviewer>,
Expand Down

0 comments on commit fd20e45

Please sign in to comment.