Improve activity journal readability
Build and Deploy Gateway / build-and-push (push) Successful in 25s
Build and Deploy Gateway / deploy (push) Successful in 15s

This commit is contained in:
Dmitriy Petrov
2026-08-25 15:52:42 +03:00
parent 64462d3639
commit f451c65b2f
8 changed files with 217 additions and 23 deletions
+77
View File
@@ -0,0 +1,77 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import {
compactActivityJournalEvents,
refreshStreakCopy,
} from '../../.test-dist/src/web/features/activity-journal/activityJournalModel.js';
function event(id, occurredAt, type = 'subscription.refreshed', data = {}) {
return {
id,
occurredAt,
type,
severity: 'info',
source: type.startsWith('subscription.') ? 'subscription' : 'connection',
dedupeKey: null,
data: type === 'subscription.refreshed'
? { profileLabel: 'Дом', serverCount: 8, added: 0, removed: 0, ...data }
: data,
};
}
test('adjacent unchanged refreshes become one observed success streak', () => {
const items = compactActivityJournalEvents([
event('newest', '2026-08-25T15:00:00.000Z', 'subscription.refreshed', { profileLabel: 'Дом' }),
event('middle', '2026-08-25T13:30:00.000Z', 'subscription.refreshed', { profileLabel: 'Работа' }),
event('oldest', '2026-08-25T12:00:00.000Z', 'subscription.refreshed', { profileLabel: 'Дом' }),
]);
assert.equal(items.length, 1);
assert.deepEqual(items[0].refreshStreak, {
count: 3,
firstOccurredAt: '2026-08-25T12:00:00.000Z',
profileLabels: ['Дом', 'Работа'],
});
assert.deepEqual(refreshStreakCopy(items[0]), [
'Подписки обновлялись без ошибок',
'3 ч всё хорошо · 3 обновления · подписок: 2',
]);
});
test('another event and a changed server list break refresh streaks', () => {
const items = compactActivityJournalEvents([
event('routine-new', '2026-08-25T15:00:00.000Z'),
event('started', '2026-08-25T14:50:00.000Z', 'connection.started', { profileLabel: 'Дом', serverLabel: 'Амстердам' }),
event('changed', '2026-08-25T14:45:00.000Z', 'subscription.refreshed', { added: 1 }),
event('routine-old', '2026-08-25T14:30:00.000Z'),
]);
assert.equal(items.length, 4);
assert.ok(items.every(({ refreshStreak }) => refreshStreak === null));
});
test('a local calendar-day boundary breaks an otherwise adjacent streak', () => {
const newer = new Date(2026, 7, 25, 0, 5).toISOString();
const older = new Date(2026, 7, 24, 23, 55).toISOString();
const items = compactActivityJournalEvents([
event('new-day', newer),
event('old-day', older),
]);
assert.equal(items.length, 2);
assert.ok(items.every(({ refreshStreak }) => refreshStreak === null));
});
test('one-profile streak names the profile and keeps the latest event identity', () => {
const items = compactActivityJournalEvents([
event('newest', '2026-08-25T15:15:00.000Z'),
event('oldest', '2026-08-25T15:00:00.000Z'),
]);
assert.equal(items[0].event.id, 'newest');
assert.deepEqual(refreshStreakCopy(items[0]), [
'Подписки обновлялись без ошибок',
'15 мин всё хорошо · 2 обновления · Дом',
]);
});