Skip to content

Commit

Permalink
chore: refactor formatRawProjectTypes (take 2) (#3421)
Browse files Browse the repository at this point in the history
Co-authored-by: Dafydd Llŷr Pearson <[email protected]>
  • Loading branch information
jessicamcinchak and DafyddLlyr authored Jul 15, 2024
1 parent f9035a8 commit 84670ae
Show file tree
Hide file tree
Showing 22 changed files with 193 additions and 150 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,31 +58,13 @@ describe("sendAgentAndPayeeConfirmationEmail", () => {
],
},
});
queryMock.mockQuery({
name: "LookupHumanReadableProjectType",
variables: {
rawList: [
"alter.internal",
"alter.openings.add.doors.rear",
"alter.facades.paint",
],
},
data: {
projectTypes: [
{ description: "internal alterations" },
{ description: "addition of doorways to the rear of the building" },
{ description: "painting of facades" },
],
},
});

const expectedConfig = {
personalisation: {
applicantName: "xyz",
payeeName: "payeeName",
address: "123 PLACE",
projectType:
"Internal alterations, addition of doorways to the rear of the building, and painting of facades",
projectType: "Paint the facade and changes to internal walls or layout",
emailReplyToId: "123",
helpEmail: "[email protected]",
helpOpeningHours: "9-5",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { $public, $api } from "../../../../client";
import { sendEmail } from "../../../../lib/notify";
import { formatRawProjectTypes } from "@opensystemslab/planx-core";
import { gql } from "graphql-request";
import { $api } from "../../../../client";
import { sendEmail } from "../../../../lib/notify";
import type { AgentAndPayeeSubmissionNotifyConfig } from "../../../../types";

export async function sendAgentAndPayeeConfirmationEmail(sessionId: string) {
const { personalisation, applicantEmail, payeeEmail, projectTypes } =
await getDataForPayeeAndAgentEmails(sessionId);
const projectType = projectTypes.length
? await $public.formatRawProjectTypes(projectTypes)
? formatRawProjectTypes(projectTypes)
: "Project type not submitted";
const config: AgentAndPayeeSubmissionNotifyConfig = {
personalisation: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@ import {
validatePaymentRequestNotFoundQueryMock,
validatePaymentRequestQueryMock,
} from "../../../../tests/mocks/inviteToPayMocks";
import { CoreDomainClient } from "@opensystemslab/planx-core";

jest
.spyOn(CoreDomainClient.prototype, "formatRawProjectTypes")
.mockResolvedValue("New office premises");

const TEST_PAYMENT_REQUEST_ID = "09655c28-3f34-4619-9385-cd57312acc44";

Expand Down
33 changes: 21 additions & 12 deletions api.planx.uk/modules/pay/service/inviteToPay/sendPaymentEmail.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { formatRawProjectTypes } from "@opensystemslab/planx-core";
import type { PaymentRequest, Team } from "@opensystemslab/planx-core/types";
import { gql } from "graphql-request";
import {
calculateExpiryDate,
getServiceLink,
} from "../../../saveAndReturn/service/utils";
import {
Template,
getClientForTemplate,
sendEmail,
} from "../../../../lib/notify";
import { InviteToPayNotifyConfig } from "../../../../types";
import type { PaymentRequest, Team } from "@opensystemslab/planx-core/types";
import { $public } from "../../../../client";
import {
calculateExpiryDate,
getServiceLink,
} from "../../../saveAndReturn/service/utils";

interface SessionDetails {
email: string;
Expand All @@ -37,7 +37,7 @@ const sendSinglePaymentEmail = async ({
paymentRequestId,
template,
);
const config = await getInviteToPayNotifyConfig(session, paymentRequest);
const config = getInviteToPayNotifyConfig(session, paymentRequest);
const recipient = template.includes("-agent")
? session.email
: paymentRequest.payeeEmail;
Expand Down Expand Up @@ -74,7 +74,16 @@ const validatePaymentRequest = async (
name
slug
domain
settings: team_settings
settings: team_settings {
boundaryUrl: boundary_url
boundaryBBox: boundary_bbox
homepage
helpEmail: help_email
helpPhone: help_phone
helpOpeningHours: help_opening_hours
emailReplyToId: email_reply_to_id
boundaryBBox: boundary_bbox
}
}
}
}
Expand Down Expand Up @@ -104,10 +113,10 @@ const validatePaymentRequest = async (
}
};

const getInviteToPayNotifyConfig = async (
const getInviteToPayNotifyConfig = (
session: SessionDetails,
paymentRequest: PaymentRequest,
): Promise<InviteToPayNotifyConfig> => {
): InviteToPayNotifyConfig => {
const flow = session.flow;
const { settings } = session.flow.team;

Expand All @@ -127,11 +136,11 @@ const getInviteToPayNotifyConfig = async (
).title,
fee: getFee(paymentRequest),
projectType:
(await $public.formatRawProjectTypes(
formatRawProjectTypes(
paymentRequest.sessionPreviewData?.[
"proposal.projectType"
] as string[],
)) || "Project type not submitted",
) || "Project type not submitted",
serviceName: session.flow.name,
serviceLink: getServiceLink(flow.team, flow.slug),
expiryDate: calculateExpiryDate(paymentRequest.createdAt),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,6 @@ import { Team } from "@opensystemslab/planx-core/types";
const ENDPOINT = "/resume-application";
const TEST_EMAIL = "[email protected]";

const mockFormatRawProjectTypes = jest
.fn()
.mockResolvedValue(["New office premises"]);

jest.mock("@opensystemslab/planx-core", () => {
const actualCoreDomainClient = jest.requireActual(
"@opensystemslab/planx-core",
).CoreDomainClient;

return {
CoreDomainClient: class extends actualCoreDomainClient {
constructor() {
super();
this.formatRawProjectTypes = () => mockFormatRawProjectTypes();
}
},
};
});

describe("buildContentFromSessions function", () => {
it("should return correctly formatted content for a single session", async () => {
const sessions: PartialDeep<LowCalSession>[] = [
Expand All @@ -57,7 +38,7 @@ describe("buildContentFromSessions function", () => {

const result = `Service: Apply for a Lawful Development Certificate
Address: 1 High Street
Project type: New office premises
Project type: New offices
Expiry Date: 29 May 2026
Link: example.com/team/apply-for-a-lawful-development-certificate/published?sessionId=123`;
expect(
Expand Down Expand Up @@ -127,15 +108,15 @@ describe("buildContentFromSessions function", () => {
];
const result = `Service: Apply for a Lawful Development Certificate
Address: 1 High Street
Project type: New office premises
Project type: New offices
Expiry Date: 29 May 2026
Link: example.com/team/apply-for-a-lawful-development-certificate/published?sessionId=123\n\nService: Apply for a Lawful Development Certificate
Address: 2 High Street
Project type: New office premises
Project type: New offices
Expiry Date: 29 May 2026
Link: example.com/team/apply-for-a-lawful-development-certificate/published?sessionId=456\n\nService: Apply for a Lawful Development Certificate
Address: 3 High Street
Project type: New office premises
Project type: New offices
Expiry Date: 29 May 2026
Link: example.com/team/apply-for-a-lawful-development-certificate/published?sessionId=789`;
expect(
Expand Down Expand Up @@ -187,7 +168,7 @@ describe("buildContentFromSessions function", () => {
];
const result = `Service: Apply for a Lawful Development Certificate
Address: 1 High Street
Project type: New office premises
Project type: New offices
Expiry Date: 29 May 2026
Link: example.com/team/apply-for-a-lawful-development-certificate/published?sessionId=123`;
expect(
Expand Down Expand Up @@ -220,7 +201,7 @@ describe("buildContentFromSessions function", () => {

const result = `Service: Apply for a Lawful Development Certificate
Address: Address not submitted
Project type: New office premises
Project type: New offices
Expiry Date: 29 May 2026
Link: example.com/team/apply-for-a-lawful-development-certificate/published?sessionId=123`;
expect(
Expand All @@ -232,7 +213,6 @@ describe("buildContentFromSessions function", () => {
});

it("should handle an empty project type field", async () => {
mockFormatRawProjectTypes.mockResolvedValueOnce("");
const sessions: PartialDeep<LowCalSession>[] = [
{
data: {
Expand Down
25 changes: 19 additions & 6 deletions api.planx.uk/modules/saveAndReturn/service/resumeApplication.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { formatRawProjectTypes } from "@opensystemslab/planx-core";
import type { SiteAddress, Team } from "@opensystemslab/planx-core/types";
import { differenceInDays } from "date-fns";
import { gql } from "graphql-request";
import { $api, $public } from "../../../client";

import { $api } from "../../../client";
import { sendEmail } from "../../../lib/notify";
import { LowCalSession } from "../../../types";
import { DAYS_UNTIL_EXPIRY, calculateExpiryDate, getResumeLink } from "./utils";
Expand Down Expand Up @@ -64,7 +66,16 @@ const validateRequest = async (
teams(where: { slug: { _eq: $teamSlug } }) {
slug
name
settings: team_settings
settings: team_settings {
boundaryUrl: boundary_url
boundaryBBox: boundary_bbox
homepage
helpEmail: help_email
helpPhone: help_phone
helpOpeningHours: help_opening_hours
emailReplyToId: email_reply_to_id
boundaryBBox: boundary_bbox
}
domain
}
}
Expand Down Expand Up @@ -108,13 +119,15 @@ const buildContentFromSessions = async (
sessions: LowCalSession[],
team: Team,
): Promise<string> => {
const contentBuilder = async (session: LowCalSession) => {
const contentBuilder = (session: LowCalSession) => {
const address: SiteAddress | undefined =
session.data?.passport?.data?._address;
const addressLine = address?.single_line_address || address?.title;
const projectType = await $public.formatRawProjectTypes(
session.data?.passport?.data?.["proposal.projectType"],
);
const projectType = session.data?.passport?.data?.["proposal.projectType"]
? formatRawProjectTypes(
session.data?.passport?.data?.["proposal.projectType"],
)
: "Project type not submitted";
const resumeLink = getResumeLink(session, team, session.flow.slug);
const expiryDate = calculateExpiryDate(session.created_at);

Expand Down
25 changes: 12 additions & 13 deletions api.planx.uk/modules/saveAndReturn/service/utils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { formatRawProjectTypes } from "@opensystemslab/planx-core";
import { SiteAddress, Team } from "@opensystemslab/planx-core/types";
import { format, addDays } from "date-fns";
import { addDays, format } from "date-fns";
import { gql } from "graphql-request";
import { LowCalSession } from "../../../types";

import { $api } from "../../../client";
import { Template, getClientForTemplate, sendEmail } from "../../../lib/notify";
import { $api, $public } from "../../../client";
import { LowCalSession } from "../../../types";

const DAYS_UNTIL_EXPIRY = 28;
const REMINDER_DAYS_FROM_EXPIRY = [7, 1];
Expand Down Expand Up @@ -129,7 +131,7 @@ const validateSingleSessionRequest = async (
flowSlug: session.flow.slug,
flowName: session.flow.name,
team: session.flow.team,
session: await getSessionDetails(session),
session: getSessionDetails(session),
};
} catch (error) {
throw Error(`Unable to validate request. ${(error as Error).message}`);
Expand All @@ -148,14 +150,11 @@ interface SessionDetails {
/**
* Parse session details into an object which will be read by email template
*/
export const getSessionDetails = async (
session: LowCalSession,
): Promise<SessionDetails> => {
export const getSessionDetails = (session: LowCalSession): SessionDetails => {
const passportProtectTypes =
session.data.passport?.data?.["proposal.projectType"];
const projectTypes =
passportProtectTypes &&
(await $public.formatRawProjectTypes(passportProtectTypes));
passportProtectTypes && formatRawProjectTypes(passportProtectTypes);
const address: SiteAddress | undefined =
session.data?.passport?.data?._address;
const addressLine = address?.single_line_address || address?.title;
Expand Down Expand Up @@ -280,12 +279,12 @@ export const setupEmailEventTriggers = async (sessionId: string) => {
};

export {
getSaveAndReturnPublicHeaders,
getResumeLink,
sendSingleApplicationEmail,
markSessionAsSubmitted,
DAYS_UNTIL_EXPIRY,
REMINDER_DAYS_FROM_EXPIRY,
calculateExpiryDate,
getResumeLink,
getSaveAndReturnPublicHeaders,
markSessionAsSubmitted,
sendSingleApplicationEmail,
softDeleteSession,
};
5 changes: 0 additions & 5 deletions api.planx.uk/modules/sendEmail/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,11 @@ import {
mockValidateSingleSessionRequest,
mockValidateSingleSessionRequestMissingSession,
} from "../../tests/mocks/saveAndReturnMocks";
import { CoreDomainClient } from "@opensystemslab/planx-core";

// https://docs.notifications.service.gov.uk/node.html#email-addresses
const TEST_EMAIL = "[email protected]";
const SAVE_ENDPOINT = "/send-email/save";

jest
.spyOn(CoreDomainClient.prototype, "formatRawProjectTypes")
.mockResolvedValue("New office premises");

describe("Send Email endpoint", () => {
beforeEach(() => {
queryMock.reset();
Expand Down
2 changes: 1 addition & 1 deletion api.planx.uk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"packageManager": "[email protected]",
"dependencies": {
"@airbrake/node": "^2.1.8",
"@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#f8d6480",
"@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#6c2cc59",
"@types/isomorphic-fetch": "^0.0.36",
"adm-zip": "^0.5.10",
"aws-sdk": "^2.1467.0",
Expand Down
Loading

0 comments on commit 84670ae

Please sign in to comment.