Add hourly detail charts for single-day ranges
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 46s

This commit is contained in:
Cauê Faleiros
2026-06-30 14:51:44 -03:00
parent 6a414a5bf4
commit ae7736019f
4 changed files with 178 additions and 20 deletions

View File

@@ -604,6 +604,42 @@ test('getProductDetailsAnalytics keeps known products visible with zero period s
}
});
test('getProductDetailsAnalytics groups single-day chart by hour', async () => {
const originalQuery = pool.query;
pool.query = async (sql) => {
if (sql.includes('selected_product AS')) {
return {
rows: [{
id: '919483307',
name: 'Produto com venda por hora',
price: 11.9
}]
};
}
assert.match(sql, /EXTRACT\(HOUR FROM created_at AT TIME ZONE 'America\/Sao_Paulo'\)::int as hour/);
return {
rows: [
{ hour: 9, quantity_sold: 2, revenue: 23.8 },
{ hour: 18, quantity_sold: 3, revenue: 35.7 }
]
};
};
try {
const details = await getProductDetailsAnalytics('919483307', { start: '2026-06-22', end: '2026-06-22' });
assert.equal(details.chartData.length, 24);
assert.deepEqual(details.chartData[9], { date: '09h', value: 2 });
assert.deepEqual(details.chartData[18], { date: '18h', value: 3 });
assert.equal(details.totalSold, 5);
assert.equal(details.totalRevenue, 59.5);
} finally {
pool.query = originalQuery;
}
});
test('getClientAnalytics returns opaque client tokens', async () => {
const originalQuery = pool.query;
const calls = [];
@@ -845,6 +881,74 @@ test('getClientDetailsAnalytics resolves legacy name tokens to the canonical pho
}
});
test('getClientDetailsAnalytics groups single-day spend chart by hour', async () => {
const originalQuery = pool.query;
const clientToken = createClientToken('(16) 99999-9999');
pool.query = async (sql, params = []) => {
if (sql.includes('FROM client_identity_tokens')) {
return { rows: [{ customer_key: '(16) 99999-9999' }] };
}
if (sql.includes('SELECT customer_key') && sql.includes('FROM identity_orders')) {
return { rows: [{ customer_key: '(16) 99999-9999' }] };
}
if (sql.includes('all_time_order_count')) {
return {
rows: [{
name: 'Cliente Teste',
phone: '(16) 99999-9999',
all_time_order_count: 2
}]
};
}
assert.deepEqual(params[0], '(16) 99999-9999');
return {
rows: [
{
cliente_nome: 'Cliente Teste',
cliente_fone: '(16) 99999-9999',
data_pedido: '22-06-2026',
data_pedido_date: '2026-06-22',
valor_pedido: 20,
produto_id: 'produto-1',
produto_descricao: 'Produto A',
quantidade: 2,
valor_unitario: 10,
pedido_id: 'pedido-1',
created_at: '2026-06-22T09:15:00.000-03:00'
},
{
cliente_nome: 'Cliente Teste',
cliente_fone: '(16) 99999-9999',
data_pedido: '22-06-2026',
data_pedido_date: '2026-06-22',
valor_pedido: 30,
produto_id: 'produto-2',
produto_descricao: 'Produto B',
quantidade: 1,
valor_unitario: 30,
pedido_id: 'pedido-2',
created_at: '2026-06-22T18:30:00.000-03:00'
}
]
};
};
try {
const details = await getClientDetailsAnalytics(clientToken, { start: '2026-06-22', end: '2026-06-22' });
assert.equal(details.chartData.length, 24);
assert.deepEqual(details.chartData[9], { date: '09h', value: 20 });
assert.deepEqual(details.chartData[18], { date: '18h', value: 30 });
assert.equal(details.periodSpent, 50);
} finally {
pool.query = originalQuery;
}
});
test('getClientDetailsAnalytics rejects invalid client tokens before querying', async () => {
const originalQuery = pool.query;
pool.query = async () => {