161 lines
5.3 KiB
JavaScript
161 lines
5.3 KiB
JavaScript
"use strict";
|
|
|
|
const test = require("node:test");
|
|
const assert = require("node:assert/strict");
|
|
const fs = require("fs");
|
|
const os = require("os");
|
|
const path = require("path");
|
|
|
|
const { buildMimeMessage, sendBackupReportMail, sendTestMail } = require("../lib/mailNotify");
|
|
|
|
function fakeLogger() {
|
|
const infos = [];
|
|
const warnings = [];
|
|
const errors = [];
|
|
return {
|
|
infos,
|
|
warnings,
|
|
errors,
|
|
info: (msg) => infos.push(msg),
|
|
warn: (msg) => warnings.push(msg),
|
|
error: (msg) => errors.push(msg),
|
|
};
|
|
}
|
|
|
|
test("buildMimeMessage: 添付ファイル無しでも本文がbase64で埋め込まれる", () => {
|
|
const raw = buildMimeMessage({
|
|
from: "a@example.com",
|
|
to: "b@example.com",
|
|
subject: "件名",
|
|
bodyText: "本文テキスト",
|
|
});
|
|
|
|
assert.match(raw, /^From: a@example\.com/);
|
|
assert.match(raw, /Subject: =\?UTF-8\?B\?/);
|
|
assert.match(raw, /Content-Type: multipart\/mixed; boundary="/);
|
|
assert.doesNotMatch(raw, /Content-Disposition: attachment/);
|
|
});
|
|
|
|
test("buildMimeMessage: 添付ファイルがあればbase64化して埋め込む", () => {
|
|
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "mail-notify-test-"));
|
|
const attachmentPath = path.join(dir, "backup-202607.log");
|
|
fs.writeFileSync(attachmentPath, "ログ本文");
|
|
|
|
const raw = buildMimeMessage({
|
|
from: "a@example.com",
|
|
to: "b@example.com",
|
|
subject: "件名",
|
|
bodyText: "本文",
|
|
attachmentPath,
|
|
});
|
|
|
|
assert.match(raw, /Content-Disposition: attachment; filename="backup-202607\.log"/);
|
|
assert.match(raw, new RegExp(Buffer.from("ログ本文", "utf8").toString("base64")));
|
|
});
|
|
|
|
test("sendBackupReportMail: MAIL_FROM/MAIL_TO未設定ならスキップする", async () => {
|
|
delete process.env.MAIL_FROM;
|
|
delete process.env.MAIL_TO;
|
|
const logger = fakeLogger();
|
|
let sendMailCalls = 0;
|
|
|
|
await sendBackupReportMail(
|
|
{ success: true, hostname: "host", database: "db", elapsedSec: "1.0", logFilePath: "/dev/null" },
|
|
{ logger, sendMail: async () => (sendMailCalls += 1) }
|
|
);
|
|
|
|
assert.equal(sendMailCalls, 0);
|
|
assert.ok(logger.warnings.some((m) => m.includes("スキップ")));
|
|
});
|
|
|
|
test("sendBackupReportMail: 成功時は成功ラベル入りの件名で送信する", async () => {
|
|
process.env.MAIL_FROM = "from@example.com";
|
|
process.env.MAIL_TO = "to@example.com";
|
|
const logger = fakeLogger();
|
|
const calls = [];
|
|
|
|
await sendBackupReportMail(
|
|
{ success: true, hostname: "nextoffice2", database: "Implem.Pleasanter", elapsedSec: "12.3", logFilePath: "/dev/null" },
|
|
{ logger, sendMail: async (opts) => calls.push(opts) }
|
|
);
|
|
|
|
assert.equal(calls.length, 1);
|
|
assert.match(calls[0].subject, /バックアップ成功/);
|
|
assert.match(calls[0].bodyText, /結果: 成功/);
|
|
assert.ok(logger.infos.some((m) => m.includes("メール通知送信成功")));
|
|
|
|
delete process.env.MAIL_FROM;
|
|
delete process.env.MAIL_TO;
|
|
});
|
|
|
|
test("sendBackupReportMail: 失敗時は失敗ラベルとエラー内容を含める", async () => {
|
|
process.env.MAIL_FROM = "from@example.com";
|
|
process.env.MAIL_TO = "to@example.com";
|
|
const logger = fakeLogger();
|
|
const calls = [];
|
|
|
|
await sendBackupReportMail(
|
|
{
|
|
success: false,
|
|
hostname: "nextoffice2",
|
|
database: "Implem.Pleasanter",
|
|
elapsedSec: "5.0",
|
|
errorMessage: "401 UNAUTHORIZED",
|
|
logFilePath: "/dev/null",
|
|
},
|
|
{ logger, sendMail: async (opts) => calls.push(opts) }
|
|
);
|
|
|
|
assert.match(calls[0].subject, /バックアップ失敗/);
|
|
assert.match(calls[0].bodyText, /エラー内容: 401 UNAUTHORIZED/);
|
|
|
|
delete process.env.MAIL_FROM;
|
|
delete process.env.MAIL_TO;
|
|
});
|
|
|
|
test("sendBackupReportMail: 送信自体が失敗してもERRORログに記録し例外は投げない", async () => {
|
|
process.env.MAIL_FROM = "from@example.com";
|
|
process.env.MAIL_TO = "to@example.com";
|
|
const logger = fakeLogger();
|
|
|
|
await sendBackupReportMail(
|
|
{ success: true, hostname: "h", database: "d", elapsedSec: "1.0", logFilePath: "/dev/null" },
|
|
{
|
|
logger,
|
|
sendMail: async () => {
|
|
throw new Error("sendmail異常終了 (code=1)");
|
|
},
|
|
}
|
|
);
|
|
|
|
assert.ok(logger.errors.some((m) => m.includes("メール通知送信失敗")));
|
|
|
|
delete process.env.MAIL_FROM;
|
|
delete process.env.MAIL_TO;
|
|
});
|
|
|
|
test("sendTestMail: MAIL_FROM/MAIL_TO未設定なら例外を投げる", async () => {
|
|
delete process.env.MAIL_FROM;
|
|
delete process.env.MAIL_TO;
|
|
const logger = fakeLogger();
|
|
|
|
await assert.rejects(() => sendTestMail({ logger, sendMail: async () => {} }), /MAIL_FROM\/MAIL_TO/);
|
|
});
|
|
|
|
test("sendTestMail: 設定済みならsendMailを1回呼ぶ", async () => {
|
|
process.env.MAIL_FROM = "from@example.com";
|
|
process.env.MAIL_TO = "to@example.com";
|
|
const logger = fakeLogger();
|
|
const calls = [];
|
|
|
|
await sendTestMail({ logger, sendMail: async (opts) => calls.push(opts) });
|
|
|
|
assert.equal(calls.length, 1);
|
|
assert.equal(calls[0].from, "from@example.com");
|
|
assert.equal(calls[0].to, "to@example.com");
|
|
assert.match(calls[0].subject, /テスト送信/);
|
|
|
|
delete process.env.MAIL_FROM;
|
|
delete process.env.MAIL_TO;
|
|
});
|