Files
order_site/apps/backend/src/routes/pdd-extension.test.ts
T
yml2213 9fb27b0ad2 feat(pdd): 拼多多订单支持 out_sku_sn 匹配与浏览器插件加密保活
- 拼多多进单 Cookie 失效即时拦截与告警修复(支持 43001 会话过期等错误识别)
- 拼多多订单映射优先使用 out_sku_sn(外部商家编码)作为商品规格与工单匹配核心字段
- 新增 Chrome/Edge 浏览器扩展 (Manifest V3),支持端到端 RSA-OAEP + AES-256-GCM 信封加密自动保活
- 后台店铺管理新增插件配对面板、专属密钥管理与一键导入配置 JSON
2026-09-14 12:24:48 +08:00

152 lines
4.7 KiB
TypeScript

import test from 'node:test'
import assert from 'node:assert/strict'
import express from 'express'
import http from 'node:http'
import pddExtensionRouter from './pdd-extension.js'
import {
getOrCreatePddRsaKeyPair,
testEncryptPddPayload,
} from '../services/platforms/pdd/pdd-crypto-service.js'
import {
generatePddStoreSyncToken,
getPddStoreById,
savePddSourcesConfig,
getPddSourcesConfig,
} from '../services/platforms/pdd/pdd-source-config-service.js'
import { PddClient } from '../services/platforms/pdd/pdd-client.js'
import { query } from '../db/client.js'
function makeTestApp() {
const app = express()
app.use(express.json())
app.use('/api/v1/pdd/extension', pddExtensionRouter)
return app
}
test('pdd-extension router: GET /public-key and POST /sync-cookie full flow', async (t) => {
let dbAvailable = false
try {
const check = await query('SELECT 1').catch(() => null)
dbAvailable = Boolean(check)
} catch {
dbAvailable = false
}
if (!dbAvailable) {
t.skip('Skipping integration test: PostgreSQL database is not reachable outside container')
return
}
const app = makeTestApp()
const server = http.createServer(app)
await new Promise<void>((resolve) => server.listen(0, resolve))
const addr = server.address()
const port = typeof addr === 'object' && addr ? addr.port : 0
const baseUrl = `http://127.0.0.1:${port}/api/v1/pdd/extension`
// Prepare a test store in config
const originalConfig = getPddSourcesConfig()
const testShopId = 'test_shop_router_01'
const mockConfig = {
...originalConfig,
stores: [
{
shopId: testShopId,
shopName: '测试路由店铺',
cookie: 'old_cookie=123;',
cookieValid: false,
enabled: true,
},
],
}
await savePddSourcesConfig(mockConfig)
// Generate sync token
const token = await generatePddStoreSyncToken(testShopId)
// Mock PddClient.testCookie
const originalTestCookie = PddClient.testCookie
PddClient.testCookie = async () => ({
valid: true,
totalOrders: 88,
})
try {
// 1. Test GET /public-key
const pkResp = await fetch(`${baseUrl}/public-key`)
assert.equal(pkResp.status, 200)
const pkData = await pkResp.json()
assert.equal(pkData.code, 0)
assert.ok(pkData.data.publicKeySpki)
assert.equal(pkData.data.algorithm, 'RSA-OAEP-256')
// 2. Test POST /sync-cookie with missing token
const kp = getOrCreatePddRsaKeyPair()
const payload = {
shopId: testShopId,
cookie: 'new_fresh_cookie=xyz;',
userAgent: 'Mozilla/5.0 Extension Test',
timestamp: Date.now(),
nonce: 'nonce_test_' + Math.random().toString(36).slice(2),
}
const envelope = testEncryptPddPayload(payload, kp.publicKeyPem)
const noTokenResp = await fetch(`${baseUrl}/sync-cookie`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ envelope }),
})
assert.equal(noTokenResp.status, 401)
// 3. Test POST /sync-cookie with wrong token
const wrongTokenResp = await fetch(`${baseUrl}/sync-cookie`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Shop-Token': 'wrong-token-abc',
},
body: JSON.stringify({
envelope: testEncryptPddPayload(
{ ...payload, nonce: 'nonce_wrong_' + Math.random().toString(36).slice(2) },
kp.publicKeyPem,
),
}),
})
assert.equal(wrongTokenResp.status, 403)
// 4. Test POST /sync-cookie with valid token and fresh nonce
const freshPayload = {
...payload,
nonce: 'nonce_fresh_' + Math.random().toString(36).slice(2),
}
const freshEnvelope = testEncryptPddPayload(freshPayload, kp.publicKeyPem)
const validResp = await fetch(`${baseUrl}/sync-cookie`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Shop-Token': token,
},
body: JSON.stringify({ envelope: freshEnvelope }),
})
assert.equal(validResp.status, 200)
const validData = await validResp.json()
assert.equal(validData.code, 0)
assert.equal(validData.data.shopId, testShopId)
assert.equal(validData.data.valid, true)
assert.equal(validData.data.totalOrders, 88)
// Verify store was updated in memory/config
const updatedStore = getPddStoreById(testShopId)
assert.ok(updatedStore)
assert.equal(updatedStore.cookie, 'new_fresh_cookie=xyz;')
assert.equal(updatedStore.cookieValid, true)
assert.ok(updatedStore.lastExtensionSyncAt)
} finally {
PddClient.testCookie = originalTestCookie
await savePddSourcesConfig(originalConfig)
await new Promise<void>((resolve) => server.close(() => resolve()))
}
})