Files
HiveGrid-Wireframes/hivegrid-cloud/apps/web/app/modules/emails/services/MailjetEmailService.test.ts
T

145 lines
3.8 KiB
TypeScript

import { afterEach, describe, expect, test, vi } from "vitest";
import { buildRetryJobOptions, buildTransactionalMailJob, queueNames, type TypedQueue } from "@toolctrl/queue";
import { sendEmailMailjet } from "./MailjetEmailService";
const runtimeQueue = {
add: vi.fn(async () => ({ id: "job_from_env" })),
close: vi.fn(async () => undefined),
};
vi.mock("@toolctrl/queue/runtime", () => ({
createQueue: vi.fn(() => runtimeQueue),
}));
afterEach(() => {
vi.clearAllMocks();
delete process.env.BULLMQ_REDIS_URL;
delete process.env.REDIS_URL;
});
function createQueueMock() {
return {
add: vi.fn(async () => ({ id: "job_123" })),
} as unknown as TypedQueue<typeof queueNames.email> & {
add: ReturnType<typeof vi.fn>;
};
}
describe("sendEmailMailjet", () => {
test("enqueues transactional email through the default queue provider", async () => {
const queue = createQueueMock();
const result = await sendEmailMailjet(
{
data: {
to: "user@example.com",
subject: "Welcome",
body: "<p>Hello</p>",
alias: "registration-welcome",
data: { firstName: "Ada" },
},
},
{
queue,
}
);
expect(result).toEqual({
provider: "queue",
status: "queued",
messageId: "job_123",
warnings: {
queueName: queueNames.email,
jobName: "send-transactional-email",
},
});
const descriptor = buildTransactionalMailJob({
to: ["user@example.com"],
subject: "Welcome",
html: "<p>Hello</p>",
templateData: { firstName: "Ada" },
metadata: { alias: "registration-welcome" },
});
expect(queue.add).toHaveBeenCalledWith(
"send-transactional-email",
descriptor.payload,
buildRetryJobOptions(descriptor)
);
});
test("fails closed when Redis is missing without falling back to synchronous mail", async () => {
await expect(sendEmailMailjet(
{
data: {
to: "user@example.com",
subject: "Welcome",
body: "<p>Hello</p>",
alias: "registration-welcome",
data: { firstName: "Ada" },
},
},
{
env: {},
}
)).rejects.toMatchObject({
provider: "queue",
message: "Set BULLMQ_REDIS_URL or REDIS_URL to enqueue transactional email jobs.",
responseBody: {
code: "missing_redis_connection",
message: "Set BULLMQ_REDIS_URL or REDIS_URL to enqueue transactional email jobs.",
requiredEnv: ["BULLMQ_REDIS_URL", "REDIS_URL"],
},
});
});
test("uses process Redis configuration by default", async () => {
process.env.BULLMQ_REDIS_URL = "redis://localhost:6379/2";
const result = await sendEmailMailjet({
data: {
to: "user@example.com",
subject: "Welcome",
body: "<p>Hello</p>",
alias: "registration-welcome",
data: { firstName: "Ada" },
},
});
expect(result).toEqual({
provider: "queue",
status: "queued",
messageId: "job_from_env",
warnings: {
queueName: queueNames.email,
jobName: "send-transactional-email",
},
});
expect(runtimeQueue.add).toHaveBeenCalledOnce();
expect(runtimeQueue.close).toHaveBeenCalledOnce();
});
test("propagates enqueue failures to the caller", async () => {
const queue = createQueueMock();
const error = new Error("queue add failed");
queue.add.mockRejectedValueOnce(error);
await expect(
sendEmailMailjet(
{
data: {
to: "user@example.com",
subject: "Welcome",
body: "<p>Hello</p>",
alias: "registration-welcome",
data: { firstName: "Ada" },
},
},
{
queue,
}
)
).rejects.toBe(error);
});
});