Fix: resolve_offer_to_hub call in resolve_route_to_coordinate (same graphene self=None bug)
All checks were successful
Build Docker Image / build (push) Successful in 1m27s
All checks were successful
Build Docker Image / build (push) Successful in 1m27s
This commit is contained in:
@@ -1677,7 +1677,8 @@ class Query(graphene.ObjectType):
|
||||
logger.info("Found nearest hub %s to coordinates (%.3f, %.3f)", hub_uuid, lat, lon)
|
||||
|
||||
# Use existing offer_to_hub logic
|
||||
return self.resolve_offer_to_hub(info, offer_uuid, hub_uuid)
|
||||
# Note: in graphene, self is None (root value), so we call as class method
|
||||
return Query.resolve_offer_to_hub(Query, info, offer_uuid, hub_uuid)
|
||||
except Exception as e:
|
||||
logger.error("Error finding route to coordinates: %s", e)
|
||||
return None
|
||||
|
||||
Binary file not shown.
@@ -454,6 +454,176 @@ class TestNearestEndpoints:
|
||||
suppliers = data['data']['nearestSuppliers']
|
||||
print(f"✓ nearestSuppliers with product: {len(suppliers)} suppliers for product {product_uuid[:8]}")
|
||||
|
||||
def test_nearest_offers_with_hub_uuid(self):
|
||||
"""Test nearestOffers with hubUuid - should return offers with calculated routes.
|
||||
|
||||
This tests the fix for the bug where resolve_offer_to_hub was called incorrectly
|
||||
(self was None in graphene resolvers).
|
||||
"""
|
||||
# First, get a hub UUID from the database
|
||||
hubs_query = """
|
||||
query {
|
||||
nearestHubs(lat: 0, lon: 0, radius: 20000, limit: 5) {
|
||||
uuid
|
||||
name
|
||||
latitude
|
||||
longitude
|
||||
}
|
||||
}
|
||||
"""
|
||||
hubs_response = requests.post(GEO_URL, json={'query': hubs_query})
|
||||
hubs_data = hubs_response.json()
|
||||
|
||||
if not hubs_data.get('data', {}).get('nearestHubs'):
|
||||
pytest.skip("No hubs found in database")
|
||||
|
||||
hub = hubs_data['data']['nearestHubs'][0]
|
||||
hub_uuid = hub['uuid']
|
||||
hub_lat = hub['latitude']
|
||||
hub_lon = hub['longitude']
|
||||
|
||||
# Now test nearestOffers with this hub UUID
|
||||
query = """
|
||||
query NearestOffers($lat: Float!, $lon: Float!, $radius: Float, $hubUuid: String, $limit: Int) {
|
||||
nearestOffers(lat: $lat, lon: $lon, radius: $radius, hubUuid: $hubUuid, limit: $limit) {
|
||||
uuid
|
||||
productUuid
|
||||
productName
|
||||
supplierUuid
|
||||
supplierName
|
||||
latitude
|
||||
longitude
|
||||
pricePerUnit
|
||||
currency
|
||||
distanceKm
|
||||
routes {
|
||||
totalDistanceKm
|
||||
totalTimeSeconds
|
||||
stages {
|
||||
fromUuid
|
||||
fromName
|
||||
fromLat
|
||||
fromLon
|
||||
toUuid
|
||||
toName
|
||||
toLat
|
||||
toLon
|
||||
distanceKm
|
||||
travelTimeSeconds
|
||||
transportType
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
# Search around the hub location with large radius
|
||||
variables = {
|
||||
'lat': float(hub_lat) if hub_lat else 0.0,
|
||||
'lon': float(hub_lon) if hub_lon else 0.0,
|
||||
'radius': 5000, # 5000km radius to find offers
|
||||
'hubUuid': hub_uuid,
|
||||
'limit': 10
|
||||
}
|
||||
|
||||
response = requests.post(GEO_URL, json={'query': query, 'variables': variables})
|
||||
assert response.status_code == 200, f"Status: {response.status_code}, Body: {response.text}"
|
||||
|
||||
data = response.json()
|
||||
assert 'errors' not in data, f"GraphQL errors: {data.get('errors')}"
|
||||
|
||||
offers = data['data']['nearestOffers']
|
||||
assert isinstance(offers, list), "nearestOffers should return a list"
|
||||
|
||||
# The key assertion: with hubUuid, we should get offers with routes calculated
|
||||
# (This was the bug - resolve_offer_to_hub was failing silently)
|
||||
print(f"✓ nearestOffers with hubUuid: {len(offers)} offers for hub '{hub['name']}'")
|
||||
|
||||
if len(offers) > 0:
|
||||
# Check first offer structure
|
||||
offer = offers[0]
|
||||
assert 'uuid' in offer
|
||||
assert 'productUuid' in offer
|
||||
assert 'routes' in offer, "Offer should have routes field when hubUuid is provided"
|
||||
|
||||
# If routes exist, verify structure
|
||||
if offer['routes'] and len(offer['routes']) > 0:
|
||||
route = offer['routes'][0]
|
||||
assert 'totalDistanceKm' in route
|
||||
assert 'totalTimeSeconds' in route
|
||||
assert 'stages' in route
|
||||
|
||||
if route['stages'] and len(route['stages']) > 0:
|
||||
stage = route['stages'][0]
|
||||
assert 'fromUuid' in stage
|
||||
assert 'toUuid' in stage
|
||||
assert 'transportType' in stage
|
||||
assert 'distanceKm' in stage
|
||||
print(f" Route has {len(route['stages'])} stages, total {route['totalDistanceKm']:.1f}km")
|
||||
|
||||
def test_nearest_offers_with_hub_and_product(self):
|
||||
"""Test nearestOffers with both hubUuid and productUuid filters."""
|
||||
# Get a product and hub
|
||||
products_query = "query { products { uuid name } }"
|
||||
prod_response = requests.post(GEO_URL, json={'query': products_query})
|
||||
products = prod_response.json().get('data', {}).get('products', [])
|
||||
|
||||
hubs_query = """
|
||||
query {
|
||||
nearestHubs(lat: 0, lon: 0, radius: 20000, limit: 1) {
|
||||
uuid
|
||||
name
|
||||
latitude
|
||||
longitude
|
||||
}
|
||||
}
|
||||
"""
|
||||
hubs_response = requests.post(GEO_URL, json={'query': hubs_query})
|
||||
hubs = hubs_response.json().get('data', {}).get('nearestHubs', [])
|
||||
|
||||
if not products or not hubs:
|
||||
pytest.skip("No products or hubs in database")
|
||||
|
||||
product = products[0]
|
||||
hub = hubs[0]
|
||||
|
||||
query = """
|
||||
query NearestOffers($lat: Float!, $lon: Float!, $radius: Float, $productUuid: String, $hubUuid: String) {
|
||||
nearestOffers(lat: $lat, lon: $lon, radius: $radius, productUuid: $productUuid, hubUuid: $hubUuid) {
|
||||
uuid
|
||||
productUuid
|
||||
productName
|
||||
routes {
|
||||
totalDistanceKm
|
||||
stages {
|
||||
transportType
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
variables = {
|
||||
'lat': float(hub['latitude']) if hub['latitude'] else 0.0,
|
||||
'lon': float(hub['longitude']) if hub['longitude'] else 0.0,
|
||||
'radius': 10000,
|
||||
'productUuid': product['uuid'],
|
||||
'hubUuid': hub['uuid']
|
||||
}
|
||||
|
||||
response = requests.post(GEO_URL, json={'query': query, 'variables': variables})
|
||||
assert response.status_code == 200
|
||||
|
||||
data = response.json()
|
||||
assert 'errors' not in data, f"GraphQL errors: {data.get('errors')}"
|
||||
|
||||
offers = data['data']['nearestOffers']
|
||||
|
||||
# All offers should be for the requested product
|
||||
for offer in offers:
|
||||
assert offer['productUuid'] == product['uuid'], \
|
||||
f"Offer has wrong productUuid: {offer['productUuid']} != {product['uuid']}"
|
||||
|
||||
print(f"✓ nearestOffers with hub+product: {len(offers)} offers for '{product['name']}' via hub '{hub['name']}'")
|
||||
|
||||
|
||||
class TestRoutingEndpoints:
|
||||
"""Test routing and pathfinding endpoints."""
|
||||
|
||||
Reference in New Issue
Block a user