chore: build
Backend - Build & Lint / build (push) Successful in 32m22s

This commit is contained in:
Xor290
2026-09-27 12:30:20 +02:00
parent d8ad16b40e
commit f371cd0874
2 changed files with 126 additions and 1 deletions
+19 -1
View File
@@ -290,11 +290,16 @@ func RespondToAddressProposal(c *gin.Context) {
// La colonne proposed_address est vidée par RespondToAddressProposal dès // La colonne proposed_address est vidée par RespondToAddressProposal dès
// qu'elle est traitée : on la lit avant l'appel pour pouvoir regéocoder la // qu'elle est traitée : on la lit avant l'appel pour pouvoir regéocoder la
// nouvelle adresse en cas d'acceptation. // nouvelle adresse en cas d'acceptation. On récupère aussi le livreur
// assigné : ProposeAddressChange autorise un changement d'adresse même en
// "en_route" (voir commands.go ~L236-240), donc un livreur peut déjà être
// en train de rouler vers l'ancienne adresse au moment de l'acceptation.
var proposedAddress string var proposedAddress string
var livreurAssign string
if req.Accepted { if req.Accepted {
if command, err := database.GetCommandByID(commandID); err == nil { if command, err := database.GetCommandByID(commandID); err == nil {
proposedAddress, _ = command["proposed_address"].(string) proposedAddress, _ = command["proposed_address"].(string)
livreurAssign, _ = command["livreur_assign"].(string)
} }
} }
@@ -305,6 +310,19 @@ func RespondToAddressProposal(c *gin.Context) {
if req.Accepted && proposedAddress != "" { if req.Accepted && proposedAddress != "" {
updateCommandDestinationCoords(database, geoService, commandID, proposedAddress) updateCommandDestinationCoords(database, geoService, commandID, proposedAddress)
// L'ETA en cache correspond au trajet vers l'ancienne destination —
// on l'invalide pour forcer un recalcul sur les nouvelles coordonnées.
db.Redis.Del(db.RedisCtx, fmt.Sprintf("command:eta:%d", commandID))
// Sans cette notification, le livreur déjà en route continuerait à
// naviguer vers l'ancienne adresse sans savoir que la destination a
// changé en base.
if livreurAssign != "" {
clientOrderID := database.GetClientOrderID(commandID)
livreurMsg := fmt.Sprintf("⚠️ Le client a changé l'adresse de livraison de la commande #%d : %s. Merci de mettre à jour votre itinéraire.", clientOrderID, proposedAddress)
database.NotifyLivreur(livreurAssign, commandID, "address_changed", livreurMsg)
}
} }
action := "refusée" action := "refusée"
@@ -0,0 +1,107 @@
package tests
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"testing"
"gestion/db"
"gestion/handlers"
"github.com/gin-gonic/gin"
)
// Si le livreur est déjà en route quand le client accepte une proposition
// d'adresse (ProposeAddressChange autorise ce cas même en "en_route" — voir
// commands.go ~L236-240), il doit être notifié que la destination a changé,
// sans quoi il continuerait à naviguer vers l'ancienne adresse alors que la
// nouvelle est déjà enregistrée en base (voir RespondToAddressProposal).
func TestRespondToAddressProposal_NotifiesLivreurWhenAlreadyEnRoute(t *testing.T) {
if testing.Short() {
t.Skip("appelle le vrai service Nominatim en réseau — sauté en mode -short")
}
cleanupStockTestData(t)
username := newTestClient(t, "respond_addr_notif_client")
livreur := newTestClient(t, "respond_addr_notif_livreur")
productID := newTestProduct(t, "RespondAddrNotif", 10)
cmdID := newTestCommandWithItem(t, username, "en_route", livreur, productID, 1, 10)
if err := testDB.ProposeAddressChange(cmdID, "12 rue Crebillon, 44000 Nantes", "admin_test"); err != nil {
t.Fatalf("ProposeAddressChange: %v", err)
}
notifKey := fmt.Sprintf("notifications:%s", livreur)
db.Redis.Del(db.RedisCtx, notifKey)
body := []byte(`{"accepted":true}`)
req := httptest.NewRequest(http.MethodPost, "/api/v1/commands/address/respond", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
rec := httptest.NewRecorder()
c, _ := gin.CreateTestContext(rec)
c.Request = req
c.Set("database", testDB)
c.Set("geoService", ensureTestGeoService())
c.Set("username", username)
c.Set("role", "client")
c.Params = gin.Params{{Key: "id", Value: fmt.Sprintf("%d", cmdID)}}
handlers.RespondToAddressProposal(c)
if rec.Code != http.StatusOK {
t.Fatalf("RespondToAddressProposal doit réussir: got=%d body=%s", rec.Code, rec.Body.String())
}
entries, err := db.Redis.LRange(db.RedisCtx, notifKey, 0, -1).Result()
if err != nil {
t.Fatalf("lecture notifications livreur: %v", err)
}
var found bool
for _, raw := range entries {
var notif struct {
CommandID int `json:"command_id"`
Type string `json:"type"`
}
if err := json.Unmarshal([]byte(raw), &notif); err == nil && notif.CommandID == cmdID && notif.Type == "address_changed" {
found = true
break
}
}
if !found {
t.Errorf("le livreur déjà en route doit être notifié du changement d'adresse (type=address_changed, command_id=%d): notifications=%v", cmdID, entries)
}
}
// Si aucun livreur n'est assigné, il ne doit évidemment pas y avoir de
// notification livreur envoyée (pas de panique/erreur non plus).
func TestRespondToAddressProposal_NoLivreurNotificationWhenNoneAssigned(t *testing.T) {
if testing.Short() {
t.Skip("appelle le vrai service Nominatim en réseau — sauté en mode -short")
}
cleanupStockTestData(t)
username := newTestClient(t, "respond_addr_notif_nolivreur")
productID := newTestProduct(t, "RespondAddrNotifNoLivreur", 10)
cmdID := newTestCommandWithItem(t, username, "pending", "", productID, 1, 10)
if err := testDB.ProposeAddressChange(cmdID, "12 rue Crebillon, 44000 Nantes", "admin_test"); err != nil {
t.Fatalf("ProposeAddressChange: %v", err)
}
body := []byte(`{"accepted":true}`)
req := httptest.NewRequest(http.MethodPost, "/api/v1/commands/address/respond", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
rec := httptest.NewRecorder()
c, _ := gin.CreateTestContext(rec)
c.Request = req
c.Set("database", testDB)
c.Set("geoService", ensureTestGeoService())
c.Set("username", username)
c.Set("role", "client")
c.Params = gin.Params{{Key: "id", Value: fmt.Sprintf("%d", cmdID)}}
handlers.RespondToAddressProposal(c)
if rec.Code != http.StatusOK {
t.Fatalf("RespondToAddressProposal doit réussir: got=%d body=%s", rec.Code, rec.Body.String())
}
}