import test from 'node:test'; import assert from 'node:assert/strict'; import { JOURNEY_FUNNEL_STAGES } from '../src/routes/admin.js'; import { getProduct } from '../src/products.js'; test('C 端漏斗在封卷后继续追踪一生作品与付费意向', () => { const ids = JOURNEY_FUNNEL_STAGES.map(([id]) => id); const events = JOURNEY_FUNNEL_STAGES.map(([, , event]) => event); assert.equal(new Set(ids).size, ids.length, '漏斗阶段 id 不应重复'); assert.equal(new Set(events).size, events.length, '每个阶段应由独立事件计数'); assert.ok(ids.indexOf('artifact') > ids.indexOf('seal'), '作品激活必须发生在封卷之后'); assert.ok(ids.includes('portrait'), '官职照是独立收费候选,必须可单独衡量'); assert.ok(ids.includes('creation'), '二创激活必须可衡量'); assert.ok(ids.includes('invite'), '共走增长环必须可衡量'); assert.ok(ids.indexOf('interest') < ids.indexOf('checkout'), '付费意向应早于结账'); }); test('天下典藏主商品在服务端有同名 SKU,且默认不会误开真实收款', () => { const pass = getProduct('tianxia_pass'); assert.ok(pass, '前端 PASS_OFFER 对应的服务端 SKU 必须存在'); assert.equal(pass.priceCents, 6800); assert.equal(pass.entitlement, 'tianxia_pass'); if (process.env.TIANXIA_PASS_LIVE !== '1') assert.equal(pass.available, false); });