useFieldValueTransform.test.js 6.82 KB
/**
 * useFieldValueTransform 单元测试
 *
 * @description 测试字段值转换 Composable
 * @module composables/__tests__/useFieldValueTransform.test
 */

import { ref } from 'vue'
import { describe, it, expect, beforeEach } from 'vitest'
import { useFieldValueTransform } from '../useFieldValueTransform'
import { PLAN_FIELD_DEFINITIONS, TRANSFORM_TYPES } from '@/config/plan-fields'

describe('useFieldValueTransform', () => {
  describe('toYuan - 分转元(用于显示)', () => {
    it('should convert fen value to yuan format', () => {
      const formData = ref({ coverage: '1000000' }) // 分值整数(10000元×100)
      const fieldDefinitions = PLAN_FIELD_DEFINITIONS

      const { toYuan } = useFieldValueTransform(formData, fieldDefinitions)

      // 分值 1000000(10000元×100)转为元值:÷100 = 10000.00(保留两位小数)
      expect(toYuan('coverage', '1000000')).toBe('10000.00')
      expect(toYuan('coverage', '1500000')).toBe('15000.00')
    })

    it('should convert yuan decimal string correctly', () => {
      const formData = ref({ coverage: '1000050' }) // 分值整数
      const { toYuan } = useFieldValueTransform(formData, PLAN_FIELD_DEFINITIONS)

      expect(toYuan('coverage', '1000050')).toBe('10000.50') // 分转元:÷100,保留两位小数
    })

    it('should return yuan value directly for fields without transform', () => {
      const formData = ref({ customer_name: '张三' })
      const { toYuan } = useFieldValueTransform(formData, PLAN_FIELD_DEFINITIONS)

      expect(toYuan('customer_name', '张三')).toBe('张三')
    })

    it('should handle null values', () => {
      const formData = ref({ coverage: null })
      const { toYuan } = useFieldValueTransform(formData, PLAN_FIELD_DEFINITIONS)

      expect(toYuan('coverage', null)).toBe(null)
    })

    it('should handle undefined values', () => {
      const formData = ref({ coverage: undefined })
      const { toYuan } = useFieldValueTransform(formData, PLAN_FIELD_DEFINITIONS)

      expect(toYuan('coverage', undefined)).toBe(undefined)
    })

    it('should return string for fen values (keep 2 decimal places)', () => {
      const formData = ref({ coverage: '100005' }) // 分值字符串(10000.05元×100)
      const { toYuan } = useFieldValueTransform(formData, PLAN_FIELD_DEFINITIONS)

      // fenToYuan 返回字符串格式的元值
      expect(toYuan('coverage', '100005')).toBe('1000.05') // 分→元:÷100,保留两位小数
    })
  })

  describe('toFen - 元转分(用于提交)', () => {
    it('should convert yuan value to fen', () => {
      const formData = ref({ coverage: '10000' }) // 元值
      const { toFen } = useFieldValueTransform(formData, PLAN_FIELD_DEFINITIONS)

      expect(toFen('coverage', '10000')).toBe(1000000) // 元→分:×100
    })

    it('should convert yuan string to fen', () => {
      const formData = ref({ coverage: '10000.00' }) // 元值字符串
      const { toFen } = useFieldValueTransform(formData, PLAN_FIELD_DEFINITIONS)

      expect(toFen('coverage', '10000.00')).toBe(1000000) // 元→分:×100
    })

    it('should handle null values', () => {
      const formData = ref({ coverage: null })
      const { toFen } = useFieldValueTransform(formData, PLAN_FIELD_DEFINITIONS)

      expect(toFen('coverage', null)).toBe(null)
    })

    it('should handle undefined values', () => {
      const formData = ref({ coverage: undefined })
      const { toFen } = useFieldValueTransform(formData, PLAN_FIELD_DEFINITIONS)

      expect(toFen('coverage', undefined)).toBe(undefined)
    })

    it('should return original value for fields without transform', () => {
      const formData = ref({ customer_name: '张三' })
      const { toFen } = useFieldValueTransform(formData, PLAN_FIELD_DEFINITIONS)

      expect(toFen('customer_name', '张三')).toBe('张三')
    })
  })

  describe('batchToFen - 批量元转分', () => {
    it('should convert all yuan fields to fen', () => {
      const formData = ref({
        coverage: 10000,  // 元值→分值
        withdrawal_period: 3,
        customer_name: '张三'
      })
      const { submitData } = useFieldValueTransform(formData, PLAN_FIELD_DEFINITIONS)

      const result = submitData.value
      expect(result.coverage).toBe(1000000) // 元转分:×100
      expect(result.withdrawal_period).toBe(3)
      expect(result.customer_name).toBe('张三')
    })

    it('should skip fields without transform attribute', () => {
      const formData = ref({
        customer_name: '张三',
        gender: 'male'
      })
      const { submitData } = useFieldValueTransform(formData, PLAN_FIELD_DEFINITIONS)

      const result = submitData.value
      expect(result.customer_name).toBe('张三')
      expect(result.gender).toBe('male')
    })
  })

  describe('batchToFen - 批量元转分(用于提交)', () => {
    it('should convert all yuan fields to fen', () => {
      const formData = ref({
        coverage: '10000',  // 元值→分值
        withdrawal_period: 3
      })
      const { submitData } = useFieldValueTransform(formData, PLAN_FIELD_DEFINITIONS)

      const result = submitData.value
      expect(result.coverage).toBe(1000000) // 元→分:×100
      expect(result.withdrawal_period).toBe(3)
    })

    it('should skip fields without transform attribute', () => {
      const formData = ref({
        customer_name: '张三',
        gender: 'male'
      })
      const { submitData } = useFieldValueTransform(formData, PLAN_FIELD_DEFINITIONS)

      const result = submitData.value
      expect(result.customer_name).toBe('张三')
      expect(result.gender).toBe('male')
    })
  })

  describe('displayData - 表单显示数据(元值)', () => {
    it('should provide fen values for display', () => {
      const formData = ref({
        coverage: 1000000, // 分值(API存储)
        withdrawal_period: 3
      })
      const { displayData } = useFieldValueTransform(formData, PLAN_FIELD_DEFINITIONS)

      expect(displayData.value.coverage).toBe('10000.00') // 分→元显示
      expect(displayData.value.withdrawal_period).toBe(3)
    })

    it('should be reactive', () => {
      const formData = ref({ annual_premium: 10000 })
      const { displayData } = useFieldValueTransform(formData, PLAN_FIELD_DEFINITIONS)

      expect(displayData).toHaveProperty('value')
      expect(displayData.value).toHaveProperty('annual_premium')
    })
  })

  describe('submitData - API 提交数据(元值)', () => {
    it('should provide yuan values for submit', () => {
      const formData = ref({
        coverage: 10000, // 元值整数,×100转分值
        withdrawal_period: 3
      })
      const { submitData } = useFieldValueTransform(formData, PLAN_FIELD_DEFINITIONS)

      expect(submitData.value.coverage).toBe(1000000) // 元→分:×100
      expect(submitData.value.withdrawal_period).toBe(3)
    })
  })
})