/** * 字段数据存储工具测试 */ import { isStandardField, separateFieldValues, buildMetadata, parseMetadata, readAllFieldValues, prepareMaterialData, checkMetadataSize, compressMetadata, getFieldStorageLocation, getFieldsStorageLocations, STANDARD_MATERIAL_FIELDS, } from '../field-data-storage' describe('field-data-storage', () => { describe('isStandardField', () => { it('should return true for standard fields', () => { expect(isStandardField('productModel')).toBe(true) expect(isStandardField('categoryName')).toBe(true) expect(isStandardField('sceneName')).toBe(true) expect(isStandardField('renderer')).toBe(true) expect(isStandardField('authorName')).toBe(true) }) it('should return false for custom fields', () => { expect(isStandardField('customField')).toBe(false) expect(isStandardField('myField')).toBe(false) expect(isStandardField('unknownField')).toBe(false) }) it('should be case sensitive', () => { expect(isStandardField('ProductModel')).toBe(false) expect(isStandardField('PRODUCTMODEL')).toBe(false) }) }) describe('separateFieldValues', () => { it('should separate standard and custom fields', () => { const fields = { productModel: 'ABC123', categoryName: '店铺A', customField: '自定义值', anotherCustom: 123, } const { standardFields, customFields } = separateFieldValues(fields) expect(standardFields).toEqual({ productModel: 'ABC123', categoryName: '店铺A', }) expect(customFields).toEqual({ customField: '自定义值', anotherCustom: 123, }) }) it('should convert standard field values to strings', () => { const fields = { productModel: 123, categoryName: true, } const { standardFields } = separateFieldValues(fields) expect(standardFields.productModel).toBe('123') expect(standardFields.categoryName).toBe('true') }) it('should handle null/undefined values', () => { const fields = { productModel: null, categoryName: undefined, customField: null, } const { standardFields, customFields } = separateFieldValues(fields) expect(standardFields.productModel).toBe('') expect(standardFields.categoryName).toBe('') expect(customFields.customField).toBeNull() }) it('should handle empty input', () => { const { standardFields, customFields } = separateFieldValues({}) expect(Object.keys(standardFields)).toHaveLength(0) expect(Object.keys(customFields)).toHaveLength(0) }) }) describe('buildMetadata', () => { it('should build metadata with custom fields', () => { const customFields = { myField: 'value', count: 5 } const result = buildMetadata(customFields) expect(result).not.toBeNull() const parsed = JSON.parse(result!) expect(parsed.templateFields).toEqual(customFields) }) it('should include templateId', () => { const result = buildMetadata({}, 'template-123') expect(result).not.toBeNull() const parsed = JSON.parse(result!) expect(parsed.templateId).toBe('template-123') }) it('should include previewUrls', () => { const previewUrls = ['url1', 'url2'] const result = buildMetadata({}, null, previewUrls) expect(result).not.toBeNull() const parsed = JSON.parse(result!) expect(parsed.previewUrls).toEqual(previewUrls) }) it('should merge with existing metadata', () => { const existingMetadata = JSON.stringify({ templateId: 'old-template', templateFields: { oldField: 'oldValue' }, }) const result = buildMetadata({ newField: 'newValue' }, 'new-template', undefined, existingMetadata) const parsed = JSON.parse(result!) expect(parsed.templateId).toBe('new-template') expect(parsed.templateFields.oldField).toBe('oldValue') expect(parsed.templateFields.newField).toBe('newValue') }) it('should return null for empty data', () => { const result = buildMetadata({}) expect(result).toBeNull() }) }) describe('parseMetadata', () => { it('should parse valid metadata', () => { const metadata = JSON.stringify({ templateId: 'template-123', templateFields: { field1: 'value1' }, previewUrls: ['url1'], }) const result = parseMetadata(metadata) expect(result.templateId).toBe('template-123') expect(result.templateFields).toEqual({ field1: 'value1' }) expect(result.previewUrls).toEqual(['url1']) }) it('should return empty templateFields for null', () => { const result = parseMetadata(null) expect(result.templateFields).toEqual({}) }) it('should return empty templateFields for invalid JSON', () => { const result = parseMetadata('invalid json') expect(result.templateFields).toEqual({}) }) it('should handle missing templateFields', () => { const metadata = JSON.stringify({ templateId: 'test' }) const result = parseMetadata(metadata) expect(result.templateFields).toEqual({}) }) }) describe('readAllFieldValues', () => { it('should read standard fields from material', () => { const material = { productModel: 'ABC123', categoryName: '店铺A', sceneName: '场景B', metadata: null, } const result = readAllFieldValues(material) expect(result.productModel).toBe('ABC123') expect(result.categoryName).toBe('店铺A') expect(result.sceneName).toBe('场景B') }) it('should read custom fields from metadata', () => { const material = { productModel: 'ABC123', metadata: JSON.stringify({ templateFields: { customField: 'customValue' }, }), } const result = readAllFieldValues(material) expect(result.productModel).toBe('ABC123') expect(result.customField).toBe('customValue') }) it('should not override standard fields with metadata', () => { const material = { productModel: 'StandardValue', metadata: JSON.stringify({ templateFields: { productModel: 'MetadataValue' }, }), } const result = readAllFieldValues(material) // 标准字段应该使用数据库列的值 expect(result.productModel).toBe('StandardValue') }) it('should skip empty standard fields', () => { const material = { productModel: '', categoryName: null, sceneName: undefined, metadata: null, } const result = readAllFieldValues(material) expect(result.productModel).toBeUndefined() expect(result.categoryName).toBeUndefined() expect(result.sceneName).toBeUndefined() }) }) describe('prepareMaterialData', () => { it('should prepare data for material creation', () => { const templateFields = { productModel: 'ABC123', categoryName: '店铺A', customField: '自定义值', } const { standardData, metadata } = prepareMaterialData(templateFields, 'template-123') expect(standardData.productModel).toBe('ABC123') expect(standardData.categoryName).toBe('店铺A') expect(metadata).not.toBeNull() const parsedMetadata = JSON.parse(metadata!) expect(parsedMetadata.templateId).toBe('template-123') expect(parsedMetadata.templateFields.customField).toBe('自定义值') }) it('should include previewUrls', () => { const { metadata } = prepareMaterialData({}, null, ['url1', 'url2']) const parsed = JSON.parse(metadata!) expect(parsed.previewUrls).toEqual(['url1', 'url2']) }) }) describe('checkMetadataSize', () => { it('should return ok for small metadata', () => { const metadata = JSON.stringify({ field: 'value' }) const result = checkMetadataSize(metadata) expect(result.ok).toBe(true) expect(result.size).toBeLessThan(result.maxSize) }) it('should return not ok for large metadata', () => { const largeData = 'x'.repeat(100000) const metadata = JSON.stringify({ field: largeData }) const result = checkMetadataSize(metadata, 1000) expect(result.ok).toBe(false) expect(result.size).toBeGreaterThan(result.maxSize) }) it('should handle null metadata', () => { const result = checkMetadataSize(null) expect(result.ok).toBe(true) expect(result.size).toBe(0) }) }) describe('compressMetadata', () => { it('should remove empty templateFields', () => { const metadata = JSON.stringify({ templateId: 'test', templateFields: { field1: '', field2: null, field3: 'value' }, }) const result = compressMetadata(metadata) const parsed = JSON.parse(result!) expect(parsed.templateFields).toEqual({ field3: 'value' }) }) it('should remove empty previewUrls array', () => { const metadata = JSON.stringify({ templateId: 'test', previewUrls: [], }) const result = compressMetadata(metadata) const parsed = JSON.parse(result!) expect(parsed.previewUrls).toBeUndefined() }) it('should return null for empty result', () => { const metadata = JSON.stringify({ templateFields: { field1: '', field2: null }, }) const result = compressMetadata(metadata) expect(result).toBeNull() }) it('should handle invalid JSON', () => { const result = compressMetadata('invalid json') expect(result).toBe('invalid json') }) it('should handle null input', () => { const result = compressMetadata(null) expect(result).toBeNull() }) }) describe('getFieldStorageLocation', () => { it('should return standard for standard fields', () => { expect(getFieldStorageLocation('productModel')).toBe('standard') expect(getFieldStorageLocation('categoryName')).toBe('standard') }) it('should return metadata for custom fields', () => { expect(getFieldStorageLocation('customField')).toBe('metadata') expect(getFieldStorageLocation('myField')).toBe('metadata') }) }) describe('getFieldsStorageLocations', () => { it('should return map of storage locations', () => { const fields = ['productModel', 'customField', 'categoryName'] const result = getFieldsStorageLocations(fields) expect(result.get('productModel')).toBe('standard') expect(result.get('customField')).toBe('metadata') expect(result.get('categoryName')).toBe('standard') }) }) describe('STANDARD_MATERIAL_FIELDS', () => { it('should contain expected fields', () => { expect(STANDARD_MATERIAL_FIELDS).toContain('productModel') expect(STANDARD_MATERIAL_FIELDS).toContain('categoryName') expect(STANDARD_MATERIAL_FIELDS).toContain('sceneName') expect(STANDARD_MATERIAL_FIELDS).toContain('renderer') expect(STANDARD_MATERIAL_FIELDS).toContain('authorName') expect(STANDARD_MATERIAL_FIELDS).toContain('platformName') }) }) })