chore: 현재 작업 중간 커밋
This commit is contained in:
133
test/dashboardRuntime.test.js
Normal file
133
test/dashboardRuntime.test.js
Normal file
@@ -0,0 +1,133 @@
|
||||
"use strict";
|
||||
|
||||
const test = require("node:test");
|
||||
const assert = require("node:assert/strict");
|
||||
const { createDashboardRuntime } = require("../src/dashboardRuntime");
|
||||
|
||||
function createStore({ controls }) {
|
||||
const events = [];
|
||||
const watches = [
|
||||
{
|
||||
id: "watch-1",
|
||||
rawInput: "인천->도쿄",
|
||||
searchParams: { segments: [{ from: "ICN", to: "NRT" }], departureDateWindow: { from: "2026-06-01" } },
|
||||
alertRules: {
|
||||
targetPrice: null,
|
||||
notifyOnPriceChange: true,
|
||||
notifyOnFirstResult: true,
|
||||
},
|
||||
pollingEnabled: true,
|
||||
alertsEnabled: true,
|
||||
createdAt: "2026-02-19T00:00:00.000Z",
|
||||
updatedAt: "2026-02-19T00:00:00.000Z",
|
||||
lastSnapshot: null,
|
||||
lastError: null,
|
||||
},
|
||||
];
|
||||
|
||||
return {
|
||||
events,
|
||||
async init() {},
|
||||
async close() {},
|
||||
async listWatches() {
|
||||
return watches;
|
||||
},
|
||||
async getWatch() {
|
||||
return null;
|
||||
},
|
||||
async saveWatch(watch) {
|
||||
return watch;
|
||||
},
|
||||
async deleteWatch() {
|
||||
return true;
|
||||
},
|
||||
async savePollResult() {},
|
||||
async saveEvent(event) {
|
||||
events.push(event);
|
||||
return event;
|
||||
},
|
||||
async listEvents() {
|
||||
return events;
|
||||
},
|
||||
async getGlobalControls() {
|
||||
return controls;
|
||||
},
|
||||
async setGlobalControls(patch = {}) {
|
||||
controls = { ...controls, ...patch };
|
||||
return controls;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
test("runtime stores failed notification state when notifier throws", async () => {
|
||||
const store = createStore({
|
||||
controls: { crawlingEnabled: true, alertsEnabled: true },
|
||||
});
|
||||
const crawler = {
|
||||
async getQuotes() {
|
||||
return [{ provider: "mock", price: 120000, currency: "KRW" }];
|
||||
},
|
||||
};
|
||||
const notifier = {
|
||||
async notify() {
|
||||
throw new Error("network down");
|
||||
},
|
||||
};
|
||||
|
||||
const runtime = await createDashboardRuntime({
|
||||
store,
|
||||
crawler,
|
||||
notifier,
|
||||
logger: { error: () => {} },
|
||||
pollIntervalSec: 3600,
|
||||
});
|
||||
|
||||
try {
|
||||
assert.equal(store.events.length, 1);
|
||||
const payload = store.events[0].payload;
|
||||
assert.equal(payload.notificationState, "failed");
|
||||
assert.equal(payload.notificationSent, false);
|
||||
assert.equal(payload.notificationSuppressed, undefined);
|
||||
assert.equal(payload.notificationError.phase, "notify");
|
||||
assert.match(payload.notificationError.message, /Notifier failed/);
|
||||
} finally {
|
||||
await runtime.close();
|
||||
}
|
||||
});
|
||||
|
||||
test("runtime stores suppressed notification state when alerts are disabled", async () => {
|
||||
let notifyCalls = 0;
|
||||
const store = createStore({
|
||||
controls: { crawlingEnabled: true, alertsEnabled: false },
|
||||
});
|
||||
const crawler = {
|
||||
async getQuotes() {
|
||||
return [{ provider: "mock", price: 120000, currency: "KRW" }];
|
||||
},
|
||||
};
|
||||
const notifier = {
|
||||
async notify() {
|
||||
notifyCalls += 1;
|
||||
},
|
||||
};
|
||||
|
||||
const runtime = await createDashboardRuntime({
|
||||
store,
|
||||
crawler,
|
||||
notifier,
|
||||
logger: { error: () => {} },
|
||||
pollIntervalSec: 3600,
|
||||
});
|
||||
|
||||
try {
|
||||
assert.equal(store.events.length, 1);
|
||||
const payload = store.events[0].payload;
|
||||
assert.equal(payload.notificationState, "suppressed");
|
||||
assert.equal(payload.notificationSent, false);
|
||||
assert.equal(payload.notificationSuppressed, true);
|
||||
assert.equal(payload.notificationError, null);
|
||||
assert.equal(notifyCalls, 0);
|
||||
} finally {
|
||||
await runtime.close();
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user