import test from 'node:test' import assert from 'node:assert/strict' import { createAnalyticsDurationTracker } from '../lib/analytics-duration.js' import { ANALYTICS_MAX_REALTIME_DURATION_SECONDS, clampAnalyticsDurationSeconds, clampAnalyticsRealtimeDurationSeconds } from '../lib/analytics-shared.js' test('접속 신호가 이어지면 30분을 넘긴 시간도 누적한다', () => { const sample = createAnalyticsDurationTracker(0) for (let now = 20000; now <= 7200000; now += 20000) sample(now) assert.deepEqual(sample(7200000), { durationSeconds: 7200, restarted: false }) }) test('30분 이상 실행이 중단되면 복귀 시 새 방문으로 시작한다', () => { const sample = createAnalyticsDurationTracker(0) assert.equal(sample(20000).durationSeconds, 20) assert.equal(sample(40000).durationSeconds, 40) const resumedAt = 40000 + 3 * 86400000 assert.deepEqual(sample(resumedAt), { durationSeconds: 0, restarted: true }) assert.deepEqual(sample(resumedAt + 20000), { durationSeconds: 20, restarted: false }) assert.equal(sample(resumedAt + 110000).durationSeconds, 20) assert.equal(sample(resumedAt + 130000).durationSeconds, 40) assert.deepEqual(sample(resumedAt + 1930000), { durationSeconds: 0, restarted: true }) }) test('90초 이상 30분 미만 중단은 시간만 제외하고 기존 방문을 유지한다', () => { const sample = createAnalyticsDurationTracker(0) assert.equal(sample(20000).durationSeconds, 20) assert.deepEqual(sample(110000), { durationSeconds: 20, restarted: false }) assert.deepEqual(sample(1909000), { durationSeconds: 20, restarted: false }) assert.deepEqual(sample(1929000), { durationSeconds: 40, restarted: false }) }) test('짧은 지연과 소수 초를 보존하고 시계 역행·잘못된 시각은 누적하지 않는다', () => { const sample = createAnalyticsDurationTracker(1000) assert.equal(sample(1500).durationSeconds, 0) assert.equal(sample(2000).durationSeconds, 1) assert.equal(sample(82000).durationSeconds, 81) assert.equal(sample(81000).durationSeconds, 81) assert.equal(sample(NaN).durationSeconds, 81) assert.equal(sample(101000).durationSeconds, 101) assert.equal(createAnalyticsDurationTracker(101000)(101000).durationSeconds, 0) }) test('실시간 접속 시간은 정수 범위까지 허용하고 평균 체류 통계 상한은 유지한다', () => { assert.equal(clampAnalyticsRealtimeDurationSeconds(7200.9), 7200) assert.equal(clampAnalyticsDurationSeconds(7200), 1800) assert.equal(clampAnalyticsRealtimeDurationSeconds(Number.MAX_SAFE_INTEGER), ANALYTICS_MAX_REALTIME_DURATION_SECONDS) for (const value of [-1, NaN, Infinity]) assert.equal(clampAnalyticsRealtimeDurationSeconds(value), 0) })