import test from 'node:test' import assert from 'node:assert/strict' import { loadModule } from './load.mjs' // Website-Statistik (webklar.com): reine Anzeige-Helfer const v = await loadModule('src/lib/eigeneAnalyseView.js') test('Zahlen: Tausenderpunkt, Prozent, fehlender Wert', () => { assert.equal(v.formatInt(1234567), '1.234.567') assert.equal(v.formatInt(0), '0') assert.equal(v.formatInt(null), '–') assert.equal(v.formatInt(undefined), '–') assert.equal(v.formatPercent(0.63), '63 %') assert.equal(v.formatPercent(0.625), '63 %') assert.equal(v.formatPercent(0), '0 %') assert.equal(v.formatPercent(1), '100 %') assert.equal(v.formatPercent(null), '–') }) test('Dauer: Sekunden, Minuten mit zweistelligen Sekunden, null', () => { assert.equal(v.formatDuration(42), '42 s') assert.equal(v.formatDuration(0), '0 s') assert.equal(v.formatDuration(65), '1 Min. 05 s') assert.equal(v.formatDuration(60), '1 Min. 00 s') assert.equal(v.formatDuration(59.6), '1 Min. 00 s', 'gerundet, nie "60 s"') assert.equal(v.formatDuration(754.2), '12 Min. 34 s') assert.equal(v.formatDuration(null), '–') assert.equal(v.formatDuration(undefined), '–') }) test('Aenderung in Prozent: plus, minus (U+2212), null, neu, kein Vergleich', () => { assert.deepEqual(v.changeVsPrevious(112, 100), { text: '+12 %', dir: 'up' }) assert.deepEqual(v.changeVsPrevious(95, 100), { text: '−5 %', dir: 'down' }) assert.deepEqual(v.changeVsPrevious(100, 100), { text: '0 %', dir: 'flat' }) assert.deepEqual(v.changeVsPrevious(1001, 1000), { text: '0 %', dir: 'flat' }, 'unter 0,5 % gilt als unveraendert') assert.deepEqual(v.changeVsPrevious(5, 0), { text: 'neu', dir: 'up' }) assert.deepEqual(v.changeVsPrevious(0, 0), { text: '0 %', dir: 'flat' }) assert.deepEqual(v.changeVsPrevious(0, 40), { text: '−100 %', dir: 'down' }) assert.deepEqual(v.changeVsPrevious(13000, 1000), { text: '+1.200 %', dir: 'up' }) assert.equal(v.changeVsPrevious(null, 10), null) assert.equal(v.changeVsPrevious(10, null), null) assert.equal(v.changeVsPrevious(10, undefined), null) }) test('Aenderung der Zustimmungsquote in Prozentpunkten', () => { assert.deepEqual(v.changeInPoints(0.63, 0.59), { text: '+4 Pkt.', dir: 'up' }) assert.deepEqual(v.changeInPoints(0.5, 0.52), { text: '−2 Pkt.', dir: 'down' }) assert.deepEqual(v.changeInPoints(0.5, 0.5), { text: '0 Pkt.', dir: 'flat' }) assert.equal(v.changeInPoints(0.5, null), null) }) test('kpiChange: ohne vollstaendige Vorperiode kein Vergleich', () => { const stats = { totals: { pv: 120, visitors: 40, contacts: 3, consentRate: 0.63, avgSec: 65 }, previous: { complete: true, totals: { pv: 100, visitors: 50, contacts: 0, consentRate: 0.59, avgSec: null } }, } assert.equal(v.kpiChange(stats, 'pv').text, '+20 %') assert.equal(v.kpiChange(stats, 'visitors').text, '−20 %') assert.equal(v.kpiChange(stats, 'contacts').text, 'neu') assert.equal(v.kpiChange(stats, 'consentRate').text, '+4 Pkt.') assert.equal(v.kpiChange(stats, 'avgSec'), null, 'Vorperiode ohne Dauer') assert.equal(v.kpiChange({ ...stats, previous: { ...stats.previous, complete: false } }, 'pv'), null) assert.equal(v.kpiChange({ totals: stats.totals }, 'pv'), null) assert.equal(v.kpiChange(null, 'pv'), null) }) test('Beschriftungen: Geraete, Kontakte, Herkunft, Seiten', () => { assert.equal(v.deviceLabel('m'), 'Handy') assert.equal(v.deviceLabel('t'), 'Tablet') assert.equal(v.deviceLabel('d'), 'Computer') assert.equal(v.deviceLabel(''), 'unbekannt') assert.equal(v.deviceLabel('x'), 'x') assert.equal(v.contactLabel('tel'), 'Telefon') assert.equal(v.contactLabel('mail'), 'E-Mail') assert.equal(v.contactLabel('wa'), 'WhatsApp') assert.equal(v.contactLabel('out'), 'Link zu anderer Website') assert.equal(v.contactLabel('zzz'), 'zzz') assert.equal(v.refLabel(''), 'direkt / unbekannt') assert.equal(v.refLabel('google.com'), 'google.com') assert.equal(v.pageLabel('/'), '/ (Startseite)') assert.equal(v.pageLabel('/preise'), '/preise') }) test('Laender: deutsche Namen, unbekannt, ungueltiger Code bleibt Code', () => { assert.equal(v.countryLabel('DE'), 'Deutschland') assert.equal(v.countryLabel('AT'), 'Österreich') assert.equal(v.countryLabel('CH'), 'Schweiz') assert.equal(v.countryLabel(''), 'unbekannt') assert.equal(v.countryLabel('T1'), 'T1', 'kein gueltiger Regionscode') }) test('Datum: Tag, Kurzform, Zeitraum (gleiches Jahr, Jahreswechsel, ein Tag)', () => { assert.equal(v.formatDay('2026-10-17'), '17.10.2026') assert.equal(v.formatDay(''), '–') assert.equal(v.formatDay('17.10.2026'), '–') assert.equal(v.formatDayShort('2026-10-07'), '07.10.') assert.equal(v.periodText('2026-09-10', '2026-10-16'), '10.09.–16.10.2026') assert.equal(v.periodText('2025-12-30', '2026-01-05'), '30.12.2025–05.01.2026') assert.equal(v.periodText('2026-10-16', '2026-10-16'), '16.10.2026') assert.equal(v.periodText('', '2026-10-16'), '') }) test('Verlauf: jeder Tag einmal, fehlende Tage 0, Tage vor der Messung null, ueber Monatsgrenze', () => { const stats = { from: '2026-09-29', to: '2026-10-03', firstDay: '2026-09-30', series: [ { day: '2026-09-30', pv: 4, visitors: 2 }, { day: '2026-10-02', pv: 9, visitors: 5 }, ], } const c = v.chartDays(stats) assert.deepEqual(c.days, ['2026-09-29', '2026-09-30', '2026-10-01', '2026-10-02', '2026-10-03']) assert.deepEqual(c.pv, [null, 4, 0, 9, 0]) assert.deepEqual(c.visitors, [null, 2, 0, 5, 0]) assert.deepEqual(v.chartDays({ from: '2026-10-03', to: '2026-10-01', series: [] }).days, []) assert.deepEqual(v.chartDays({ from: '2026-10-01', to: '2026-10-02', firstDay: '', series: [] }).pv, [0, 0]) }) test('Rangliste: sortiert, Balken relativ zum groessten, Anteil nur auf Wunsch, Nullen raus', () => { const items = [{ key: 'm', count: 30 }, { key: 'd', count: 60 }, { key: 't', count: 10 }, { key: '', count: 0 }] const rows = v.rankRows(items, v.deviceLabel, { percent: true }) assert.deepEqual(rows.map((r) => [r.key, r.label, r.count, r.bar, r.percent]), [ ['d', 'Computer', 60, 1, '60'], ['m', 'Handy', 30, 0.5, '30'], ['t', 'Tablet', 10, 10 / 60, '10'], ]) assert.equal(v.rankRows([{ key: 'a', count: 1000 }, { key: 'b', count: 1 }], String, { percent: true })[1].percent, '<1', 'unter einem halben Prozent') assert.equal(v.rankRows(items, v.deviceLabel)[0].percent, null) assert.deepEqual(v.rankRows(null, String), []) }) test('Texte: Heute-Zeile mit Einzahl, Leerzustand, Hinweis auf spaeten Messbeginn', () => { assert.equal( v.todayText({ pv: 12, visitors: 3, contacts: 1 }), 'Heute bis jetzt: 12 Aufrufe · 3 Besucher · 1 Kontakt-Klick' ) assert.equal( v.todayText({ pv: 1, visitors: 1, contacts: 0 }), 'Heute bis jetzt: 1 Aufruf · 1 Besucher · 0 Kontakt-Klicks' ) assert.equal(v.todayText({ pv: 1500, visitors: 0, contacts: 2 }), 'Heute bis jetzt: 1.500 Aufrufe · 0 Besucher · 2 Kontakt-Klicks') assert.equal(v.hasNoData({ totals: { pv: 0 }, today: { pv: 0 } }), true) assert.equal(v.hasNoData({ totals: { pv: 0 }, today: { pv: 2 } }), false) assert.equal(v.hasNoData({ totals: { pv: 5 }, today: { pv: 0 } }), false) assert.equal(v.sinceHint({ from: '2026-09-17', firstDay: '2026-10-05' }), 'Messung seit 05.10.2026') assert.equal(v.sinceHint({ from: '2026-09-17', firstDay: '2026-09-17' }), '') assert.equal(v.sinceHint({ from: '2026-09-17', firstDay: '' }), '') })