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

View File

@@ -0,0 +1,105 @@
"use strict";
const test = require("node:test");
const assert = require("node:assert/strict");
const { PriceWatcher } = require("../src/priceWatcher");
function createSilentLogger() {
return {
log() {},
error() {},
};
}
test("global crawling toggle skips polling", async () => {
let crawlerCalls = 0;
const watcher = new PriceWatcher({
crawler: {
async getQuotes() {
crawlerCalls += 1;
return [{ provider: "x", price: 1000, currency: "KRW" }];
},
},
notifier: {
async notify() {},
},
logger: createSilentLogger(),
});
const watchId = watcher.addWatch({
rawInput: "테스트",
searchParams: { segments: [{ from: "ICN", to: "MAD" }] },
alertRules: { targetPrice: 900, notifyOnPriceChange: true },
});
watcher.setGlobalControls({ crawlingEnabled: false });
const result = await watcher.pollWatch(watchId);
assert.equal(crawlerCalls, 0);
assert.equal(result.skipped.reason, "global_crawling_disabled");
});
test("watch-level polling toggle skips polling", async () => {
let crawlerCalls = 0;
const watcher = new PriceWatcher({
crawler: {
async getQuotes() {
crawlerCalls += 1;
return [{ provider: "x", price: 1000, currency: "KRW" }];
},
},
notifier: {
async notify() {},
},
logger: createSilentLogger(),
});
const watchId = watcher.addWatch({
rawInput: "테스트",
searchParams: { segments: [{ from: "ICN", to: "MAD" }] },
alertRules: { targetPrice: null, notifyOnPriceChange: true },
pollingEnabled: false,
});
const result = await watcher.pollWatch(watchId);
assert.equal(crawlerCalls, 0);
assert.equal(result.skipped.reason, "watch_polling_disabled");
});
test("alerts can be suppressed while still computing alert events", async () => {
const notifications = [];
let call = 0;
const watcher = new PriceWatcher({
crawler: {
async getQuotes() {
call += 1;
if (call === 1) {
return [{ provider: "x", price: 1000, currency: "KRW" }];
}
return [{ provider: "x", price: 900, currency: "KRW" }];
},
},
notifier: {
async notify(event) {
notifications.push(event);
},
},
logger: createSilentLogger(),
});
const watchId = watcher.addWatch({
rawInput: "테스트",
searchParams: { segments: [{ from: "ICN", to: "MAD" }] },
alertRules: { targetPrice: 950, notifyOnPriceChange: true },
alertsEnabled: false,
});
await watcher.pollWatch(watchId);
const second = await watcher.pollWatch(watchId);
assert.equal(notifications.length, 0);
assert.equal(second.alert.eventType, "target_price");
assert.equal(second.alert.notificationSuppressed, true);
});