/** * Property 14: 聊天页手机号显示规则 * * 对于任意订单的聊天页: * - 当查看者为单主时,应展示跑腿认证手机号 * - 当查看者为跑腿时,应展示单主下单手机号 */ import { describe, it, expect } from 'vitest' import * as fc from 'fast-check' import { getChatTargetPhone } from './chat-rules' // ==================== 生成器 ==================== /** 生成手机号 */ const phoneArb = fc.stringMatching(/^1[3-9]\d{9}$/) /** 生成用户 ID */ const userIdArb = fc.integer({ min: 1, max: 100000 }) // ==================== 属性测试 ==================== describe('Feature: login-and-homepage, Property 14: 聊天页手机号显示规则', () => { /** * * 单主查看时应展示跑腿认证手机号 */ it('单主查看时展示跑腿认证手机号', () => { fc.assert( fc.property( userIdArb, userIdArb.filter(id => id > 1), phoneArb, phoneArb, (ownerId, runnerOffset, ownerPhone, runnerPhone) => { const runnerId = ownerId + runnerOffset const result = getChatTargetPhone({ currentUserId: ownerId, ownerId, runnerId, ownerPhone, runnerPhone }) expect(result).toBe(runnerPhone) } ), { numRuns: 200 } ) }) /** * * 跑腿查看时展示单主下单手机号 */ it('跑腿查看时展示单主下单手机号', () => { fc.assert( fc.property( userIdArb, userIdArb.filter(id => id > 1), phoneArb, phoneArb, (ownerId, runnerOffset, ownerPhone, runnerPhone) => { const runnerId = ownerId + runnerOffset const result = getChatTargetPhone({ currentUserId: runnerId, ownerId, runnerId, ownerPhone, runnerPhone }) expect(result).toBe(ownerPhone) } ), { numRuns: 200 } ) }) }) /** * Property 15: 聊天功能按钮显示规则 * * 对于任意订单类型和用户角色组合: * - 所有订单显示【发送图片】【更改跑腿价格】 * - 代购和美食街订单额外显示【更改商品价格】 * - 仅跑腿用户可见【完成订单】 */ import { getChatMenuButtons } from './chat-rules' /** 订单类型生成器 */ const orderTypeArb = fc.constantFrom('Pickup', 'Delivery', 'Help', 'Purchase', 'Food') describe('Feature: login-and-homepage, Property 15: 聊天功能按钮显示规则', () => { /** * * 所有订单都显示发送图片和更改跑腿价格 */ it('所有订单显示发送图片和更改跑腿价格', () => { fc.assert( fc.property( orderTypeArb, userIdArb, userIdArb, (orderType, currentUserId, runnerId) => { const buttons = getChatMenuButtons({ orderType, currentUserId, runnerId }) expect(buttons).toContain('发送图片') expect(buttons).toContain('更改跑腿价格') } ), { numRuns: 200 } ) }) /** * * 代购和美食街订单额外显示更改商品价格,其他类型不显示 */ it('仅代购和美食街订单显示更改商品价格', () => { fc.assert( fc.property( orderTypeArb, userIdArb, userIdArb, (orderType, currentUserId, runnerId) => { const buttons = getChatMenuButtons({ orderType, currentUserId, runnerId }) if (orderType === 'Purchase' || orderType === 'Food') { expect(buttons).toContain('更改商品价格') } else { expect(buttons).not.toContain('更改商品价格') } } ), { numRuns: 200 } ) }) /** * * 仅跑腿用户可见完成订单按钮 */ it('仅跑腿用户可见完成订单', () => { fc.assert( fc.property( orderTypeArb, userIdArb, userIdArb.filter(id => id > 1), (orderType, ownerId, runnerOffset) => { const runnerId = ownerId + runnerOffset // 跑腿用户应看到完成订单 const runnerButtons = getChatMenuButtons({ orderType, currentUserId: runnerId, runnerId }) expect(runnerButtons).toContain('完成订单') // 单主用户不应看到完成订单 const ownerButtons = getChatMenuButtons({ orderType, currentUserId: ownerId, runnerId }) expect(ownerButtons).not.toContain('完成订单') } ), { numRuns: 200 } ) }) })