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((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((resolve) => server.close(() => resolve())) } })