feat(plan5): shopifyMetafields — matching + gestion définitions (TDD)
Implémente Task 4 du Plan 5: - normalizeMetafieldKey: minuscules, accents retirés, espaces/parenth→_, max 30 chars - matchMetafields: compare clé normalisée d'une colonne avec les clés existantes - fetchMetafieldDefinitions: récupère les définitions Shopify existantes - ensureMetafieldDefinition: crée une définition si manquante - setProductMetafield: définit un métachamp sur un produit 7 tests passants (4 normalizeMetafieldKey + 3 matchMetafields). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
import { normalizeMetafieldKey, matchMetafields } from './shopifyMetafields'
|
||||
import type { MetafieldDefinition } from '@/types/creation'
|
||||
|
||||
describe('normalizeMetafieldKey', () => {
|
||||
it('minuscules + accents retirés', () => {
|
||||
expect(normalizeMetafieldKey('Éclairage LED')).toBe('eclairage_led')
|
||||
})
|
||||
it('parenthèses et espaces → underscore', () => {
|
||||
expect(normalizeMetafieldKey('Puissance (AN)')).toBe('puissance_an')
|
||||
})
|
||||
it('limité à 30 caractères', () => {
|
||||
const long = 'a'.repeat(40)
|
||||
expect(normalizeMetafieldKey(long)).toHaveLength(30)
|
||||
})
|
||||
it('underscores multiples réduits à un', () => {
|
||||
expect(normalizeMetafieldKey('Poids par carton')).toBe('poids_par_carton')
|
||||
})
|
||||
})
|
||||
|
||||
describe('matchMetafields', () => {
|
||||
const definitions: MetafieldDefinition[] = [
|
||||
{ id: '1', namespace: 'custom', key: 'puissance_an', name: 'Puissance (AN)', type: 'single_line_text_field' },
|
||||
{ id: '2', namespace: 'custom', key: 'coloris', name: 'Coloris', type: 'single_line_text_field' },
|
||||
]
|
||||
|
||||
it('trouve une correspondance exacte sur la clé normalisée', () => {
|
||||
const result = matchMetafields(['Puissance (AN)', 'Batterie (AP)'], definitions)
|
||||
expect(result.matched['Puissance (AN)'].existingDefinitionId).toBe('1')
|
||||
})
|
||||
|
||||
it('met les colonnes sans correspondance dans unmatched', () => {
|
||||
const result = matchMetafields(['Puissance (AN)', 'Batterie (AP)'], definitions)
|
||||
expect(result.unmatched).toContain('Batterie (AP)')
|
||||
})
|
||||
|
||||
it('ne met pas en unmatched les colonnes qui ont un match', () => {
|
||||
const result = matchMetafields(['Puissance (AN)'], definitions)
|
||||
expect(result.unmatched).not.toContain('Puissance (AN)')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user