package controllers import ( "encoding/json" "testing" "doormile/models" ) // A hub's city is derived, not stored. `hubs` carries only `applocationid`, and // for as long as the response carried that and nothing else, every console // screen that asked a hub what city it was in got undefined: // // - ZoneContext.matchesZone compares an order's address text against the // hub's city. An empty city makes that comparison unreachable, so the only // matcher left was a 35km radius — and an order stored without coordinates // then belonged to no zone at all. // - fetchAppLocations names each city `hub.city || hub.hubname`, so the // Pricing and report pickers offered "Coimbatore Jupiter Hub" where they // meant "Coimbatore". func TestApplyHubCities(t *testing.T) { locations := map[int]string{1: "Coimbatore", 3: "Bangalore"} t.Run("resolves each hub against its applocation", func(t *testing.T) { hubs := []models.Hub{ {Hubid: 1, Hubname: "Coimbatore Jupiter Hub", Applocationid: 1}, {Hubid: 5, Hubname: "Bangalore Earth Hub", Applocationid: 3}, } applyHubCities(hubs, locations) if hubs[0].City != "Coimbatore" || hubs[1].City != "Bangalore" { t.Fatalf("got %q and %q", hubs[0].City, hubs[1].City) } }) t.Run("an unknown applocation leaves the city empty, not guessed", func(t *testing.T) { // Empty is the honest answer and callers already read it as "unknown": // ZoneContext skips its city comparison rather than matching everything. hubs := []models.Hub{{Hubid: 99, Hubname: "Somewhere Hub", Applocationid: 42}} applyHubCities(hubs, locations) if hubs[0].City != "" { t.Fatalf("expected empty city, got %q", hubs[0].City) } }) t.Run("a hub with no applocation at all is left alone", func(t *testing.T) { hubs := []models.Hub{{Hubid: 98, Hubname: "Orphan Hub"}} applyHubCities(hubs, locations) if hubs[0].City != "" { t.Fatalf("expected empty city, got %q", hubs[0].City) } }) t.Run("the city follows the applocation, never the name", func(t *testing.T) { // Hub 22 is a live example of why this is worth asserting: it is named // "Chennai Comet Hub" but sits on applocationid 1, because CreateCityHub // copies the creating staff member's location. hubs := []models.Hub{{Hubid: 22, Hubname: "Chennai Comet Hub", Applocationid: 1}} applyHubCities(hubs, locations) if hubs[0].City != "Coimbatore" { t.Fatalf("city must come from applocationid, got %q", hubs[0].City) } }) t.Run("an empty list is not an error", func(t *testing.T) { applyHubCities(nil, locations) applyHubCities([]models.Hub{}, locations) }) } // The field has to survive JSON encoding, since the console reads `hub.city`. // `gorm:"-"` keeps it out of the SQL; it must not also keep it out of the body. func TestHubCityIsSerialised(t *testing.T) { b, err := json.Marshal(models.Hub{Hubid: 5, Hubname: "Bangalore Earth Hub", City: "Bangalore"}) if err != nil { t.Fatal(err) } var back map[string]any if err := json.Unmarshal(b, &back); err != nil { t.Fatal(err) } if back["city"] != "Bangalore" { t.Fatalf("city missing from the hub response: %s", b) } }