105 lines
3.8 KiB
TypeScript
105 lines
3.8 KiB
TypeScript
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
import { getMailjetProviderStatus, updateMailjetSettings } from "./TransactionalEmailSettings.server";
|
|
import { getAppConfiguration, updateAppConfiguration } from "~/utils/db/appConfiguration.db.server";
|
|
|
|
vi.mock("~/utils/db/appConfiguration.db.server", () => ({
|
|
getAppConfiguration: vi.fn(),
|
|
updateAppConfiguration: vi.fn(),
|
|
}));
|
|
|
|
const request = new Request("https://admin.example.com/settings/transactional-emails");
|
|
const getAppConfigurationMock = vi.mocked(getAppConfiguration);
|
|
const updateAppConfigurationMock = vi.mocked(updateAppConfiguration);
|
|
|
|
function clearMailjetEnv() {
|
|
delete process.env.MAILJET_API_KEY;
|
|
delete process.env.MAILJET_SECRET_KEY;
|
|
delete process.env.MAILJET_FROM_EMAIL;
|
|
}
|
|
|
|
describe("TransactionalEmailSettings.server", () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
clearMailjetEnv();
|
|
|
|
getAppConfigurationMock.mockResolvedValue({
|
|
email: {
|
|
provider: "mailjet",
|
|
fromEmail: "",
|
|
fromName: "Support",
|
|
supportEmail: "support@example.com",
|
|
},
|
|
} as Awaited<ReturnType<typeof getAppConfiguration>>);
|
|
});
|
|
|
|
afterEach(() => {
|
|
clearMailjetEnv();
|
|
});
|
|
|
|
it("uses Mailjet environment values as a redacted fallback status", async () => {
|
|
process.env.MAILJET_API_KEY = "env-public-key";
|
|
process.env.MAILJET_SECRET_KEY = "env-secret-key";
|
|
process.env.MAILJET_FROM_EMAIL = "sender@example.com";
|
|
|
|
const status = await getMailjetProviderStatus({ request });
|
|
|
|
expect(status).toEqual({
|
|
id: "mailjet",
|
|
name: "Mailjet",
|
|
configured: true,
|
|
source: { apiKey: "environment", secretKey: "environment", fromEmail: "environment" },
|
|
missing: [],
|
|
});
|
|
expect(JSON.stringify(status)).not.toContain("env-secret-key");
|
|
});
|
|
|
|
it("reports the missing Mailjet keys by name when partially configured", async () => {
|
|
process.env.MAILJET_API_KEY = "env-public-key";
|
|
|
|
const status = await getMailjetProviderStatus({ request });
|
|
|
|
expect(status.configured).toBe(false);
|
|
expect(status.missing).toEqual(["MAILJET_SECRET_KEY", "MAILJET_FROM_EMAIL"]);
|
|
});
|
|
|
|
it("rejects non-Mailjet provider updates", async () => {
|
|
const form = createSettingsForm({ emailProvider: "smtp", apiKey: "new-secret-key" });
|
|
|
|
const result = await updateMailjetSettings(form);
|
|
|
|
expect(result).toEqual({ success: false, error: "Only Mailjet is supported for transactional email." });
|
|
expect(updateAppConfigurationMock).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("rejects submitted API keys because queued delivery is environment configured", async () => {
|
|
const form = createSettingsForm({ apiKey: "new-secret-key" });
|
|
|
|
const result = await updateMailjetSettings(form);
|
|
|
|
expect(result).toEqual({ success: false, error: "Mailjet API keys are configured through environment variables only." });
|
|
expect(updateAppConfigurationMock).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("updates support metadata only when the submitted API key is blank", async () => {
|
|
const form = createSettingsForm({ apiKey: " " });
|
|
|
|
const result = await updateMailjetSettings(form);
|
|
|
|
expect(result).toEqual({ success: true });
|
|
expect(updateAppConfigurationMock).toHaveBeenCalledWith({
|
|
emailProvider: "mailjet",
|
|
emailSupportEmail: "support@example.com",
|
|
});
|
|
});
|
|
});
|
|
|
|
function createSettingsForm(overrides: Partial<Record<string, string>> = {}) {
|
|
const form = new FormData();
|
|
form.set("emailProvider", overrides.emailProvider ?? "mailjet");
|
|
form.set("emailFromEmail", overrides.emailFromEmail ?? "sender@example.com");
|
|
form.set("emailFromName", overrides.emailFromName ?? "Support");
|
|
form.set("emailSupportEmail", overrides.emailSupportEmail ?? "support@example.com");
|
|
form.set("apiKey", overrides.apiKey ?? "new-secret-key");
|
|
return form;
|
|
}
|