📧 Prevent users from enabling events without the template (#722)

* Prevent users from enabling events without the template

* Add test for the events update validation
This commit is contained in:
Krzysztof Wolski 2023-07-06 09:02:08 +02:00 committed by GitHub
parent 78670ce712
commit e1980aae90
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 85 additions and 2 deletions

View file

@ -0,0 +1,5 @@
---
"saleor-app-emails-and-messages": patch
---
Added validation for Sendgrid events form. Enabling event without a template is no longer allowed to avoid misconfiguration and undelivered emails.

View file

@ -12,6 +12,7 @@ export const BoxFooter = (props: BoxProps) => {
gap={defaultPadding} gap={defaultPadding}
flexDirection="row" flexDirection="row"
justifyContent="flex-end" justifyContent="flex-end"
alignItems="center"
{...props} {...props}
> >
{props.children} {props.children}

View file

@ -0,0 +1,58 @@
import { expect, describe, it } from "vitest";
import { sendgridUpdateEventArraySchema } from "./sendgrid-config-input-schema";
import { ZodError } from "zod";
describe("sendgridUpdateEventArraySchema", async function () {
it("No errors should be thrown, when active event has specified template", async () => {
sendgridUpdateEventArraySchema.parse({
configurationId: "123",
events: [
{
eventType: "ORDER_CREATED",
active: true,
template: "123",
},
],
});
});
it("No errors should be thrown, when non active event has no template", async () => {
sendgridUpdateEventArraySchema.parse({
configurationId: "123",
events: [
{
eventType: "ORDER_CREATED",
active: false,
template: undefined,
},
],
});
});
it("Error should be thrown, when any of active events has no template", async () => {
await expect(async () =>
sendgridUpdateEventArraySchema.parse({
configurationId: "123",
events: [
{
eventType: "ORDER_CREATED",
active: true,
template: "123",
},
{
eventType: "ORDER_FULFILLED",
active: true,
template: undefined,
},
],
})
).rejects.toThrow(
new ZodError([
{
code: "custom",
message: "All active events must have assigned template.",
path: ["events"],
},
])
);
});
});

View file

@ -89,7 +89,19 @@ export type SendgridUpdateEvent = z.infer<typeof sendgridUpdateEventSchema>;
export const sendgridUpdateEventArraySchema = z.object({ export const sendgridUpdateEventArraySchema = z.object({
configurationId: z.string(), configurationId: z.string(),
events: z.array(sendgridConfigurationEventSchema), events: z
.array(sendgridConfigurationEventSchema)
/*
* Pass the validation if all the events are in one of two states:
* 1. Inactive
* 2. Active and have a template
*/
.refine(
(data) => data.every((event) => event.active === false || (event.active && event.template)),
{
message: "All active events must have assigned template.",
}
),
}); });
export type SendgridUpdateEventArray = z.infer<typeof sendgridUpdateEventArraySchema>; export type SendgridUpdateEventArray = z.infer<typeof sendgridUpdateEventArraySchema>;

View file

@ -34,7 +34,13 @@ export const SendgridEventsSection = ({ configuration }: SendgridEventsSectionPr
messageEventTypesLabels[a.eventType].localeCompare(messageEventTypesLabels[b.eventType]) messageEventTypesLabels[a.eventType].localeCompare(messageEventTypesLabels[b.eventType])
); );
const { control, register, handleSubmit, setError } = useForm<SendgridUpdateEventArray>({ const {
control,
register,
handleSubmit,
setError,
formState: { errors },
} = useForm<SendgridUpdateEventArray>({
defaultValues: { defaultValues: {
configurationId: configuration.id, configurationId: configuration.id,
events: eventsSorted, events: eventsSorted,
@ -132,6 +138,7 @@ export const SendgridEventsSection = ({ configuration }: SendgridEventsSectionPr
</Table.Container> </Table.Container>
</Box> </Box>
<BoxFooter> <BoxFooter>
{errors.events && <Text color={"iconCriticalDefault"}>{errors.events.message}</Text>}
<Button type="submit">Save provider</Button> <Button type="submit">Save provider</Button>
</BoxFooter> </BoxFooter>
</BoxWithBorder> </BoxWithBorder>