| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- import assert from 'node:assert/strict';
- import { test } from 'node:test';
- import {
- buildDashboardSummary,
- buildDeliveryFunnel,
- buildEventTimeline,
- buildDomainRanking,
- buildHourlyHeatmap,
- buildStatusDistribution,
- buildTrendSeries
- } from '../src/frontend/analytics-model.js';
- test('builds dashboard summary from analytics, DNS health, and SMTP state', () => {
- const summary = buildDashboardSummary({
- analytics: {
- summary: {
- total: 20,
- queued: 18,
- failed: 2,
- recipients: 25,
- today: 8,
- successRate: 90,
- verifiedDomains: 1
- }
- },
- domains: [
- domain(true, [
- record('verification', 'ok'),
- record('dkim', 'ok'),
- record('spf', 'ok'),
- record('dmarc', 'ok'),
- record('sender-a', 'ok')
- ]),
- domain(false, [
- record('verification', 'ok'),
- record('dkim', 'warn'),
- record('spf', 'missing')
- ])
- ],
- events: [{ createdAt: '2026-07-08T12:30:00.000Z' }],
- config: { submission: { enabled: true } },
- smtpCredential: { passwordSet: true }
- });
- assert.equal(summary.verifiedDomains, 1);
- assert.equal(summary.today, 8);
- assert.equal(summary.successRate, 90);
- assert.equal(summary.bounceRate, 10);
- assert.equal(summary.complaintRate, 0);
- assert.equal(summary.dnsIssues, 4);
- assert.equal(summary.smtpReady, true);
- assert.equal(summary.lastSentAt, '2026-07-08T12:30:00.000Z');
- });
- test('normalizes chart datasets for trend, status, ranking, and hourly views', () => {
- const analytics = {
- byDay: [
- { day: '2026-07-07', total: 6, queued: 5, failed: 1, recipients: 8 },
- { day: '2026-07-08', total: 9, queued: 9, failed: 0, recipients: 10 }
- ],
- byStatus: [
- { status: 'queued', total: 14 },
- { status: 'failed', total: 1 }
- ],
- byDomain: [
- { domain: 'b.example.com', total: 2, queued: 2, failed: 0, recipients: 2 },
- { domain: 'a.example.com', total: 8, queued: 7, failed: 1, recipients: 12 }
- ],
- hourly: [
- { hour: 0, total: 0, queued: 0, failed: 0 },
- { hour: 9, total: 4, queued: 3, failed: 1 }
- ]
- };
- assert.deepEqual(buildTrendSeries(analytics), [
- { date: '2026-07-07', total: 6, accepted: 5, failed: 1, recipients: 8 },
- { date: '2026-07-08', total: 9, accepted: 9, failed: 0, recipients: 10 }
- ]);
- assert.deepEqual(buildStatusDistribution(analytics), [
- { status: 'queued', label: 'queued', value: 14 },
- { status: 'failed', label: 'failed', value: 1 }
- ]);
- assert.deepEqual(buildDomainRanking(analytics).map((item) => item.domain), ['a.example.com', 'b.example.com']);
- assert.deepEqual(buildHourlyHeatmap(analytics).find((item) => item.hour === '09:00'), {
- hour: '09:00',
- total: 4,
- accepted: 3,
- failed: 1
- });
- });
- test('builds delivery funnel and event timeline models', () => {
- const analytics = {
- deliveryFunnel: [
- { stage: 'submitted', total: 5, rate: 100 },
- { stage: 'accepted', total: 4, rate: 80 },
- { stage: 'delivered', total: 2, rate: 40 },
- { stage: 'pending', total: 1, rate: 20 },
- { stage: 'failed', total: 2, rate: 40 }
- ]
- };
- assert.deepEqual(buildDeliveryFunnel(analytics), [
- { stage: 'submitted', total: 5, rate: 100, tone: 'info' },
- { stage: 'accepted', total: 4, rate: 80, tone: 'info' },
- { stage: 'delivered', total: 2, rate: 40, tone: 'success' },
- { stage: 'pending', total: 1, rate: 20, tone: 'warning' },
- { stage: 'failed', total: 2, rate: 40, tone: 'error' }
- ]);
- const timeline = buildEventTimeline({
- id: 7,
- status: 'sent',
- queueId: 'Q7',
- createdAt: '2026-07-09T11:59:00.000Z',
- deliveredAt: '2026-07-09T12:00:00.000Z',
- deliveryAttempts: [{
- at: '2026-07-09T12:00:00.000Z',
- queueId: 'Q7',
- status: 'sent',
- recipient: 'user@example.com',
- relay: 'mx.example.net',
- response: '250 ok'
- }],
- webhookDeliveries: [{
- id: 11,
- webhookId: 3,
- userId: 1,
- sendEventId: 7,
- eventType: 'sent',
- status: 'success',
- attemptCount: 1,
- createdAt: '2026-07-09T12:00:01.000Z',
- lastAttemptAt: '2026-07-09T12:00:02.000Z',
- responseStatus: 200
- }]
- });
- assert.deepEqual(timeline.map((item) => item.stage), ['submitted', 'accepted', 'delivered', 'webhook']);
- assert.equal(timeline[1].queueId, 'Q7');
- assert.equal(timeline[2].tone, 'success');
- assert.equal(timeline[3].status, 'success');
- });
- function domain(verified, records) {
- return {
- status: {
- verified,
- records
- }
- };
- }
- function record(key, status) {
- return { key, status };
- }
|