chore: 현재 작업 중간 커밋

This commit is contained in:
chungyeong
2026-03-05 11:00:45 +09:00
parent 02970df6af
commit be88b4fcec
43 changed files with 6837 additions and 466 deletions

View File

@@ -45,6 +45,7 @@ test("emits threshold alerts when crossing and improving below threshold", async
rawInput: "인천-마드리드 추적",
searchParams: {
segments: [{ from: "ICN", to: "MAD" }],
departureDateWindow: { from: "2026-06-01" },
},
alertRules: {
targetPrice: 900,
@@ -79,6 +80,7 @@ test("emits price change alerts when price changes", async () => {
rawInput: "인천-마드리드 추적",
searchParams: {
segments: [{ from: "ICN", to: "MAD" }],
departureDateWindow: { from: "2026-06-01" },
},
alertRules: {
notifyOnPriceChange: true,
@@ -114,6 +116,7 @@ test("keeps crawl snapshot even when notifier fails", async () => {
rawInput: "인천-마드리드 추적",
searchParams: {
segments: [{ from: "ICN", to: "MAD" }],
departureDateWindow: { from: "2026-06-01" },
},
alertRules: {
targetPrice: 980000,
@@ -132,3 +135,53 @@ test("keeps crawl snapshot even when notifier fails", async () => {
assert.equal(watch.lastSnapshot.bestPrice, 950000);
assert.equal(watch.lastError.phase, "notify");
});
test("pollAll skips when another poll cycle is already in progress", async () => {
let release = null;
let started = null;
const startedPromise = new Promise((resolve) => {
started = resolve;
});
const watcher = new PriceWatcher({
crawler: {
async getQuotes() {
started();
await new Promise((resolve) => {
release = resolve;
});
return [
{
provider: "slow-crawler",
price: 999000,
currency: "KRW",
},
];
},
},
notifier: {
async notify() {},
},
logger: createSilentLogger(),
});
watcher.addWatch({
rawInput: "인천-마드리드 추적",
searchParams: { segments: [{ from: "ICN", to: "MAD" }], departureDateWindow: { from: "2026-06-01" } },
alertRules: {
notifyOnPriceChange: true,
targetPrice: null,
},
});
const firstCycle = watcher.pollAll();
await startedPromise;
const skipped = await watcher.pollAll();
assert.equal(skipped.length, 1);
assert.equal(skipped[0].skipped.reason, "poll_cycle_in_progress");
release();
await firstCycle;
});