Files
gestion-materiaux-destock/src/lib/creationSheets.test.ts
T

104 lines
3.8 KiB
TypeScript

import { parseTabRows, findColIndex, extractSpecificFields } from './creationSheets'
const HEADERS = [
'ID', 'Type', 'UGS', 'Nom', 'Publié', 'Mis en avant ?',
'Description courte', 'Description longue',
'Date de début de promo', 'Date de fin de promo',
'État de la TVA', 'Classe de TVA', 'En stock ?',
'Stock (en pièce)', 'Vendre individuellement ?',
'Prix marché', 'Prix remisé', 'Code ecopart', 'Ecopart montant',
'Famille', 'Sous famille',
"Classe d'expédition (en retrait, livraison)",
'Conditionnement', 'Surface (m2)', 'Poids (kg) fonction unité',
'Images', 'Unité', 'Marque', 'Neuf ?',
"Commentaire\nexemple : Modèle d'expo (lègères rayures)",
'Longueur (cm)', 'Largeur (cm)', 'Hauteur (cm)', 'Épaisseur (cm)',
'Poids par carton', 'Stock conditionné (en carton)',
'Fabrication', 'Garantie', 'Coloris',
'Puissance (AN)', 'Batterie (AP)', 'Couple (AQ)',
'PHOTO ?', 'ID FAMILLE', 'ID SOUS FAMILLE',
]
const makeRow = (overrides: Record<number, string> = {}): string[] => {
const base: Record<number, string> = {
0: '', // ID vide = à créer
2: 'SKU-001', // UGS
3: 'Perceuse Test',
4: '1', // Publié
13: '5', // Stock
15: '99.99', // Prix marché
16: '79.99', // Prix remisé
19: 'OUTILLAGE',
24: '2.5', // Poids
27: 'BOSCH', // Marque
39: '1500W', // Puissance
40: 'Li-Ion', // Batterie
// Couple (index 41) laissé vide
[HEADERS.length - 2]: '10', // ID FAMILLE
[HEADERS.length - 1]: '20', // ID SOUS FAMILLE
}
return HEADERS.map((_, i) => overrides[i] ?? base[i] ?? '')
}
describe('findColIndex', () => {
it('trouve un en-tête exact', () => {
expect(findColIndex(HEADERS, 'UGS')).toBe(2)
})
it('trouve un en-tête commençant par Commentaire', () => {
const idx = findColIndex(HEADERS, 'Commentaire')
expect(idx).toBeGreaterThan(-1)
})
it('retourne -1 si non trouvé', () => {
expect(findColIndex(HEADERS, 'Inexistant')).toBe(-1)
})
})
describe('extractSpecificFields', () => {
it('exclut les colonnes communes', () => {
const row = makeRow()
const specific = extractSpecificFields(HEADERS, row)
expect(Object.keys(specific)).not.toContain('Nom')
expect(Object.keys(specific)).not.toContain('UGS')
})
it('inclut les colonnes spécifiques non vides', () => {
const row = makeRow()
const specific = extractSpecificFields(HEADERS, row)
expect(specific['Puissance (AN)']).toBe('1500W')
expect(specific['Batterie (AP)']).toBe('Li-Ion')
})
it('exclut les colonnes spécifiques vides', () => {
const row = makeRow()
const specific = extractSpecificFields(HEADERS, row)
expect(Object.keys(specific)).not.toContain('Couple (AQ)')
})
})
describe('parseTabRows', () => {
it('ignore les lignes avec ID déjà rempli', () => {
const row = makeRow({ 0: '12345' })
const result = parseTabRows('OUTILLAGE', HEADERS, [row])
expect(result).toHaveLength(0)
})
it('ignore les lignes avec Publié ≠ 1', () => {
const row = makeRow({ 4: '0' })
const result = parseTabRows('OUTILLAGE', HEADERS, [row])
expect(result).toHaveLength(0)
})
it('retourne un PendingProduct pour une ligne valide', () => {
const row = makeRow()
const result = parseTabRows('OUTILLAGE', HEADERS, [row])
expect(result).toHaveLength(1)
expect(result[0].sku).toBe('SKU-001')
expect(result[0].title).toBe('Perceuse Test')
expect(result[0].priceActual).toBe('79.99')
expect(result[0].collectionId).toBe('10')
expect(result[0].specificFields['Puissance (AN)']).toBe('1500W')
})
it('attribue le bon numéro de ligne (1-indexé depuis row 2)', () => {
const rows = [makeRow(), makeRow({ 3: 'Deuxième' })]
const result = parseTabRows('OUTILLAGE', HEADERS, rows)
expect(result[0].rowNumber).toBe(2)
expect(result[1].rowNumber).toBe(3)
})
})