feat: enhance cancellation parser to support mixed wording and add tests for hospital cancellations
This commit is contained in:
@@ -2,7 +2,7 @@ const test = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs/promises');
|
||||
const path = require('node:path');
|
||||
const { TelegramImportService } = require('../src/services/telegramImportService');
|
||||
const { TelegramImportService, contentHash } = require('../src/services/telegramImportService');
|
||||
const { CLAIM_DUE_ALERTS_SQL } = require('../src/services/alertSchedulerService');
|
||||
|
||||
// Run against an isolated in-memory PostgreSQL engine, never the working database.
|
||||
@@ -12,6 +12,35 @@ const carrierText = 'Не будут выполняться рейсы:\nПО М
|
||||
const config = { enabled: true, autoPublish: true, apiId: 123, apiHash: 'a'.repeat(32), sessionFile: '/tmp/private/account.session', channel: 'avp2Polotsk', citySlug: 'polotsk', intervalMs: 60_000 };
|
||||
const message = (id = 1166, text = carrierText) => ({ channelId: '1234567', channelUsername: 'avp2Polotsk', messageId: id, publishedAt: '2026-10-02T12:52:00Z', editedAt: null, hasMedia: false, text });
|
||||
|
||||
test('fixed parser reprocesses a stored invalid-date review without a Telegram text edit or duplicate alerts', { skip: !modulePath }, async () => {
|
||||
const { db, pool, service, clock } = await setup();
|
||||
try {
|
||||
clock('2026-10-05T04:20:00Z');
|
||||
await pool.query("UPDATE routes SET route_number='2' WHERE city_id=1");
|
||||
await pool.query("UPDATE stops SET name=CASE id WHEN 1 THEN 'Больница (Ксты)' ELSE 'Больница (Новка)' END WHERE city_id=1");
|
||||
await service.stopAliases.save(1, { alias: 'больница ксты', stop_id: 1 });
|
||||
await service.stopAliases.save(1, { alias: 'больница(новка)', stop_id: 2 });
|
||||
const text = await fs.readFile(path.join(__dirname, 'fixtures/telegram-hospital-cancellation.txt'), 'utf8');
|
||||
const input = { ...message(1400, text), publishedAt: '2026-10-05T04:16:53Z' };
|
||||
const oldParsed = { status: 'review', reasons: ['Некорректная дата отмены.'], groups: [], plans: [] };
|
||||
await pool.query(`INSERT INTO telegram_import_messages
|
||||
(city_id,channel_id,channel_username,message_id,published_at,content_hash,raw_text,status,reasons,parsed)
|
||||
VALUES (1,$1,$2,$3,$4,$5,$6,'review',$7::jsonb,$8::jsonb)`,
|
||||
[input.channelId,input.channelUsername,input.messageId,input.publishedAt,contentHash(input),input.text,JSON.stringify(oldParsed.reasons),JSON.stringify(oldParsed)]);
|
||||
assert.equal((await service.processMessage(input, 1)).status, 'published');
|
||||
const row = (await service.list(1))[0];
|
||||
assert.equal(row.parsed.serviceDate, '2026-10-05');
|
||||
assert.deepEqual(row.reasons, []);
|
||||
const alerts = (await pool.query('SELECT a.* FROM alerts a JOIN telegram_import_alerts t ON t.alert_id=a.id WHERE t.message_id=$1 ORDER BY route_id', [row.id])).rows;
|
||||
assert.equal(alerts.length, 2);
|
||||
assert.match(alerts[0].message, /Больница \(Ксты\) — 07:15, 08:45/);
|
||||
assert.match(alerts[1].message, /Больница \(Новка\) — 08:00, 09:30/);
|
||||
assert.ok(alerts.every(alert => alert.end_time.toISOString() === '2026-10-05T21:00:00.000Z'));
|
||||
assert.equal((await service.processMessage(input, 1)).status, 'unchanged');
|
||||
assert.equal((await pool.query('SELECT count(*)::int AS n FROM telegram_import_alerts WHERE message_id=$1', [row.id])).rows[0].n, 2);
|
||||
} finally { await db.close(); }
|
||||
});
|
||||
|
||||
async function setup() {
|
||||
const { PGlite } = require(modulePath);
|
||||
const db = new PGlite();
|
||||
|
||||
Reference in New Issue
Block a user