initial commit

This commit is contained in:
chungyeong
2026-02-19 17:28:58 +09:00
commit 02970df6af
34 changed files with 5673 additions and 0 deletions

97
test/notifier.test.js Normal file
View File

@@ -0,0 +1,97 @@
"use strict";
const test = require("node:test");
const assert = require("node:assert/strict");
const { TelegramNotifier, createNotifier } = require("../src/notifier");
const sampleEvent = {
watchId: "watch-1",
rawInput: "인천->마드리드",
eventType: "target_price",
threshold: 1300000,
previousBestPrice: 1320000,
currentBestPrice: 1295000,
currency: "KRW",
bestOffer: {
provider: "mock-ota-b",
},
observedAt: "2026-02-19T00:00:00.000Z",
};
test("createNotifier selects telegram channel and sends formatted message", async () => {
const requests = [];
const notifier = createNotifier({
channel: "telegram",
telegramBotToken: "123:abc",
telegramChatId: "999",
fetch: async (url, init) => {
requests.push({ url, init });
return {
ok: true,
status: 200,
async text() {
return JSON.stringify({ ok: true });
},
};
},
});
await notifier.notify(sampleEvent);
assert.equal(requests.length, 1);
assert.equal(requests[0].url, "https://api.telegram.org/bot123:abc/sendMessage");
const body = JSON.parse(requests[0].init.body);
assert.equal(body.chat_id, "999");
assert.equal(body.disable_web_page_preview, true);
assert.equal(typeof body.text, "string");
assert.match(body.text, /Current best: 1,295,000 KRW/);
assert.match(body.text, /Target threshold: 1,300,000 KRW/);
});
test("createNotifier supports webhook channel", async () => {
const requests = [];
const notifier = createNotifier({
channel: "webhook",
webhookUrl: "https://example.com/hook",
fetch: async (url, init) => {
requests.push({ url, init });
return {
ok: true,
status: 200,
async text() {
return "";
},
};
},
});
await notifier.notify(sampleEvent);
assert.equal(requests.length, 1);
assert.equal(requests[0].url, "https://example.com/hook");
assert.deepEqual(JSON.parse(requests[0].init.body), sampleEvent);
});
test("createNotifier rejects unsupported channel", () => {
assert.throws(() => createNotifier({ channel: "email" }), /Unsupported NOTIFY_CHANNEL/);
});
test("telegram notifier surfaces API errors", async () => {
const notifier = new TelegramNotifier({
botToken: "token",
chatId: "chat",
fetch: async () => ({
ok: false,
status: 400,
async text() {
return JSON.stringify({ description: "Bad Request: chat not found" });
},
}),
});
await assert.rejects(
async () => notifier.notify(sampleEvent),
/Telegram notification failed \(400\): Bad Request: chat not found/
);
});