All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 2m40s
162 lines
6.0 KiB
JavaScript
162 lines
6.0 KiB
JavaScript
const test = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const {
|
|
buildWhatsappCampaignPayload,
|
|
formatProductList,
|
|
formatProductNameForDisplay,
|
|
groupCampaignRows,
|
|
groupCampaignRowsByBaseProduct,
|
|
isCampaignEligibleProductName,
|
|
mapCampaignProducts
|
|
} = require('../services/campaignFormatter');
|
|
|
|
const row = (overrides) => ({
|
|
id: 1,
|
|
base_product_name: 'BASE LISA CAMISETA COR BRANCO',
|
|
produto_id: 'SKU-1',
|
|
nome: 'BASE LISA CAMISETA COR BRANCO TAMANHO - P',
|
|
saldo: 10,
|
|
delta_estoque: 10,
|
|
status: 'pending',
|
|
attempts: 0,
|
|
last_error: null,
|
|
created_at: '2026-05-28T10:00:00.000Z',
|
|
updated_at: '2026-05-28T10:00:00.000Z',
|
|
sent_at: null,
|
|
...overrides
|
|
});
|
|
|
|
test('formatProductList uses inline bullet separators', () => {
|
|
assert.equal(formatProductList([]), '');
|
|
assert.equal(formatProductList(['BONÉ - PRETO']), 'Boné - Preto');
|
|
assert.equal(formatProductList(['BONÉ - PRETO', 'BASE BRANCA']), 'Boné - Preto • Base Branca');
|
|
assert.equal(
|
|
formatProductList(['BONÉ - PRETO', 'BASE BRANCA', 'BASE PRETA']),
|
|
'Boné - Preto • Base Branca • Base Preta'
|
|
);
|
|
});
|
|
|
|
test('formatProductNameForDisplay converts campaign product names to title case', () => {
|
|
assert.equal(
|
|
formatProductNameForDisplay('BASE LISA MOLETOM CANGURU COR PRETO'),
|
|
'Moletom Canguru Premium Cor Preto'
|
|
);
|
|
assert.equal(formatProductNameForDisplay('BONÉ - BRANCO'), 'Boné - Branco');
|
|
});
|
|
|
|
test('formatProductNameForDisplay applies customer-facing campaign aliases', () => {
|
|
assert.equal(
|
|
formatProductNameForDisplay('BASE LISA CAMISETA COR AZUL'),
|
|
'Camiseta Premium Cor Azul'
|
|
);
|
|
assert.equal(
|
|
formatProductNameForDisplay('BASE LISA OVER SIZE COR PRETO'),
|
|
'Camiseta Premium Over Size Cor Preto'
|
|
);
|
|
assert.equal(
|
|
formatProductNameForDisplay('BASE LISA MOLETOM CANGURU COR PRETO'),
|
|
'Moletom Canguru Premium Cor Preto'
|
|
);
|
|
});
|
|
|
|
test('isCampaignEligibleProductName allows only customer-facing apparel campaigns', () => {
|
|
[
|
|
'Camiseta Premium Cor Bordo',
|
|
'Camiseta Premium Cor Preto',
|
|
'Moletom Canguru Premium Cor Preto',
|
|
'IMPRESSÃO DTF PERSONALIZADO 57X100 (1 METRO)',
|
|
'BASE LISA CAMISETA COR PRETO TAMANHO - G',
|
|
'BASE LISA MOLETOM CANGURU COR PRETO'
|
|
].forEach(name => {
|
|
assert.equal(isCampaignEligibleProductName(name), true, name);
|
|
});
|
|
|
|
[
|
|
'Ilhos Com Arruela',
|
|
'Atacador 001 Chato Preto 1,20 Mt',
|
|
'2099 Ribana 2x1 Cor Bordo',
|
|
'2001.09 Ribana 2x1 Cor Cinza',
|
|
'2001.09 Malha Camiseta 30oe Cor Cinza',
|
|
'201 Malha Camiseta 30oe Cor Preto',
|
|
'4006 Malha Camiseta 30oe Cor Marinho',
|
|
'TINTA DTF 1 LITRO - BRANCO',
|
|
'FILME DTF ROLO 60CM',
|
|
'POLIAMIDA EM PÓ PARA DTF - 1 KG',
|
|
'SALDO ESTOQUE CAMISETA'
|
|
].forEach(name => {
|
|
assert.equal(isCampaignEligibleProductName(name), false, name);
|
|
});
|
|
});
|
|
|
|
test('isCampaignEligibleProductName keeps accessories out of WhatsApp apparel campaigns', () => {
|
|
assert.equal(isCampaignEligibleProductName('BONÉ - PRETO'), false);
|
|
});
|
|
|
|
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' }),
|
|
row({ id: 2, delta_estoque: 50, produto_id: 'SKU-M', nome: 'Produto Split TAMANHO - M' }),
|
|
row({ id: 3, delta_estoque: 40, produto_id: 'SKU-G', nome: 'Produto Split TAMANHO - G' })
|
|
]);
|
|
|
|
const products = mapCampaignProducts(groups);
|
|
|
|
assert.equal(products.length, 1);
|
|
assert.equal(products[0].total_delta, 100);
|
|
assert.deepEqual(products[0].itemIds, [3, 2, 1]);
|
|
assert.deepEqual(products[0].sizes.map(size => size.id), ['SKU-G', 'SKU-M', 'SKU-P']);
|
|
});
|
|
|
|
test('buildWhatsappCampaignPayload combines multiple ready products into one message payload', () => {
|
|
const products = mapCampaignProducts(groupCampaignRowsByBaseProduct([
|
|
row({
|
|
id: 1,
|
|
base_product_name: 'BONÉ - PRETO',
|
|
produto_id: 'BONE-P',
|
|
nome: 'BONÉ - PRETO TAMANHO - P',
|
|
delta_estoque: 100,
|
|
created_at: '2026-05-28T10:00:00.000Z'
|
|
}),
|
|
row({
|
|
id: 2,
|
|
base_product_name: 'BASE LISA CAMISETA COR BRANCO',
|
|
produto_id: 'BASE-P',
|
|
nome: 'BASE LISA CAMISETA COR BRANCO TAMANHO - P',
|
|
delta_estoque: 100,
|
|
created_at: '2026-05-28T11:00:00.000Z'
|
|
})
|
|
]));
|
|
const payload = buildWhatsappCampaignPayload(products, [{ nome: 'Cliente', fone: '5511999999999' }]);
|
|
|
|
assert.equal(payload.productsText, 'Boné - Preto • Camiseta Premium Cor Branco');
|
|
assert.equal(payload.baseProduct, payload.productsText);
|
|
assert.equal(payload.total_delta, 200);
|
|
assert.equal(payload.products.length, 2);
|
|
assert.equal(payload.sizes.length, 2);
|
|
assert.deepEqual(Object.keys(payload.products[0]).includes('itemIds'), false);
|
|
});
|
|
|
|
test('groupCampaignRows summarizes rows by base product and status', () => {
|
|
const groups = groupCampaignRows([
|
|
row({ id: 1, delta_estoque: 60, attempts: 1, updated_at: '2026-05-28T10:00:00.000Z' }),
|
|
row({ id: 2, delta_estoque: 40, attempts: 2, updated_at: '2026-05-28T10:05:00.000Z' }),
|
|
row({
|
|
id: 3,
|
|
base_product_name: 'BONÉ - PRETO',
|
|
status: 'failed',
|
|
delta_estoque: 100,
|
|
attempts: 3,
|
|
last_error: 'Webhook failed',
|
|
updated_at: '2026-05-28T11:00:00.000Z'
|
|
})
|
|
]);
|
|
|
|
assert.equal(groups.length, 2);
|
|
assert.equal(groups[0].baseProductName, 'BONÉ - PRETO');
|
|
assert.equal(groups[0].lastError, 'Webhook failed');
|
|
assert.equal(groups[1].baseProductName, 'BASE LISA CAMISETA COR BRANCO');
|
|
assert.equal(groups[1].totalDelta, 100);
|
|
assert.equal(groups[1].rowCount, 2);
|
|
assert.equal(groups[1].attempts, 2);
|
|
});
|