gongxiangp2/lib/__tests__/public-traffic-stats.test.ts
2026-07-08 14:35:15 +08:00

148 lines
5.2 KiB
TypeScript

import { mkdtempSync, rmSync, writeFileSync } from 'fs'
import os from 'os'
import path from 'path'
import {
classifyPublicTrafficPurpose,
getPublicTrafficPresetRange,
getPublicTrafficStats,
normalizeTrafficRange,
parsePublicTrafficLogLine,
} from '@/lib/public-traffic-stats'
describe('public traffic stats', () => {
test('parses standard nginx access log response bytes', () => {
const line =
'58.216.227.194 - - [04/Jul/2026:10:35:05 +0800] "POST /api/dingtalk/login HTTP/2.0" 200 349 "https://sc.jiansun.vip/dingtalk-callback" "Mozilla/5.0"'
const entry = parsePublicTrafficLogLine(line, 'sc.jiansun.vip')
expect(entry).toEqual(
expect.objectContaining({
domain: 'sc.jiansun.vip',
remoteAddress: '58.216.227.194',
method: 'POST',
path: '/api/dingtalk/login',
status: 200,
responseBytes: 349,
requestBytes: null,
}),
)
expect(entry?.timestamp.toISOString()).toBe('2026-07-04T02:35:05.000Z')
})
test('parses extended request_length when present', () => {
const line =
'58.216.227.194 - - [04/Jul/2026:10:42:52 +0800] "GET /api/materials/download?id=abc HTTP/1.1" 200 1024 "-" "curl" bytes_sent=1200 request_length=512'
const entry = parsePublicTrafficLogLine(line, 'sc.jiansun.vip')
expect(entry).toEqual(
expect.objectContaining({
method: 'GET',
path: '/api/materials/download',
responseBytes: 1200,
requestBytes: 512,
}),
)
})
test('normalizes default range to whole local days', () => {
const range = normalizeTrafficRange('2026-07-01', '2026-07-04')
expect(range.start.toISOString()).toBe('2026-06-30T16:00:00.000Z')
expect(range.end.toISOString()).toBe('2026-07-04T15:59:59.999Z')
})
test('builds public traffic presets using China business dates', () => {
const now = new Date('2026-07-08T05:00:00.000Z')
const today = getPublicTrafficPresetRange('today', now)
const last7 = getPublicTrafficPresetRange('last7', now)
const last30 = getPublicTrafficPresetRange('last30', now)
expect(today.start.toISOString()).toBe('2026-07-07T16:00:00.000Z')
expect(today.end.toISOString()).toBe('2026-07-08T15:59:59.999Z')
expect(last7.start.toISOString()).toBe('2026-07-01T16:00:00.000Z')
expect(last7.end.toISOString()).toBe('2026-07-08T15:59:59.999Z')
expect(last30.start.toISOString()).toBe('2026-06-08T16:00:00.000Z')
expect(last30.end.toISOString()).toBe('2026-07-08T15:59:59.999Z')
})
test('groups daily traffic by China business date', async () => {
const previousPaths = process.env.PUBLIC_TRAFFIC_LOG_PATHS
const tempDir = mkdtempSync(path.join(os.tmpdir(), 'public-traffic-'))
const logPath = path.join(tempDir, 'sc.jiansun.vip.access.log')
try {
writeFileSync(
logPath,
'58.216.227.194 - - [04/Jul/2026:01:35:05 +0800] "GET /assets/a.png HTTP/2.0" 200 2048 "-" "Mozilla/5.0"\n',
)
process.env.PUBLIC_TRAFFIC_LOG_PATHS = logPath
const stats = await getPublicTrafficStats(normalizeTrafficRange('2026-07-04', '2026-07-04'))
expect(stats.byDay).toEqual([
expect.objectContaining({
date: '2026-07-04',
responseBytes: 2048,
totalRequests: 1,
}),
])
expect(stats.byPurpose).toEqual([
expect.objectContaining({
key: 'static-asset',
label: '图片直链访问',
category: '资源文件',
}),
])
} finally {
if (previousPaths === undefined) {
delete process.env.PUBLIC_TRAFFIC_LOG_PATHS
} else {
process.env.PUBLIC_TRAFFIC_LOG_PATHS = previousPaths
}
rmSync(tempDir, { recursive: true, force: true })
}
})
test('classifies technical paths into human-readable business purposes', () => {
expect(classifyPublicTrafficPurpose('sc.jiansun.vip', '/api/materials/download', 'GET')).toEqual(
expect.objectContaining({
key: 'material-download',
label: '素材下载/打包下载',
}),
)
expect(classifyPublicTrafficPurpose('cp.jiansun.vip', '/api/intake/non-integrated', 'GET')).toEqual(
expect.objectContaining({
key: 'product-intake-non-integrated',
label: '产品设计平台未集成素材列表',
}),
)
expect(
classifyPublicTrafficPurpose(
's3.jiansun.vip',
'/gongxiangpan/uploads/direct/d685fa51-d8eb-42ea-b471-4a91269a7a90/1783137399966-p0j9wv.jpg',
'GET',
),
).toEqual(
expect.objectContaining({
key: 'direct-upload-asset',
label: '图片直链访问',
category: '直传资源',
detail: '直传上传目录下的图片、视频、压缩包等资源直链汇总,具体文件请看“流量最高路径”。',
}),
)
expect(classifyPublicTrafficPurpose('s3.jiansun.vip', '/gongxiangpan/uploads/1775120618610-g75pxl.png', 'GET')).toEqual(
expect.objectContaining({
key: 'legacy-upload-asset',
label: '图片直链访问',
category: '历史上传资源',
detail: '历史上传目录下的图片、视频、压缩包等资源直链汇总,具体文件请看“流量最高路径”。',
}),
)
})
})