Add hourly detail charts for single-day ranges
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 46s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 46s
This commit is contained in:
@@ -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 () => {
|
||||
|
||||
Reference in New Issue
Block a user