173 lines
5.2 KiB
TypeScript
173 lines
5.2 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import { createHash } from 'node:crypto';
|
|
import test from 'node:test';
|
|
import { Hono } from 'hono';
|
|
import app from './index.js';
|
|
import {
|
|
registerElectricMonthlyRoute,
|
|
registerElectricOverviewRoute,
|
|
type ElectricDependencies,
|
|
} from './electric.js';
|
|
import {
|
|
registerHydrogenDailyRoute,
|
|
type HydrogenDailyDependencies,
|
|
} from './hydrogen-daily.js';
|
|
import {
|
|
registerHydrogenOverviewRoute,
|
|
type HydrogenOverviewDependencies,
|
|
} from './hydrogen-overview.js';
|
|
|
|
interface QueryCall {
|
|
sql: string;
|
|
params: unknown;
|
|
}
|
|
|
|
interface CacheCall {
|
|
key: string;
|
|
force: boolean | undefined;
|
|
}
|
|
|
|
function createQueryMock(resultSets: unknown[][], calls: QueryCall[]) {
|
|
return async (sql: string, params?: unknown) => {
|
|
calls.push({ sql, params });
|
|
return [resultSets.shift() ?? [], []];
|
|
};
|
|
}
|
|
|
|
function createCachedMock(calls: CacheCall[]) {
|
|
return async <T>(
|
|
key: string,
|
|
loader: () => Promise<T>,
|
|
opts: { force?: boolean } = {},
|
|
): Promise<T> => {
|
|
calls.push({ key, force: opts.force });
|
|
return loader();
|
|
};
|
|
}
|
|
|
|
function sqlHash(sql: string): string {
|
|
return createHash('sha256').update(sql).digest('hex').slice(0, 12);
|
|
}
|
|
|
|
test('能源路由继续按原顺序注册四个 GET 接口', () => {
|
|
assert.deepEqual(
|
|
app.routes.filter(route => route.method === 'GET').map(route => route.path),
|
|
[
|
|
'/hydrogen/overview',
|
|
'/hydrogen/daily',
|
|
'/electric/overview',
|
|
'/electric/monthly',
|
|
],
|
|
);
|
|
});
|
|
|
|
test('四个处理器保持缓存和参数契约,加氢站点使用新主数据表', async () => {
|
|
const hydrogenCalls: QueryCall[] = [];
|
|
const electricCalls: QueryCall[] = [];
|
|
const cacheCalls: CacheCall[] = [];
|
|
const cached = createCachedMock(cacheCalls);
|
|
const hydrogenQuery = createQueryMock([
|
|
[{ y: 2025 }],
|
|
[{}],
|
|
[],
|
|
[],
|
|
[],
|
|
[],
|
|
[],
|
|
[
|
|
{ d: '2025-01-02', stationId: 7, stationName: '测试站', kg: 10, pricePerKg: 35 },
|
|
],
|
|
], hydrogenCalls);
|
|
const electricQuery = createQueryMock([
|
|
[{ totalKwh: 20, totalFee: 30, monthKwh: 15, monthFee: 25, todayKwh: 10, todayFee: 12 }],
|
|
[],
|
|
[{ date: '2025-01-02', kwh: 10, fee: 12 }],
|
|
[{ kwh: 5 }],
|
|
[{ date: '2025-01-02', kwh: 10, fee: 12 }],
|
|
], electricCalls);
|
|
|
|
const hydrogenOverviewApp = new Hono();
|
|
registerHydrogenOverviewRoute(hydrogenOverviewApp, {
|
|
hydrogenPool: { query: hydrogenQuery },
|
|
cached,
|
|
} as unknown as HydrogenOverviewDependencies);
|
|
const overviewResponse = await hydrogenOverviewApp.request(
|
|
'/hydrogen/overview?year=2025&force=1',
|
|
);
|
|
assert.equal(overviewResponse.status, 200);
|
|
|
|
const hydrogenDailyApp = new Hono();
|
|
registerHydrogenDailyRoute(hydrogenDailyApp, {
|
|
hydrogenPool: { query: hydrogenQuery },
|
|
cached,
|
|
} as unknown as HydrogenDailyDependencies);
|
|
const dailyResponse = await hydrogenDailyApp.request(
|
|
'/hydrogen/daily?startDate=2025-01-01&endDate=2025-01-02&customer=external&force=1',
|
|
);
|
|
assert.equal(dailyResponse.status, 200);
|
|
assert.deepEqual(await dailyResponse.json(), [
|
|
{ date: '2025-01-02', totalKg: 10, chainPct: 0, customerType: 'external',
|
|
stations: [{ name: '测试站', pricePerKg: 35, kg: 10, chainPct: 0 }] },
|
|
{ date: '2025-01-01', totalKg: 0, chainPct: 0, customerType: 'external', stations: [] },
|
|
]);
|
|
|
|
const electricApp = new Hono();
|
|
const electricDependencies = {
|
|
pool: { query: electricQuery },
|
|
cached,
|
|
} as unknown as ElectricDependencies;
|
|
registerElectricOverviewRoute(electricApp, electricDependencies);
|
|
registerElectricMonthlyRoute(electricApp, electricDependencies);
|
|
const electricOverviewResponse = await electricApp.request('/electric/overview?force=1');
|
|
assert.equal(electricOverviewResponse.status, 200);
|
|
const electricMonthlyResponse = await electricApp.request(
|
|
'/electric/monthly?startDate=2025-01-01&endDate=2025-01-02&customer=external&force=1',
|
|
);
|
|
assert.equal(electricMonthlyResponse.status, 200);
|
|
|
|
assert.deepEqual(cacheCalls, [
|
|
{ key: 'hydrogen/overview?year=2025', force: true },
|
|
{ key: 'hydrogen/daily?start=2025-01-01&end=2025-01-02&customer=external', force: true },
|
|
{ key: 'electric/overview', force: true },
|
|
{ key: 'electric/monthly?customer=external&start=2025-01-01&end=2025-01-02', force: true },
|
|
]);
|
|
|
|
// 保留查询契约指纹;日明细已更新为佛山羚牛站未关联车辆的外部订单筛选。
|
|
assert.deepEqual(
|
|
[...hydrogenCalls, ...electricCalls].map(call => sqlHash(call.sql)),
|
|
[
|
|
'95f6d99b61c9',
|
|
'63a63c5f78bb',
|
|
'9cf6719a39c3',
|
|
'089d8a10d666',
|
|
'256ac8309d5a',
|
|
'dac9e86fc527',
|
|
'a71da8f05765',
|
|
'd1620280f520',
|
|
'226fd8f950a1',
|
|
'6e4031b10926',
|
|
'4fc77463294c',
|
|
'1886d54939d8',
|
|
'09fc714ec4b2',
|
|
],
|
|
);
|
|
|
|
assert.deepEqual(hydrogenCalls.map(call => call.params), [
|
|
['2024-01-01'],
|
|
[2025, 2025, 2025, 2025, 2025, 2025, 2025, 0, 0, 0, 0, 0, 0, 0, 0, '2024-01-01'],
|
|
['2024-01-01', 2025],
|
|
['2024-01-01', 2025],
|
|
['2024-01-01', 2025],
|
|
['2024-01-01', 2025],
|
|
['2024-01-01', 2025],
|
|
['2025-01-01', '2025-01-02'],
|
|
]);
|
|
assert.deepEqual(electricCalls.map(call => call.params), [
|
|
undefined,
|
|
undefined,
|
|
undefined,
|
|
undefined,
|
|
['2025-01-01', '2025-01-02'],
|
|
]);
|
|
});
|