105 lines
3.7 KiB
Go
105 lines
3.7 KiB
Go
package tests
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// ResetAdminStat déplace le point de coupure temporel utilisé par toutes les
|
|
// requêtes de stats (TotalOrders, TotalRevenue, ActiveDaysLast30, ...) : les
|
|
// commandes créées AVANT le reset doivent disparaître des totaux, celles
|
|
// créées APRÈS doivent rester visibles. C'est le mécanisme central derrière
|
|
// le bouton "reset stats" de l'admin — jamais testé jusqu'ici.
|
|
|
|
const statsResetTestKey = "stats_reset_commandes_at"
|
|
|
|
func cleanupStatsResetKey(t *testing.T, key string) {
|
|
t.Helper()
|
|
t.Cleanup(func() {
|
|
testDB.GDB.Exec(`DELETE FROM app_settings WHERE key = ?`, key)
|
|
})
|
|
}
|
|
|
|
func TestResetAdminStat_TotalOrdersExcludesOrdersBeforeReset(t *testing.T) {
|
|
cleanupStockTestData(t)
|
|
cleanupStatsResetKey(t, statsResetTestKey)
|
|
username := newTestClient(t, "stat_reset_orders")
|
|
productID := newTestProduct(t, "StatResetOrders", 10)
|
|
|
|
newTestCommandWithItem(t, username, "pending", "", productID, 1, 10)
|
|
time.Sleep(1100 * time.Millisecond) // RFC3339 stocké sans fraction de seconde : marge nécessaire
|
|
|
|
if err := testDB.ResetAdminStat(statsResetTestKey); err != nil {
|
|
t.Fatalf("ResetAdminStat: %v", err)
|
|
}
|
|
time.Sleep(1100 * time.Millisecond)
|
|
|
|
newTestCommandWithItem(t, username, "pending", "", productID, 1, 10)
|
|
|
|
totalWithoutFilter, err := testDB.TotalOrders(time.Time{})
|
|
if err != nil {
|
|
t.Fatalf("TotalOrders(zero): %v", err)
|
|
}
|
|
if totalWithoutFilter != 2 {
|
|
t.Fatalf("précondition: 2 commandes doivent exister sans filtre: got=%d", totalWithoutFilter)
|
|
}
|
|
|
|
resetAt := testDB.ReadResetAt(statsResetTestKey)
|
|
if resetAt.IsZero() {
|
|
t.Fatal("ReadResetAt ne doit pas être zero après ResetAdminStat")
|
|
}
|
|
|
|
totalAfterReset, err := testDB.TotalOrders(resetAt)
|
|
if err != nil {
|
|
t.Fatalf("TotalOrders(resetAt): %v", err)
|
|
}
|
|
if totalAfterReset != 1 {
|
|
t.Errorf("après reset, seule la commande créée après doit être comptée: got=%d want=1", totalAfterReset)
|
|
}
|
|
}
|
|
|
|
// Chaque section de stats a sa propre clé de reset (commandes, revenus,
|
|
// produits, heures, jours, doses) — réinitialiser l'une ne doit jamais
|
|
// affecter les autres.
|
|
func TestResetAdminStat_DifferentSectionsAreIndependent(t *testing.T) {
|
|
cleanupStatsResetKey(t, "stats_reset_commandes_at_test_indep")
|
|
cleanupStatsResetKey(t, "stats_reset_revenus_at_test_indep")
|
|
|
|
if err := testDB.ResetAdminStat("stats_reset_commandes_at_test_indep"); err != nil {
|
|
t.Fatalf("ResetAdminStat (commandes): %v", err)
|
|
}
|
|
|
|
if got := testDB.ReadResetAt("stats_reset_revenus_at_test_indep"); !got.IsZero() {
|
|
t.Errorf("réinitialiser la section commandes ne doit pas créer de reset pour revenus: got=%v", got)
|
|
}
|
|
if got := testDB.ReadResetAt("stats_reset_commandes_at_test_indep"); got.IsZero() {
|
|
t.Error("la section commandes doit bien avoir une date de reset")
|
|
}
|
|
}
|
|
|
|
// ActiveDaysLast30 (stat secondaire) doit respecter le même filtre de reset
|
|
// que TotalOrders : un jour dont l'unique commande a été passée avant le
|
|
// reset ne doit plus compter comme jour actif.
|
|
func TestActiveDaysLast30_RespectsResetFilter(t *testing.T) {
|
|
cleanupStockTestData(t)
|
|
cleanupStatsResetKey(t, statsResetTestKey)
|
|
username := newTestClient(t, "stat_reset_active_days")
|
|
productID := newTestProduct(t, "StatResetActiveDays", 10)
|
|
|
|
newTestCommandWithItem(t, username, "pending", "", productID, 1, 10)
|
|
time.Sleep(1100 * time.Millisecond)
|
|
|
|
if err := testDB.ResetAdminStat(statsResetTestKey); err != nil {
|
|
t.Fatalf("ResetAdminStat: %v", err)
|
|
}
|
|
resetAt := testDB.ReadResetAt(statsResetTestKey)
|
|
|
|
activeDays, err := testDB.ActiveDaysLast30(resetAt)
|
|
if err != nil {
|
|
t.Fatalf("ActiveDaysLast30: %v", err)
|
|
}
|
|
if activeDays != 0 {
|
|
t.Errorf("aucun jour actif ne doit être compté (seule commande antérieure au reset): got=%d want=0", activeDays)
|
|
}
|
|
}
|