Files
order_site/apps/backend/src/services/session/session.test.js
T

209 lines
6.0 KiB
JavaScript

import test from 'node:test'
import assert from 'node:assert/strict'
import {
normalizeLoginType,
parseViewportSpec,
} from './session-browser-config.js'
import { normalizeTencentCookieMap } from './session-cookie-map.js'
import {
buildArtifactsPayload,
buildRedeemPayload,
} from './session-payload.js'
import { ensureReviewScreenshot } from './session-review.js'
import { resolveInitialQrSessionState } from './session-state.js'
import {
REDEEM_SUCCESS_AUTO_CLOSE_MS,
resolveTencentSessionExpiresAt,
} from './session.js'
test('resolveTencentSessionExpiresAt uses normal ttl when no auto-close is armed', () => {
const nowMs = Date.UTC(2026, 3, 14, 9, 30, 0)
assert.equal(
resolveTencentSessionExpiresAt({ autoCloseAt: 0 }, nowMs),
nowMs + (30 * 60 * 1000),
)
})
test('resolveTencentSessionExpiresAt keeps redeemed auto-close deadline once armed', () => {
const nowMs = Date.UTC(2026, 3, 14, 9, 30, 0)
const autoCloseAt = nowMs + REDEEM_SUCCESS_AUTO_CLOSE_MS
assert.equal(
resolveTencentSessionExpiresAt({ autoCloseAt }, nowMs + 60_000),
autoCloseAt,
)
})
test('normalizeLoginType collapses aliases and falls back to qq', () => {
assert.equal(normalizeLoginType(' qc '), 'qq')
assert.equal(normalizeLoginType('wechat'), 'wx')
assert.equal(normalizeLoginType('unknown'), 'qq')
assert.equal(normalizeLoginType(''), 'qq')
})
test('parseViewportSpec accepts valid viewport strings and rejects invalid values', () => {
assert.deepEqual(parseViewportSpec('1920x1080'), { width: 1920, height: 1080 })
assert.deepEqual(parseViewportSpec('1920x1080x24'), { width: 1920, height: 1080 })
assert.equal(parseViewportSpec('799x600'), null)
assert.equal(parseViewportSpec('broken'), null)
})
test('buildRedeemPayload strips internal paths unless explicitly requested', () => {
const redeem = {
code: 'ABC123',
area: '微信区',
proofMode: 'basic',
attempts: [
{
attempt: 1,
redeem: { success: false, message: '验证码错误' },
},
],
final: {
attempt: 2,
redeem: { success: true, message: '兑换成功' },
},
finishedAt: '2026-04-14T09:40:00.000Z',
screenshotPath: '/tmp/redeem.png',
htmlPath: '/tmp/redeem.html',
resultPath: '/tmp/redeem.json',
}
assert.deepEqual(buildRedeemPayload(redeem), {
code: 'ABC123',
area: '微信区',
proofMode: 'basic',
attempts: [
{
attempt: 1,
redeem: { success: false, message: '验证码错误' },
},
],
final: {
attempt: 2,
redeem: { success: true, message: '兑换成功' },
},
finishedAt: '2026-04-14T09:40:00.000Z',
})
assert.deepEqual(buildRedeemPayload(redeem, { includeInternalPaths: true }), {
code: 'ABC123',
area: '微信区',
proofMode: 'basic',
attempts: [
{
attempt: 1,
redeem: { success: false, message: '验证码错误' },
},
],
final: {
attempt: 2,
redeem: { success: true, message: '兑换成功' },
},
finishedAt: '2026-04-14T09:40:00.000Z',
screenshotPath: '/tmp/redeem.png',
htmlPath: '/tmp/redeem.html',
resultPath: '/tmp/redeem.json',
})
})
test('buildArtifactsPayload only exposes internal artifact paths in debug mode', () => {
const session = {
sessionDir: '/tmp/session',
qrImagePath: '/tmp/session/qq-qr.png',
qrImageBase64: 'base64data',
lastReview: {
screenshotPath: '/tmp/session/review.png',
},
lastRedeem: {
screenshotPath: '/tmp/session/redeem.png',
htmlPath: '/tmp/session/redeem.html',
resultPath: '/tmp/session/redeem.json',
},
}
assert.deepEqual(buildArtifactsPayload(session), {
hasQrImage: true,
hasReviewScreenshot: true,
hasScreenshot: true,
})
assert.deepEqual(buildArtifactsPayload(session, { includeInternalPaths: true }), {
hasQrImage: true,
hasReviewScreenshot: true,
hasScreenshot: true,
sessionDir: '/tmp/session',
qrImagePath: '/tmp/session/qq-qr.png',
screenshotPath: '/tmp/session/redeem.png',
htmlPath: '/tmp/session/redeem.html',
resultPath: '/tmp/session/redeem.json',
reviewScreenshotPath: '/tmp/session/review.png',
})
})
test('normalizeTencentCookieMap fills required defaults and derived proxy cookie', () => {
assert.deepEqual(
normalizeTencentCookieMap([
{ name: 'openid', value: 'openid-1' },
{ name: 'access_token', value: 'token-1' },
{ name: '', value: 'ignored' },
]),
{
openid: 'openid-1',
access_token: 'token-1',
acctype: 'qc',
appid: '101491592',
iegams_milo_proxylogin_qc: '101491592_$$_openid-1_$$_token-1',
},
)
})
test('resolveInitialQrSessionState creates waiting-scan snapshot with ttl', () => {
assert.deepEqual(
resolveInitialQrSessionState('wx', {
updatedAt: '2026-04-14T09:30:00.000Z',
nowMs: 1_700_000_000_000,
sessionTtlMs: 1_800_000,
}),
{
status: 'waiting_scan',
notice: '请使用微信扫码登录',
updatedAt: '2026-04-14T09:30:00.000Z',
expiresAt: 1_700_001_800_000,
},
)
})
test('ensureReviewScreenshot writes screenshot state and skips unchanged signature', async () => {
const screenshotCalls = []
const session = {
sessionId: 'txbs-demo',
loginType: 'qq',
sessionDir: '/tmp/session-demo',
page: {
async screenshot(options) {
screenshotCalls.push(options)
},
},
lastReview: null,
}
const activityInfo = {
role: {
roleId: '1001',
roleName: '测试角色',
},
}
assert.equal(await ensureReviewScreenshot(session, activityInfo), true)
assert.equal(screenshotCalls.length, 1)
assert.equal(session.lastReview.roleId, '1001')
assert.equal(session.lastReview.roleName, '测试角色')
assert.equal(session.lastReview.signature, 'qq|1001|测试角色')
assert.match(session.lastReview.screenshotPath, /role-review\.png$/)
assert.equal(await ensureReviewScreenshot(session, activityInfo), false)
assert.equal(screenshotCalls.length, 1)
})