From fce7bbf975a0bf016d16ee7618c508b19e27ac93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Faleiros?= Date: Mon, 1 Jun 2026 09:47:35 -0300 Subject: [PATCH] fix: title case campaign product names --- backend/services/campaignFormatter.js | 19 +++++++++++++++---- backend/test/campaignFormatter.test.js | 17 +++++++++++++---- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/backend/services/campaignFormatter.js b/backend/services/campaignFormatter.js index af0cd8f..d044943 100644 --- a/backend/services/campaignFormatter.js +++ b/backend/services/campaignFormatter.js @@ -1,9 +1,19 @@ +const formatProductNameForDisplay = (name) => { + return String(name || '') + .toLocaleLowerCase('pt-BR') + .replace(/(^|[\s/-])(\p{L})/gu, (_, separator, letter) => { + return `${separator}${letter.toLocaleUpperCase('pt-BR')}`; + }); +}; + const formatProductList = (productNames) => { - if (productNames.length <= 2) { - return productNames.join(' e '); + const displayNames = productNames.map(formatProductNameForDisplay); + + if (displayNames.length <= 2) { + return displayNames.join(' e '); } - return `${productNames.slice(0, -1).join(', ')} e ${productNames[productNames.length - 1]}`; + return `${displayNames.slice(0, -1).join(', ')} e ${displayNames[displayNames.length - 1]}`; }; const groupCampaignRowsByBaseProduct = (rows) => { @@ -23,7 +33,7 @@ const mapCampaignProducts = (groups) => { const sortedItems = [...items].sort((a, b) => String(a.nome).localeCompare(String(b.nome), 'pt-BR')); return { - baseProduct: baseProductName, + baseProduct: formatProductNameForDisplay(baseProductName), total_delta: sortedItems.reduce((sum, item) => sum + Number(item.delta_estoque || 0), 0), sizes: sortedItems.map(item => ({ id: item.produto_id, @@ -85,6 +95,7 @@ const groupCampaignRows = (rows) => { module.exports = { buildWhatsappCampaignPayload, + formatProductNameForDisplay, formatProductList, groupCampaignRows, groupCampaignRowsByBaseProduct, diff --git a/backend/test/campaignFormatter.test.js b/backend/test/campaignFormatter.test.js index 6646a64..7a5adc4 100644 --- a/backend/test/campaignFormatter.test.js +++ b/backend/test/campaignFormatter.test.js @@ -3,6 +3,7 @@ const assert = require('node:assert/strict'); const { buildWhatsappCampaignPayload, formatProductList, + formatProductNameForDisplay, groupCampaignRows, groupCampaignRowsByBaseProduct, mapCampaignProducts @@ -26,14 +27,22 @@ const row = (overrides) => ({ test('formatProductList uses Portuguese list joining', () => { assert.equal(formatProductList([]), ''); - assert.equal(formatProductList(['BONÉ - PRETO']), 'BONÉ - PRETO'); - assert.equal(formatProductList(['BONÉ - PRETO', 'BASE BRANCA']), 'BONÉ - PRETO e BASE BRANCA'); + assert.equal(formatProductList(['BONÉ - PRETO']), 'Boné - Preto'); + assert.equal(formatProductList(['BONÉ - PRETO', 'BASE BRANCA']), 'Boné - Preto e Base Branca'); assert.equal( formatProductList(['BONÉ - PRETO', 'BASE BRANCA', 'BASE PRETA']), - 'BONÉ - PRETO, BASE BRANCA e BASE PRETA' + 'Boné - Preto, Base Branca e Base Preta' ); }); +test('formatProductNameForDisplay converts campaign product names to title case', () => { + assert.equal( + formatProductNameForDisplay('BASE LISA MOLETOM CANGURU COR PRETO'), + 'Base Lisa Moletom Canguru Cor Preto' + ); + assert.equal(formatProductNameForDisplay('BONÉ - BRANCO'), 'Boné - Branco'); +}); + test('mapCampaignProducts accumulates split deltas by base product', () => { const groups = groupCampaignRowsByBaseProduct([ row({ id: 1, delta_estoque: 10, produto_id: 'SKU-P', nome: 'Produto Split TAMANHO - P' }), @@ -70,7 +79,7 @@ test('buildWhatsappCampaignPayload combines multiple ready products into one mes ])); const payload = buildWhatsappCampaignPayload(products, [{ nome: 'Cliente', fone: '5511999999999' }]); - assert.equal(payload.productsText, 'BONÉ - PRETO e BASE LISA CAMISETA COR BRANCO'); + assert.equal(payload.productsText, 'Boné - Preto e Base Lisa Camiseta Cor Branco'); assert.equal(payload.baseProduct, payload.productsText); assert.equal(payload.total_delta, 200); assert.equal(payload.products.length, 2);