feat: add Open Graph image generation and SEO metadata

- Introduced `PageSeo` component for managing page metadata for social sharing.
- Created Open Graph image templates using SVG and static fonts for better visual representation.
- Implemented service alert management with functions to check active alerts and format route numbers.
- Added utility functions for generating and watching alert validity.
- Developed a script to generate Open Graph images dynamically based on page content.
- Included tests for service alert functionalities to ensure correctness and reliability.
This commit is contained in:
2026-10-05 13:02:06 +03:00
parent 6460846134
commit 142ec97959
35 changed files with 8226 additions and 4690 deletions

View File

@@ -102,6 +102,7 @@ test('loads active alerts for the requested city without exposing notification f
id: 2,
alert_type: 'detour',
route_number: ' 21тк ',
route_id: 19,
route_name: ' Route ',
start_time: '2026-10-01T12:00:00Z',
created_at: '2026-09-30T12:00:00Z',
@@ -118,9 +119,14 @@ test('loads active alerts for the requested city without exposing notification f
alerts: [
{
id: 2,
cityId: 2,
type: 'detour',
title: 'Notice',
message: 'Public message',
routeNumbers: ['21тк'],
routeIds: [19],
isCityWide: false,
routeId: 19,
routeNumber: '21тк',
routeName: 'Route',
startTime: '2026-10-01T12:00:00.000Z',
@@ -129,9 +135,14 @@ test('loads active alerts for the requested city without exposing notification f
},
{
id: 1,
cityId: 2,
type: 'info',
title: 'Notice',
message: 'Public message',
routeNumbers: [],
routeIds: [],
isCityWide: true,
routeId: null,
routeNumber: null,
routeName: null,
startTime: '2026-09-25T12:00:00.000Z',
@@ -170,7 +181,9 @@ test('expires alerts within a cached response and keeps different cities separat
const initial = await Promise.all([client.get(query), client.get(query)]);
assert.equal(initial[0].alerts.length, 1);
assert.equal(calls, 1);
clock += 11000;
clock += 9999;
assert.equal((await client.get(query)).alerts.length, 1);
clock += 1;
assert.equal((await client.get(query)).alerts.length, 0);
assert.equal(calls, 1);
assert.equal(
@@ -268,7 +281,7 @@ test('shows schedule times, removes historical delay, sorts and limits departure
route_number: '1',
name: 'Centre',
arrivals: [
{ scheduledTime: '9:05:00', minutesUntil: 7, delay: 2 },
{ scheduledTime: '9:05:00', minutesUntil: 7, delay: 7 },
{ scheduledTime: '09:15', minutesUntil: 15 },
{ scheduledTime: '09:25', minutesUntil: 25 },
],
@@ -292,12 +305,12 @@ test('shows schedule times, removes historical delay, sorts and limits departure
cityId: 1,
stopId: 5,
});
assert.equal(data.departures.length, 6);
assert.equal(data.departures.length, 4);
assert.deepEqual(
data.departures.map((item) => item.minutesUntil),
[1, 2, 3, 4, 5, 15]
[0, 1, 2, 3]
);
assert.equal(data.departures[4].scheduledTime, '09:05');
assert.equal(data.departures[0].scheduledTime, '09:05');
assert.equal(data.updatedAt, '1970-01-01T00:00:00.000Z');
assert.equal(data.partial, false);
});