| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- import * as fc from 'fast-check';
- import {
- OrderStatus,
- VALID_ORDER_TRANSITIONS,
- isValidOrderTransition,
- generateOrderNo
- } from '../../../src/models/order.model';
- /**
- * **Feature: backend-frontend-integration, Property 3: Order Status Transition Validity**
- * **Validates: Requirements 2.5, 2.6**
- *
- * *For any* order status update, the new status SHALL only be reachable from valid previous states
- * (e.g., Shipped can only follow PendingShipment, Cancelled can only follow PendingPayment or PendingShipment).
- */
- describe('Order Model Property Tests', () => {
- // 所有订单状态
- const allStatuses = Object.values(OrderStatus);
- // 生成任意订单状态的arbitrary
- const orderStatusArb = fc.constantFrom(...allStatuses);
- describe('Property 3: Order Status Transition Validity', () => {
- it('should only allow valid status transitions as defined in VALID_ORDER_TRANSITIONS', () => {
- fc.assert(
- fc.property(
- orderStatusArb,
- orderStatusArb,
- (fromStatus, toStatus) => {
- const isValid = isValidOrderTransition(fromStatus, toStatus);
- const expectedValid = VALID_ORDER_TRANSITIONS[fromStatus].includes(toStatus);
-
- // 验证isValidOrderTransition函数与VALID_ORDER_TRANSITIONS映射一致
- return isValid === expectedValid;
- }
- ),
- { numRuns: 100 }
- );
- });
- it('Shipped status can only be reached from PendingShipment', () => {
- fc.assert(
- fc.property(
- orderStatusArb,
- (fromStatus) => {
- const canTransitionToShipped = isValidOrderTransition(fromStatus, OrderStatus.Shipped);
-
- // 只有PendingShipment可以转换到Shipped
- if (fromStatus === OrderStatus.PendingShipment) {
- return canTransitionToShipped === true;
- } else {
- return canTransitionToShipped === false;
- }
- }
- ),
- { numRuns: 100 }
- );
- });
- it('Completed status can only be reached from Shipped', () => {
- fc.assert(
- fc.property(
- orderStatusArb,
- (fromStatus) => {
- const canTransitionToCompleted = isValidOrderTransition(fromStatus, OrderStatus.Completed);
-
- // 只有Shipped可以转换到Completed
- if (fromStatus === OrderStatus.Shipped) {
- return canTransitionToCompleted === true;
- } else {
- return canTransitionToCompleted === false;
- }
- }
- ),
- { numRuns: 100 }
- );
- });
- it('Cancelled status can only be reached from PendingPayment or PendingShipment', () => {
- fc.assert(
- fc.property(
- orderStatusArb,
- (fromStatus) => {
- const canTransitionToCancelled = isValidOrderTransition(fromStatus, OrderStatus.Cancelled);
-
- // 只有PendingPayment和PendingShipment可以转换到Cancelled
- if (fromStatus === OrderStatus.PendingPayment || fromStatus === OrderStatus.PendingShipment) {
- return canTransitionToCancelled === true;
- } else {
- return canTransitionToCancelled === false;
- }
- }
- ),
- { numRuns: 100 }
- );
- });
- it('terminal states (Completed, Cancelled) cannot transition to any other state', () => {
- fc.assert(
- fc.property(
- orderStatusArb,
- (toStatus) => {
- // Completed和Cancelled是终态,不能转换到任何其他状态
- const fromCompleted = isValidOrderTransition(OrderStatus.Completed, toStatus);
- const fromCancelled = isValidOrderTransition(OrderStatus.Cancelled, toStatus);
-
- return fromCompleted === false && fromCancelled === false;
- }
- ),
- { numRuns: 100 }
- );
- });
- });
- describe('Order Number Generation', () => {
- it('should generate order numbers with correct format (yyyyMMddHHmmss + 6 digits)', () => {
- fc.assert(
- fc.property(
- fc.integer({ min: 1, max: 100 }),
- () => {
- const orderNo = generateOrderNo();
-
- // 订单号应该是20位:14位时间戳 + 6位随机数
- if (orderNo.length !== 20) return false;
-
- // 应该全是数字
- if (!/^\d{20}$/.test(orderNo)) return false;
-
- return true;
- }
- ),
- { numRuns: 100 }
- );
- });
- it('should generate unique order numbers', () => {
- fc.assert(
- fc.property(
- fc.integer({ min: 10, max: 50 }),
- (count) => {
- const orderNos = new Set<string>();
- for (let i = 0; i < count; i++) {
- orderNos.add(generateOrderNo());
- }
- // 生成的订单号应该都是唯一的
- return orderNos.size === count;
- }
- ),
- { numRuns: 20 }
- );
- });
- });
- });
|