228 lines
7.8 KiB
Go
228 lines
7.8 KiB
Go
package tests
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
"testing"
|
|
)
|
|
|
|
// Adresses réalistes de Nantes (44000) utilisées pour vérifier que l'adresse
|
|
// de livraison survit intacte à la création puis à toutes les voies de
|
|
// récupération d'une commande (client, admin, livreur, historique).
|
|
var nantesAddresses = []string{
|
|
"12 Rue Crébillon, 44000 Nantes",
|
|
"3 Place Royale, 44000 Nantes",
|
|
"5 Cours des 50 Otages, 44000 Nantes",
|
|
"8 Rue de Verdun, 44000 Nantes",
|
|
}
|
|
|
|
// newTestCommandWithAddress crée directement une commande avec une adresse et
|
|
// un statut contrôlés (en contournant le checkout), pour tester isolément la
|
|
// récupération de l'adresse par les différentes fonctions de listing.
|
|
func newTestCommandWithAddress(t *testing.T, username, status, address, livreurAssign string, productID int, quantite, prix float64) int {
|
|
t.Helper()
|
|
var cmdID int
|
|
if err := testDB.GDB.Raw(
|
|
`INSERT INTO commandes (username, status, adresse, livreur_assign, total_prix, created_at, updated_at)
|
|
VALUES (?, ?, ?, NULLIF(?, ''), ?, NOW(), NOW()) RETURNING id`,
|
|
username, status, address, livreurAssign, prix,
|
|
).Scan(&cmdID).Error; err != nil {
|
|
t.Fatalf("création commande test avec adresse: %v", err)
|
|
}
|
|
if err := testDB.GDB.Exec(
|
|
`INSERT INTO command_items (command_id, product_id, produit, quantite, prix, status)
|
|
VALUES (?, ?, 'item test', ?, ?, 'pending')`,
|
|
cmdID, productID, quantite, prix,
|
|
).Error; err != nil {
|
|
t.Fatalf("création item test: %v", err)
|
|
}
|
|
return cmdID
|
|
}
|
|
|
|
// Le checkout réel (panier -> CreateCommandWithAddress) doit stocker l'adresse
|
|
// telle quelle, et GetCommandByID doit la restituer à l'identique.
|
|
func TestCreateCommandWithAddress_RoundTripsRealNantesAddress(t *testing.T) {
|
|
for _, address := range nantesAddresses {
|
|
t.Run(address, func(t *testing.T) {
|
|
cleanupStockTestData(t)
|
|
username := newTestClient(t, "addr_checkout")
|
|
productID := newTestProduct(t, "AddrCheckout", 10)
|
|
|
|
if _, err := testDB.AddToBasket(username, productID, 1); err != nil {
|
|
t.Fatalf("AddToBasket: %v", err)
|
|
}
|
|
cmd, err := testDB.CreateCommandWithAddress(username, address)
|
|
if err != nil {
|
|
t.Fatalf("CreateCommandWithAddress: %v", err)
|
|
}
|
|
|
|
command, err := testDB.GetCommandByID(cmd.ID)
|
|
if err != nil {
|
|
t.Fatalf("GetCommandByID: %v", err)
|
|
}
|
|
got, _ := command["adresse"].(string)
|
|
if got != address {
|
|
t.Errorf("adresse récupérée: got=%q want=%q", got, address)
|
|
}
|
|
if got == "" {
|
|
t.Error("l'adresse ne doit jamais être vide")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// Une adresse vide ou uniquement composée d'espaces doit être rejetée au
|
|
// checkout — pas de commande créée avec une adresse de livraison absente.
|
|
func TestCreateCommandWithAddress_RejectsEmptyOrBlankAddress(t *testing.T) {
|
|
for _, address := range []string{"", " ", "\t\n"} {
|
|
cleanupStockTestData(t)
|
|
username := newTestClient(t, "addr_blank")
|
|
productID := newTestProduct(t, "AddrBlank", 10)
|
|
|
|
if _, err := testDB.AddToBasket(username, productID, 1); err != nil {
|
|
t.Fatalf("AddToBasket: %v", err)
|
|
}
|
|
if _, err := testDB.CreateCommandWithAddress(username, address); err == nil {
|
|
t.Errorf("adresse %q aurait dû être rejetée", address)
|
|
}
|
|
|
|
var count int64
|
|
testDB.GDB.Raw(`SELECT COUNT(*) FROM commandes WHERE username = ?`, username).Scan(&count)
|
|
if count != 0 {
|
|
t.Errorf("aucune commande ne doit être créée avec une adresse %q: got=%d", address, count)
|
|
}
|
|
}
|
|
}
|
|
|
|
// GetAllCommands (vue admin) doit toujours renvoyer l'adresse de chaque
|
|
// commande, quel que soit son statut.
|
|
func TestGetAllCommands_AlwaysIncludesAddress(t *testing.T) {
|
|
cleanupStockTestData(t)
|
|
username := newTestClient(t, "addr_admin_list")
|
|
productID := newTestProduct(t, "AddrAdminList", 10)
|
|
|
|
want := map[int]string{}
|
|
for i, address := range nantesAddresses {
|
|
status := []string{"pending", "assigned", "en_route", "livre"}[i%4]
|
|
cmdID := newTestCommandWithAddress(t, username, status, address, "", productID, 1, 10)
|
|
want[cmdID] = address
|
|
}
|
|
|
|
commands, err := testDB.GetAllCommands("", username)
|
|
if err != nil {
|
|
t.Fatalf("GetAllCommands: %v", err)
|
|
}
|
|
if len(commands) != len(want) {
|
|
t.Fatalf("nombre de commandes: got=%d want=%d", len(commands), len(want))
|
|
}
|
|
for _, c := range commands {
|
|
id, _ := c["id"].(int)
|
|
address, _ := c["adresse"].(string)
|
|
if address == "" {
|
|
t.Errorf("commande %d: adresse vide", id)
|
|
}
|
|
if want[id] != address {
|
|
t.Errorf("commande %d: adresse=%q want=%q", id, address, want[id])
|
|
}
|
|
}
|
|
}
|
|
|
|
// GetDeliveryPersonCommands (vue livreur) doit inclure l'adresse de chaque
|
|
// commande qui lui est assignée.
|
|
func TestGetDeliveryPersonCommands_IncludesAddress(t *testing.T) {
|
|
cleanupStockTestData(t)
|
|
username := newTestClient(t, "addr_livreur_client")
|
|
productID := newTestProduct(t, "AddrLivreur", 10)
|
|
livreurUsername := testUserPrefix + "addr_livreur"
|
|
address := nantesAddresses[0]
|
|
|
|
cmdID := newTestCommandWithAddress(t, username, "assigned", address, livreurUsername, productID, 1, 10)
|
|
|
|
commands, err := testDB.GetDeliveryPersonCommands(livreurUsername, "")
|
|
if err != nil {
|
|
t.Fatalf("GetDeliveryPersonCommands: %v", err)
|
|
}
|
|
if len(commands) != 1 {
|
|
t.Fatalf("nombre de commandes assignées: got=%d want=1", len(commands))
|
|
}
|
|
got, _ := commands[0]["adresse"].(string)
|
|
if got != address {
|
|
t.Errorf("adresse: got=%q want=%q", got, address)
|
|
}
|
|
// Le type Go concret de la colonne "id" issue d'un Raw(...).Scan(&[]map[string]any)
|
|
// n'est pas garanti (int64 selon le driver) — même précaution que le code
|
|
// de production (ex: handlers/deleviry.go, fmt.Sprintf + strconv.Atoi).
|
|
id, _ := strconv.Atoi(fmt.Sprintf("%v", commands[0]["id"]))
|
|
if id != cmdID {
|
|
t.Errorf("id de commande inattendu: got=%d want=%d", id, cmdID)
|
|
}
|
|
}
|
|
|
|
// GetCancelledCommands doit inclure l'adresse même pour une commande annulée.
|
|
func TestGetCancelledCommands_IncludesAddress(t *testing.T) {
|
|
cleanupStockTestData(t)
|
|
username := newTestClient(t, "addr_cancelled")
|
|
productID := newTestProduct(t, "AddrCancelled", 10)
|
|
address := nantesAddresses[1]
|
|
|
|
newTestCommandWithAddress(t, username, "cancelled", address, "", productID, 1, 10)
|
|
|
|
commands, err := testDB.GetCancelledCommands(username, 10)
|
|
if err != nil {
|
|
t.Fatalf("GetCancelledCommands: %v", err)
|
|
}
|
|
if len(commands) != 1 {
|
|
t.Fatalf("nombre de commandes annulées: got=%d want=1", len(commands))
|
|
}
|
|
got, _ := commands[0]["adresse"].(string)
|
|
if got != address {
|
|
t.Errorf("adresse: got=%q want=%q", got, address)
|
|
}
|
|
}
|
|
|
|
// GetCompletedCommandsByUsername (historique client) doit inclure l'adresse
|
|
// des commandes terminées (approved).
|
|
func TestGetCompletedCommandsByUsername_IncludesAddress(t *testing.T) {
|
|
cleanupStockTestData(t)
|
|
username := newTestClient(t, "addr_history")
|
|
productID := newTestProduct(t, "AddrHistory", 10)
|
|
address := nantesAddresses[2]
|
|
|
|
newTestCommandWithAddress(t, username, "approved", address, "", productID, 1, 10)
|
|
|
|
commands, err := testDB.GetCompletedCommandsByUsername(username)
|
|
if err != nil {
|
|
t.Fatalf("GetCompletedCommandsByUsername: %v", err)
|
|
}
|
|
if len(commands) != 1 {
|
|
t.Fatalf("nombre de commandes terminées: got=%d want=1", len(commands))
|
|
}
|
|
got, _ := commands[0]["adresse"].(string)
|
|
if got != address {
|
|
t.Errorf("adresse: got=%q want=%q", got, address)
|
|
}
|
|
}
|
|
|
|
// GetAllCommandsOldestFirst (vue cabine/admin triée) doit également inclure
|
|
// l'adresse de chaque commande.
|
|
func TestGetAllCommandsOldestFirst_IncludesAddress(t *testing.T) {
|
|
cleanupStockTestData(t)
|
|
username := newTestClient(t, "addr_oldest_first")
|
|
productID := newTestProduct(t, "AddrOldestFirst", 10)
|
|
address := nantesAddresses[3]
|
|
|
|
newTestCommandWithAddress(t, username, "pending", address, "", productID, 1, 10)
|
|
|
|
commands, err := testDB.GetAllCommandsOldestFirst("", username)
|
|
if err != nil {
|
|
t.Fatalf("GetAllCommandsOldestFirst: %v", err)
|
|
}
|
|
if len(commands) != 1 {
|
|
t.Fatalf("nombre de commandes: got=%d want=1", len(commands))
|
|
}
|
|
got, _ := commands[0]["adresse"].(string)
|
|
if got != address {
|
|
t.Errorf("adresse: got=%q want=%q", got, address)
|
|
}
|
|
}
|