Files
pedwfrontend/tests/phase22/email-provider-contract.test.cjs

114 lines
3.2 KiB
JavaScript

const assert = require("node:assert/strict");
const fs = require("node:fs");
const path = require("node:path");
const test = require("node:test");
const vm = require("node:vm");
const root = path.resolve(__dirname, "../..");
const source = fs.readFileSync(
path.join(root, "lib/auth/email-provider.js"),
"utf8"
);
const EmailProvider = vm.runInNewContext(
source.replace("export default EmailProvider;", "") + "\nEmailProvider;",
{}
);
const OriginalEmailProvider = require("next-auth/providers/email").default;
const customSender = async () => {};
const options = {
maxAge: 2 * 60 * 60,
sendVerificationRequest: customSender
};
const normalize = (provider) => {
const { options: userOptions, ...defaults } = provider;
return {
...defaults,
...userOptions
};
};
test("local provider preserves NextAuth email provider defaults", () => {
const original = OriginalEmailProvider(options);
const replacement = EmailProvider(options);
for (const property of ["id", "type", "name", "server", "from", "maxAge"]) {
assert.deepEqual(
JSON.parse(JSON.stringify(replacement[property])),
JSON.parse(JSON.stringify(original[property])),
`Mismatch in ${property}`
);
}
});
test("local provider preserves the user options contract", () => {
const provider = EmailProvider(options);
assert.equal(provider.options.maxAge, 7200);
assert.equal(provider.options.sendVerificationRequest, customSender);
});
test("normalized provider retains two-hour token expiry", () => {
const original = normalize(OriginalEmailProvider(options));
const replacement = normalize(EmailProvider(options));
assert.equal(original.maxAge, 7200);
assert.equal(replacement.maxAge, original.maxAge);
});
test("normalized provider uses the custom verification sender", () => {
const provider = normalize(EmailProvider(options));
assert.equal(provider.sendVerificationRequest, customSender);
});
test("provider retains NextAuth email identity", () => {
const provider = normalize(EmailProvider(options));
assert.equal(provider.id, "email");
assert.equal(provider.type, "email");
assert.equal(provider.name, "Email");
});
test("default sender fails explicitly without PEDW override", async () => {
const provider = EmailProvider();
await assert.rejects(
provider.sendVerificationRequest(),
/requires a custom GOV\.UK Notify verification sender/
);
});
test("local provider does not import Nodemailer", () => {
assert.doesNotMatch(
source,
/(?:require\s*\(|from\s+|import\s*\()\s*["']nodemailer/
);
});
test("authentication handler imports the local provider", () => {
const authSource = fs.readFileSync(
path.join(root, "pages/api/auth/[...nextauth].js"),
"utf8"
);
assert.match(
authSource,
/import EmailProvider from ["']\.\.\/\.\.\/\.\.\/lib\/auth\/email-provider["']/
);
assert.doesNotMatch(authSource, /from ["']next-auth\/providers\/email["']/);
assert.match(authSource, /EmailProvider\s*\(\s*\{/);
assert.match(authSource, /async sendVerificationRequest\s*\(/);
assert.match(authSource, /notifyClient\.sendEmail\s*\(/);
});