Skip to content

Commit

Permalink
fix: Don't overwrite req with parsedReq (#2354)
Browse files Browse the repository at this point in the history
* fix: Don't overwrite req with parsedReq

* fix: Update schema, add tests
  • Loading branch information
DafyddLlyr authored Nov 2, 2023
1 parent 4e29137 commit cde4cd5
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 48 deletions.
14 changes: 7 additions & 7 deletions api.planx.uk/modules/analytics/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ValidatedRequestHandler } from "../../shared/middleware/validate";

export const logAnalyticsSchema = z.object({
query: z.object({
analyticsLogId: z.string(),
analyticsLogId: z.string().pipe(z.coerce.number()),
}),
});

Expand All @@ -13,14 +13,14 @@ export type LogAnalytics = ValidatedRequestHandler<
Record<string, never>
>;

export const logUserExitController: LogAnalytics = async (req, res) => {
const { analyticsLogId } = req.query;
trackAnalyticsLogExit({ id: Number(analyticsLogId), isUserExit: true });
export const logUserExitController: LogAnalytics = async (_req, res) => {
const { analyticsLogId } = res.locals.parsedReq.query;
trackAnalyticsLogExit({ id: analyticsLogId, isUserExit: true });
res.status(204).send();
};

export const logUserResumeController: LogAnalytics = async (req, res) => {
const { analyticsLogId } = req.query;
trackAnalyticsLogExit({ id: Number(analyticsLogId), isUserExit: false });
export const logUserResumeController: LogAnalytics = async (_req, res) => {
const { analyticsLogId } = res.locals.parsedReq.query;
trackAnalyticsLogExit({ id: analyticsLogId, isUserExit: false });
res.status(204).send();
};
18 changes: 9 additions & 9 deletions api.planx.uk/modules/team/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ export type RemoveMember = ValidatedRequestHandler<
TeamMemberResponse
>;

export const addMember: UpsertMember = async (req, res, next) => {
const { teamSlug } = req.params;
const { userEmail, role } = req.body;
export const addMember: UpsertMember = async (_req, res, next) => {
const { teamSlug } = res.locals.parsedReq.params;
const { userEmail, role } = res.locals.parsedReq.body;

try {
await Service.addMember({ userEmail, teamSlug, role });
Expand All @@ -53,9 +53,9 @@ export const addMember: UpsertMember = async (req, res, next) => {
}
};

export const changeMemberRole: UpsertMember = async (req, res, next) => {
const { teamSlug } = req.params;
const { userEmail, role } = req.body;
export const changeMemberRole: UpsertMember = async (_req, res, next) => {
const { teamSlug } = res.locals.parsedReq.params;
const { userEmail, role } = res.locals.parsedReq.body;

try {
await Service.changeMemberRole({ userEmail, teamSlug, role });
Expand All @@ -67,9 +67,9 @@ export const changeMemberRole: UpsertMember = async (req, res, next) => {
}
};

export const removeMember: RemoveMember = async (req, res, next) => {
const { teamSlug } = req.params;
const { userEmail } = req.body;
export const removeMember: RemoveMember = async (_req, res, next) => {
const { teamSlug } = res.locals.parsedReq.params;
const { userEmail } = res.locals.parsedReq.body;

try {
await Service.removeMember({ userEmail, teamSlug });
Expand Down
9 changes: 5 additions & 4 deletions api.planx.uk/modules/user/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ export type CreateUser = ValidatedRequestHandler<
UserResponse
>;

export const createUser: CreateUser = async (req, res, next) => {
export const createUser: CreateUser = async (_req, res, next) => {
try {
const newUser = res.locals.parsedReq.body;
const $client = getClient();
await $client.user.create(req.body);
await $client.user.create(newUser);
return res.send({ message: "Successfully created user" });
} catch (error) {
return next(
Expand All @@ -44,9 +45,9 @@ export type DeleteUser = ValidatedRequestHandler<
UserResponse
>;

export const deleteUser: DeleteUser = async (req, res, next) => {
export const deleteUser: DeleteUser = async (_req, res, next) => {
try {
const { email } = req.params;
const { email } = res.locals.parsedReq.params;
const $client = getClient();

const user = await $client.user.getByEmail(email);
Expand Down
37 changes: 24 additions & 13 deletions api.planx.uk/modules/webhooks/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { SanitiseApplicationData } from "./service/sanitiseApplicationData/types
import { sanitiseApplicationData } from "./service/sanitiseApplicationData";

export const sendSlackNotificationController: SendSlackNotification = async (
req,
_req,
res,
next,
) => {
Expand All @@ -27,8 +27,9 @@ export const sendSlackNotificationController: SendSlackNotification = async (
});
}

const eventData = req.body.event.data.new;
const eventType = req.query.type;
const { body, query } = res.locals.parsedReq;
const eventData = body.event.data.new;
const eventType = query.type;

try {
const data = await sendSlackNotification(eventData, eventType);
Expand All @@ -44,9 +45,11 @@ export const sendSlackNotificationController: SendSlackNotification = async (
};

export const createPaymentInvitationEventsController: CreatePaymentEventController =
async (req, res, next) => {
async (_req, res, next) => {
try {
const response = await createPaymentInvitationEvents(req.body);
const response = await createPaymentInvitationEvents(
res.locals.parsedReq.body,
);
res.json(response);
} catch (error) {
return next(
Expand All @@ -59,9 +62,11 @@ export const createPaymentInvitationEventsController: CreatePaymentEventControll
};

export const createPaymentReminderEventsController: CreatePaymentEventController =
async (req, res, next) => {
async (_req, res, next) => {
try {
const response = await createPaymentReminderEvents(req.body);
const response = await createPaymentReminderEvents(
res.locals.parsedReq.body,
);
res.json(response);
} catch (error) {
return next(
Expand All @@ -74,9 +79,11 @@ export const createPaymentReminderEventsController: CreatePaymentEventController
};

export const createPaymentExpiryEventsController: CreatePaymentEventController =
async (req, res, next) => {
async (_req, res, next) => {
try {
const response = await createPaymentExpiryEvents(req.body);
const response = await createPaymentExpiryEvents(
res.locals.parsedReq.body,
);
res.json(response);
} catch (error) {
return next(
Expand All @@ -89,9 +96,11 @@ export const createPaymentExpiryEventsController: CreatePaymentEventController =
};

export const createSessionReminderEventController: CreateSessionEventController =
async (req, res, next) => {
async (_req, res, next) => {
try {
const response = await createSessionReminderEvent(req.body);
const response = await createSessionReminderEvent(
res.locals.parsedReq.body,
);
res.json(response);
} catch (error) {
return next(
Expand All @@ -104,9 +113,11 @@ export const createSessionReminderEventController: CreateSessionEventController
};

export const createSessionExpiryEventController: CreateSessionEventController =
async (req, res, next) => {
async (_req, res, next) => {
try {
const response = await createSessionExpiryEvent(req.body);
const response = await createSessionExpiryEvent(
res.locals.parsedReq.body,
);
res.json(response);
} catch (error) {
return next(
Expand Down
3 changes: 3 additions & 0 deletions api.planx.uk/modules/webhooks/docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ components:
properties:
sessionId:
type: string
email:
type: string
format: email
responses:
SlackNotificationSuccessMessage:
content:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,23 @@ describe("Create reminder event webhook", () => {
it("returns a 400 if a required value is missing", async () => {
const missingCreatedAt = { createdAt: null, payload: {} };
const missingPayload = { createdAt: new Date(), payload: null };

for (const body of [missingCreatedAt, missingPayload]) {
const missingEmail = {
createdAt: new Date(),
payload: { sessionId: "abc123" },
};
const missingSessionId = {
createdAt: new Date(),
payload: { email: "[email protected]" },
};

const invalidRequestBodies = [
missingCreatedAt,
missingPayload,
missingEmail,
missingSessionId,
];

for (const body of invalidRequestBodies) {
await post(ENDPOINT)
.set({ Authorization: process.env.HASURA_PLANX_API_KEY })
.send(body)
Expand All @@ -46,7 +61,10 @@ describe("Create reminder event webhook", () => {
});

it("returns a 200 on successful event setup", async () => {
const body = { createdAt: new Date(), payload: { sessionId: "123" } };
const body = {
createdAt: new Date(),
payload: { sessionId: "123", email: "[email protected]" },
};
mockedCreateScheduledEvent.mockResolvedValue(mockScheduledEventResponse);

await post(ENDPOINT)
Expand All @@ -64,7 +82,10 @@ describe("Create reminder event webhook", () => {
});

it("passes the correct arguments along to createScheduledEvent", async () => {
const body = { createdAt: new Date(), payload: { sessionId: "123" } };
const body = {
createdAt: new Date(),
payload: { sessionId: "123", email: "[email protected]" },
};
mockedCreateScheduledEvent.mockResolvedValue(mockScheduledEventResponse);

await post(ENDPOINT)
Expand Down Expand Up @@ -96,7 +117,10 @@ describe("Create reminder event webhook", () => {
});

it("returns a 500 on event setup failure", async () => {
const body = { createdAt: new Date(), payload: { sessionId: "123" } };
const body = {
createdAt: new Date(),
payload: { sessionId: "123", email: "[email protected]" },
};
mockedCreateScheduledEvent.mockRejectedValue(new Error("Failed!"));

await post(ENDPOINT)
Expand Down Expand Up @@ -143,20 +167,27 @@ describe("Create expiry event webhook", () => {
});

it("returns a 200 on successful event setup", async () => {
const body = { createdAt: new Date(), payload: { sessionId: "123" } };
const body = {
createdAt: new Date(),
payload: { sessionId: "123", email: "[email protected]" },
};
mockedCreateScheduledEvent.mockResolvedValue(mockScheduledEventResponse);

await post(ENDPOINT)
.set({ Authorization: process.env.HASURA_PLANX_API_KEY })
.send(body)
.expect(200)
.then((response) => {
// expect(mockedCreateScheduledEvent).toHaveBeenCalledWith(body.p)
expect(response.body).toStrictEqual([mockScheduledEventResponse]);
});
});

it("passes the correct arguments along to createScheduledEvent", async () => {
const body = { createdAt: new Date(), payload: { sessionId: "123" } };
const body = {
createdAt: new Date(),
payload: { sessionId: "123", email: "[email protected]" },
};
mockedCreateScheduledEvent.mockResolvedValue(mockScheduledEventResponse);

await post(ENDPOINT)
Expand All @@ -173,7 +204,10 @@ describe("Create expiry event webhook", () => {
});

it("returns a 500 on event setup failure", async () => {
const body = { createdAt: new Date(), payload: { sessionId: "123" } };
const body = {
createdAt: new Date(),
payload: { sessionId: "123", email: "[email protected]" },
};
mockedCreateScheduledEvent.mockRejectedValue(new Error("Failed!"));

await post(ENDPOINT)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const createSessionEventSchema = z.object({
createdAt: z.string().pipe(z.coerce.date()),
payload: z.object({
sessionId: z.string(),
email: z.string().email(),
}),
}),
});
Expand Down
13 changes: 6 additions & 7 deletions api.planx.uk/shared/middleware/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,9 @@ export const validate =
query: req.query,
});

// Assign parsed values to the request object
// Assign parsed values to the response object
// Required for schemas to transform or coerce raw requests
req.params = parsedReq.params;
req.body = parsedReq.body;
req.query = parsedReq.query;
res.locals.parsedReq = parsedReq;

return next();
} catch (error) {
Expand All @@ -40,8 +38,9 @@ export type ValidatedRequestHandler<
TSchema extends ZodSchema,
TResponse,
> = RequestHandler<
z.infer<TSchema>["params"],
Request["params"],
TResponse,
z.infer<TSchema>["body"],
z.infer<TSchema>["query"]
Request["body"],
Request["query"],
{ parsedReq: z.infer<TSchema> }
>;

0 comments on commit cde4cd5

Please sign in to comment.