test: cover ticket demo data contract
This commit is contained in:
@@ -15,35 +15,64 @@ import {
|
||||
} from './model.mjs'
|
||||
|
||||
test('provides coherent default visitor ticket data', async () => {
|
||||
const {
|
||||
AVAILABLE_DATES,
|
||||
GROUPS,
|
||||
INITIAL_ORDERS,
|
||||
INITIAL_TRAVELERS,
|
||||
INSURANCE,
|
||||
PLACEHOLDER_IMAGE,
|
||||
PRODUCTS,
|
||||
REFUND_REASONS,
|
||||
} = await import('./data.js')
|
||||
const data = await import('./data.js')
|
||||
const { AVAILABLE_DATES, GROUPS, INITIAL_TRAVELERS, INSURANCE, PLACEHOLDER_IMAGE, PRODUCTS, REFUND_REASONS, SCENIC_SPOT } = data
|
||||
const productsBeforeOrders = structuredClone(PRODUCTS)
|
||||
const travelersBeforeOrders = structuredClone(INITIAL_TRAVELERS)
|
||||
const { INITIAL_ORDERS } = data
|
||||
|
||||
assert.equal(PLACEHOLDER_IMAGE, 'https://one-feel-bucket.oss-cn-guangzhou.aliyuncs.com/oneFeel/2082673896938569729.jpg')
|
||||
assert.deepEqual(GROUPS.map(({ id }) => id), ['ticket', 'vip', 'bus', 'package', 'tour', 'play'])
|
||||
assert.deepEqual(GROUPS.map(({ sortOrder, enabled }) => [sortOrder, enabled]), [[1, true], [2, true], [3, true], [4, true], [5, true], [6, true]])
|
||||
assert.deepEqual(SCENIC_SPOT, {
|
||||
id: 'libo-xiaoqikong', name: '荔波小七孔景区', level: '国家5A级景区', heritage: '世界自然遗产', address: '贵州省黔南布依族苗族自治州荔波县', phone: '0854-3619810', latitude: 25.2534, longitude: 107.7255, heroImage: PLACEHOLDER_IMAGE,
|
||||
})
|
||||
assert.deepEqual(GROUPS.map(({ id, name, sortOrder, enabled, productIds }) => ({ id, name, sortOrder, enabled, productIds })), [
|
||||
{ id: 'ticket', name: '景点门票', sortOrder: 1, enabled: true, productIds: ['adult', 'elderly', 'minor', 'free'] },
|
||||
{ id: 'vip', name: 'VIP速通', sortOrder: 2, enabled: true, productIds: ['vip-fast'] },
|
||||
{ id: 'bus', name: '直通车', sortOrder: 3, enabled: true, productIds: ['direct-bus'] },
|
||||
{ id: 'package', name: '门票+观光车', sortOrder: 4, enabled: true, productIds: ['classic'] },
|
||||
{ id: 'tour', name: '一日游', sortOrder: 5, enabled: true, productIds: ['day-tour'] },
|
||||
{ id: 'play', name: '玩乐体验', sortOrder: 6, enabled: true, productIds: ['boat', 'guide'] },
|
||||
])
|
||||
assert.deepEqual(PRODUCTS.map(({ id }) => id), ['adult', 'elderly', 'minor', 'free', 'vip-fast', 'direct-bus', 'classic', 'day-tour', 'boat', 'guide'])
|
||||
const productsById = new Map(PRODUCTS.map((product) => [product.id, product]))
|
||||
assert.ok(GROUPS.every((group) => group.productIds.every((productId) => productsById.has(productId))))
|
||||
assert.deepEqual(GROUPS.flatMap((group) => group.productIds).sort(), PRODUCTS.map(({ id }) => id).sort())
|
||||
assert.ok(PRODUCTS.every((product) => product.images[0] === PLACEHOLDER_IMAGE && product.reservation && product.entitlements.length && Number.isFinite(product.salePrice) && Number.isFinite(product.stock) && Number.isFinite(product.sold)))
|
||||
assert.deepEqual(PRODUCTS.slice(0, 3).map(({ id, salePrice, sold }) => [id, salePrice, sold]), [['adult', 160, 2386], ['elderly', 100, 816], ['minor', 100, 629]])
|
||||
assert.ok(INITIAL_TRAVELERS.length > 0)
|
||||
assert.ok(INITIAL_TRAVELERS.every((traveler) => traveler.id && traveler.name && traveler.idType && traveler.idNumber && traveler.phone))
|
||||
const productKeys = ['id', 'name', 'shortTitle', 'category', 'description', 'salePrice', 'marketPrice', 'stock', 'sold', 'status', 'highlights', 'ageRule', 'included', 'excluded', 'detail', 'purchaseNotice', 'images', 'reservation', 'entitlements']
|
||||
const reservationKeys = ['requiresDate', 'advanceDays', 'requiresTimeSlot', 'timeSlots', 'realNameRequired', 'idTypes', 'maxQuantity', 'contactPhoneRequired']
|
||||
const entitlementKeys = ['id', 'name', 'fulfillment', 'quantity', 'unit', 'refundAllocation']
|
||||
assert.ok(PRODUCTS.every((product) => productKeys.every((key) => key in product) && product.status === 'on_sale' && Number.isFinite(product.salePrice) && Number.isFinite(product.stock) && Number.isFinite(product.sold) && product.images.length === 1 && product.images[0] === PLACEHOLDER_IMAGE && reservationKeys.every((key) => key in product.reservation) && product.entitlements.length && product.entitlements.every((entitlement) => entitlementKeys.every((key) => key in entitlement))))
|
||||
assert.deepEqual(PRODUCTS.map(({ id, salePrice, marketPrice, sold }) => [id, salePrice, marketPrice, sold]), [
|
||||
['adult', 160, 170, 2386], ['elderly', 100, 160, 816], ['minor', 100, 160, 629], ['free', 40, 80, 346], ['vip-fast', 98, 128, 126], ['direct-bus', 68, 88, 92], ['classic', 188, 210, 184], ['day-tour', 188, 228, 68], ['boat', 50, 60, 326], ['guide', 68, 88, 40],
|
||||
])
|
||||
assert.deepEqual(productsById.get('elderly').ageRule, { min: 60, max: 120 })
|
||||
assert.deepEqual(productsById.get('minor').ageRule, { min: 6, max: 17 })
|
||||
assert.deepEqual(productsById.get('adult').entitlements.map(({ fulfillment, refundAllocation }) => [fulfillment, refundAllocation]), [['third_party', 120], ['third_party', 40]])
|
||||
assert.deepEqual(productsById.get('classic').entitlements.map(({ fulfillment, refundAllocation }) => [fulfillment, refundAllocation]), [['third_party', 160], ['self', 28]])
|
||||
for (const productId of ['vip-fast', 'day-tour', 'boat', 'guide']) assert.ok(productsById.get(productId).entitlements.every(({ fulfillment }) => fulfillment === 'self'))
|
||||
for (const productId of ['direct-bus', 'free', 'elderly', 'minor']) assert.ok(productsById.get(productId).entitlements.every(({ fulfillment }) => fulfillment === 'third_party'))
|
||||
const standardSlots = ['08:00—09:30', '09:30—11:30', '11:30—13:30', '13:30—15:00', '15:00—16:00']
|
||||
for (const productId of ['adult', 'elderly', 'minor', 'free', 'classic']) assert.deepEqual(productsById.get(productId).reservation.timeSlots, standardSlots)
|
||||
assert.deepEqual(productsById.get('vip-fast').reservation.timeSlots, ['08:00—10:00', '10:00—12:00', '12:00—14:00', '14:00—16:00'])
|
||||
assert.deepEqual(productsById.get('direct-bus').reservation.timeSlots, ['06:30—07:00 去程', '18:00—18:30 返程'])
|
||||
assert.deepEqual(productsById.get('day-tour').reservation.timeSlots, ['08:00—08:30 集合', '09:00—09:30 集合'])
|
||||
assert.deepEqual(productsById.get('guide').reservation.timeSlots, ['09:00—10:30', '13:30—15:00'])
|
||||
assert.equal(productsById.get('boat').reservation.requiresTimeSlot, false)
|
||||
assert.deepEqual(productsById.get('boat').reservation.timeSlots, [])
|
||||
assert.deepEqual(AVAILABLE_DATES, [
|
||||
{ date: '2026-08-01', week: '周六', label: '8月1日', stock: 120 }, { date: '2026-08-02', week: '周日', label: '8月2日', stock: 96 }, { date: '2026-08-03', week: '周一', label: '8月3日', stock: 68 }, { date: '2026-08-04', week: '周二', label: '8月4日', stock: 0 }, { date: '2026-08-05', week: '周三', label: '8月5日', stock: 42 },
|
||||
])
|
||||
assert.deepEqual(INSURANCE, { name: '出行意外险', price: 5, description: '最高10万元意外保障' })
|
||||
assert.deepEqual(REFUND_REASONS, ['行程有变,无法按计划出行', '重复购买', '选错日期或票种', '其他原因'])
|
||||
assert.deepEqual(INITIAL_TRAVELERS, [
|
||||
{ id: 'traveler-lin-xiao', name: '林晓', idType: '身份证', idNumber: '110101199001020010', phone: '13800138000' }, { id: 'traveler-zhou-ning', name: '周宁', idType: '身份证', idNumber: '110101196001020010', phone: '13900139000' },
|
||||
])
|
||||
assert.deepEqual(PRODUCTS, productsBeforeOrders)
|
||||
assert.deepEqual(INITIAL_TRAVELERS, travelersBeforeOrders)
|
||||
assert.equal(INITIAL_ORDERS.length, 2)
|
||||
assert.ok(INITIAL_ORDERS.some((order) => order.entitlements.some((entitlement) => entitlement.fulfillment === 'third_party') && order.gateCredential))
|
||||
assert.ok(INITIAL_ORDERS.some((order) => order.entitlements.some((entitlement) => entitlement.fulfillment === 'third_party') && order.entitlements.some((entitlement) => entitlement.fulfillment === 'self') && order.gateCredential && order.selfCredential))
|
||||
assert.equal(AVAILABLE_DATES.length, 5)
|
||||
assert.ok(AVAILABLE_DATES.some((date) => date.stock === 0))
|
||||
assert.equal(REFUND_REASONS.length, 4)
|
||||
assert.equal(INSURANCE.price, 5)
|
||||
assert.deepEqual(INITIAL_ORDERS.map(({ productId, visitDate, timeSlot, insurance, gateCredential, selfCredential, entitlements }) => ({ productId, visitDate, timeSlot, insurance, hasGateCredential: Boolean(gateCredential), hasSelfCredential: Boolean(selfCredential), fulfillment: entitlements.map(({ fulfillment }) => fulfillment) })), [
|
||||
{ productId: 'adult', visitDate: '2026-08-01', timeSlot: '08:00—09:30', insurance: { name: '出行意外险', price: 5, quantity: 1, status: 'active' }, hasGateCredential: true, hasSelfCredential: false, fulfillment: ['third_party', 'third_party'] },
|
||||
{ productId: 'classic', visitDate: '2026-08-02', timeSlot: '09:30—11:30', insurance: null, hasGateCredential: true, hasSelfCredential: true, fulfillment: ['third_party', 'self'] },
|
||||
])
|
||||
})
|
||||
|
||||
const adultProduct = {
|
||||
|
||||
Reference in New Issue
Block a user