updates on the api endpoints on the customer page and more
This commit is contained in:
137
controllers/logisticsRouting_test.go
Normal file
137
controllers/logisticsRouting_test.go
Normal file
@@ -0,0 +1,137 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"doormile/constants"
|
||||
)
|
||||
|
||||
// The bulk-upload test sheet, checked against the rule that actually decides.
|
||||
//
|
||||
// krow_talent_app/tests/fixtures/doormile-logistics-test.xlsx carries 16 rows
|
||||
// and an "Expected Routing" column saying, in words, what each one should do.
|
||||
// That column is only a claim until something checks it, and the thing that
|
||||
// decides is here, in Go — so it is checked here rather than restated in a
|
||||
// JavaScript test, which would only prove that two copies of the rule agree
|
||||
// with each other.
|
||||
//
|
||||
// If a row of the sheet is edited, this table is what says whether the sheet is
|
||||
// still testing what it says it tests.
|
||||
//
|
||||
// Pickup is the sheet's single sender: Jayanthi's kitchen, Edayarpalayam,
|
||||
// Coimbatore 641025.
|
||||
const (
|
||||
sheetPickupPincode = "641025"
|
||||
sheetPickupLat = 11.0168
|
||||
sheetPickupLng = 76.9558
|
||||
)
|
||||
|
||||
func TestBulkTestSheetRoutesAsDocumented(t *testing.T) {
|
||||
cases := []struct {
|
||||
row int
|
||||
receiver string
|
||||
pincode string
|
||||
lat, lng float64
|
||||
wantLocal bool
|
||||
wantAction string
|
||||
wantConsStat string // with the hub-handover flow ON
|
||||
why string
|
||||
}{
|
||||
// Customer -> Base. A different postal area, so the parcel cannot be
|
||||
// carried to the receiver by the collecting rider.
|
||||
{1, "Suresh Kumar", "600001", 13.091, 80.285, false, constants.NextActionInwardAtHub, constants.ConsignmentCreated, "641 -> 600, Chennai"},
|
||||
{2, "Priya Raghavan", "600028", 13.018, 80.256, false, constants.NextActionInwardAtHub, constants.ConsignmentCreated, "641 -> 600, Chennai"},
|
||||
{3, "Anil Reddy", "500081", 17.44, 78.3489, false, constants.NextActionInwardAtHub, constants.ConsignmentCreated, "interstate, Hyderabad"},
|
||||
{4, "Meera Krishnan", "500032", 17.4156, 78.3378, false, constants.NextActionInwardAtHub, constants.ConsignmentCreated, "interstate with COD"},
|
||||
{5, "Rahul Menon", "560001", 12.975, 77.606, false, constants.NextActionInwardAtHub, constants.ConsignmentCreated, "interstate, Bengaluru"},
|
||||
{6, "Divya Nair", "560066", 12.9698, 77.75, false, constants.NextActionInwardAtHub, constants.ConsignmentCreated, "interstate with COD"},
|
||||
{7, "Karthik Subramani", "625001", 9.9195, 78.119, false, constants.NextActionInwardAtHub, constants.ConsignmentCreated, "same state, different area"},
|
||||
{8, "Lakshmi Devi", "636001", 11.664, 78.146, false, constants.NextActionInwardAtHub, constants.ConsignmentCreated, "same state, different area"},
|
||||
|
||||
// Customer -> Customer. The control group: if any of these routes to a
|
||||
// base, the prefix rule has broken.
|
||||
{9, "Ganesh Iyer", "641004", 11.029, 76.993, true, constants.NextActionDeliver, constants.ConsignmentOutForDelivery, "same 641 area"},
|
||||
{10, "Revathi Balaji", "641012", 11.018, 76.966, true, constants.NextActionDeliver, constants.ConsignmentOutForDelivery, "same 641 area, COD"},
|
||||
{11, "Vignesh Murugan", "641025", 11.008, 76.928, true, constants.NextActionDeliver, constants.ConsignmentOutForDelivery, "identical pincode"},
|
||||
{12, "Anitha Selvam", "641038", 11.023, 76.945, true, constants.NextActionDeliver, constants.ConsignmentOutForDelivery, "same 641 area"},
|
||||
|
||||
// No pincode: the decision falls to straight-line distance. Both
|
||||
// outcomes are present, because a fallback that only ever answers one
|
||||
// way is not being tested.
|
||||
{13, "Mohan Das", "", 11.05, 77.01, true, constants.NextActionDeliver, constants.ConsignmentOutForDelivery, "~8km, inside the 30km fallback"},
|
||||
{14, "Sridhar Venkat", "", 13.0827, 80.2707, false, constants.NextActionInwardAtHub, constants.ConsignmentCreated, "~430km, far outside the fallback"},
|
||||
{15, "Bhavani Shankar", "64", 13.06, 80.24, false, constants.NextActionInwardAtHub, constants.ConsignmentCreated, "2-digit pincode is unusable, distance decides"},
|
||||
|
||||
// The row that proves the prefix rule outranks distance.
|
||||
{16, "Ramesh Palanisamy", "642001", 10.658, 77.008, false, constants.NextActionInwardAtHub, constants.ConsignmentCreated, "~40km but 642 is a different area"},
|
||||
}
|
||||
|
||||
if len(cases) != 16 {
|
||||
t.Fatalf("the sheet has 16 rows, this table has %d — they must not drift apart", len(cases))
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.receiver, func(t *testing.T) {
|
||||
gotLocal := isHyperlocalBooking(
|
||||
sheetPickupPincode, tc.pincode,
|
||||
sheetPickupLat, sheetPickupLng,
|
||||
tc.lat, tc.lng,
|
||||
)
|
||||
if gotLocal != tc.wantLocal {
|
||||
t.Fatalf("row %d (%s): hyperlocal = %v, want %v — %s",
|
||||
tc.row, tc.receiver, gotLocal, tc.wantLocal, tc.why)
|
||||
}
|
||||
|
||||
// What the rider is actually told to do with it, from the same
|
||||
// helper pickup-complete and the queue read both use.
|
||||
status := constants.ConsignmentCreated
|
||||
if gotLocal {
|
||||
status = constants.ConsignmentOutForDelivery
|
||||
}
|
||||
if status != tc.wantConsStat {
|
||||
t.Errorf("row %d: consignment state %s, want %s", tc.row, status, tc.wantConsStat)
|
||||
}
|
||||
if got := nextActionForConsignment(status); got != tc.wantAction {
|
||||
t.Errorf("row %d: next_action %s, want %s", tc.row, got, tc.wantAction)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// The sheet is only worth uploading if it actually splits both ways. A file
|
||||
// that turned out to be all-hyperlocal would pass every assertion above and
|
||||
// still test nothing — which is exactly the problem with the tenant's own
|
||||
// export that this sheet was written to replace.
|
||||
func TestBulkTestSheetExercisesBothLegs(t *testing.T) {
|
||||
type dest struct {
|
||||
pincode string
|
||||
lat, lng float64
|
||||
}
|
||||
dests := []dest{
|
||||
{"600001", 13.091, 80.285}, {"600028", 13.018, 80.256},
|
||||
{"500081", 17.44, 78.3489}, {"500032", 17.4156, 78.3378},
|
||||
{"560001", 12.975, 77.606}, {"560066", 12.9698, 77.75},
|
||||
{"625001", 9.9195, 78.119}, {"636001", 11.664, 78.146},
|
||||
{"641004", 11.029, 76.993}, {"641012", 11.018, 76.966},
|
||||
{"641025", 11.008, 76.928}, {"641038", 11.023, 76.945},
|
||||
{"", 11.05, 77.01}, {"", 13.0827, 80.2707},
|
||||
{"64", 13.06, 80.24}, {"642001", 10.658, 77.008},
|
||||
}
|
||||
|
||||
var local, hub int
|
||||
for _, d := range dests {
|
||||
if isHyperlocalBooking(sheetPickupPincode, d.pincode, sheetPickupLat, sheetPickupLng, d.lat, d.lng) {
|
||||
local++
|
||||
} else {
|
||||
hub++
|
||||
}
|
||||
}
|
||||
|
||||
if hub < 5 {
|
||||
t.Errorf("only %d rows route through a base — too few to exercise the handover flow", hub)
|
||||
}
|
||||
if local < 3 {
|
||||
t.Errorf("only %d rows go direct to the customer — no control group", local)
|
||||
}
|
||||
t.Logf("sheet splits %d base-handover / %d direct-to-customer", hub, local)
|
||||
}
|
||||
Reference in New Issue
Block a user