FarmerHelp / backend /tests /test_mandi_api.py
Gankit12's picture
All Code
b64de39
Raw
History Blame Contribute Delete
9.37 kB
"""
Unit tests for the Mandi Price API endpoints.
Test data is seeded via conftest.py:
- 3 Wheat records (Azadpur, Khanna, Karnal) + 2 older Azadpur records
- 2 Rice records (Azadpur, Khanna)
- 1 Onion record (Lasalgaon)
"""
import pytest
class TestMandiHealth:
"""Tests for GET /api/mandi/health"""
def test_health(self, client):
resp = client.get("/api/mandi/health")
assert resp.status_code == 200
body = resp.json()
assert body["status"] == "healthy"
class TestMandiCommodities:
"""Tests for GET /api/mandi/commodities"""
def test_list_commodities(self, client):
resp = client.get("/api/mandi/commodities")
assert resp.status_code == 200
body = resp.json()
assert body["total"] >= 3
names = [c["commodity"] for c in body["commodities"]]
assert "Wheat" in names
assert "Rice" in names
assert "Onion" in names
def test_commodity_fields(self, client):
resp = client.get("/api/mandi/commodities")
body = resp.json()
for c in body["commodities"]:
assert "commodity" in c
assert "record_count" in c
assert "avg_price_per_quintal" in c
assert "min_price_per_quintal" in c
assert "max_price_per_quintal" in c
assert "mandi_count" in c
class TestMandiPrices:
"""Tests for GET /api/mandi/prices"""
def test_all_prices(self, client):
resp = client.get("/api/mandi/prices")
assert resp.status_code == 200
body = resp.json()
assert body["total"] >= 8
assert "prices" in body
def test_filter_by_commodity(self, client):
resp = client.get("/api/mandi/prices?commodity=Wheat")
assert resp.status_code == 200
body = resp.json()
assert body["total"] >= 3
for p in body["prices"]:
assert p["commodity"].lower() == "wheat"
def test_filter_by_state(self, client):
resp = client.get("/api/mandi/prices?state=Punjab")
assert resp.status_code == 200
body = resp.json()
for p in body["prices"]:
assert p["state"].lower() == "punjab"
def test_filter_by_commodity_and_state(self, client):
resp = client.get("/api/mandi/prices?commodity=Wheat&state=Delhi")
assert resp.status_code == 200
body = resp.json()
for p in body["prices"]:
assert p["commodity"].lower() == "wheat"
assert p["state"].lower() == "delhi"
def test_filter_by_price_range(self, client):
resp = client.get("/api/mandi/prices?min_price=2000&max_price=2500")
assert resp.status_code == 200
body = resp.json()
for p in body["prices"]:
assert p["price_per_quintal"] >= 2000
assert p["price_per_quintal"] <= 2500
def test_pagination(self, client):
resp = client.get("/api/mandi/prices?limit=2&offset=0")
assert resp.status_code == 200
body = resp.json()
assert len(body["prices"]) <= 2
assert body["limit"] == 2
assert body["offset"] == 0
def test_no_results(self, client):
resp = client.get("/api/mandi/prices?commodity=Saffron")
assert resp.status_code == 200
body = resp.json()
assert body["total"] == 0
assert body["prices"] == []
def test_price_fields(self, client):
resp = client.get("/api/mandi/prices?limit=1")
body = resp.json()
if body["prices"]:
p = body["prices"][0]
assert "id" in p
assert "commodity" in p
assert "mandi_name" in p
assert "state" in p
assert "price_per_quintal" in p
assert "arrival_date" in p
class TestMandiCompare:
"""Tests for GET /api/mandi/compare"""
def test_compare_wheat(self, client):
resp = client.get("/api/mandi/compare?commodity=Wheat")
assert resp.status_code == 200
body = resp.json()
assert body["commodity"] == "Wheat"
assert body["total_mandis"] >= 2
assert "mandis" in body
assert "analytics" in body
def test_compare_analytics_fields(self, client):
resp = client.get("/api/mandi/compare?commodity=Wheat")
body = resp.json()
analytics = body["analytics"]
assert "average_price" in analytics
assert "price_range" in analytics
assert "price_spread" in analytics
assert "best_mandi" in analytics
assert "worst_mandi" in analytics
def test_compare_specific_mandis(self, client):
resp = client.get(
"/api/mandi/compare?commodity=Wheat&mandis=Azadpur Mandi,Khanna Mandi"
)
assert resp.status_code == 200
body = resp.json()
assert body["total_mandis"] == 2
def test_compare_with_state_filter(self, client):
resp = client.get("/api/mandi/compare?commodity=Wheat&state=Delhi")
assert resp.status_code == 200
body = resp.json()
for m in body["mandis"]:
assert m["state"].lower() == "delhi"
def test_compare_no_results(self, client):
resp = client.get("/api/mandi/compare?commodity=Saffron")
assert resp.status_code == 200
body = resp.json()
assert body["total_mandis"] == 0
assert body["analytics"] is None
class TestMandiBest:
"""Tests for GET /api/mandi/best"""
def test_best_mandi_no_location(self, client):
resp = client.get("/api/mandi/best?commodity=Wheat")
assert resp.status_code == 200
body = resp.json()
assert body["commodity"] == "Wheat"
assert body["total_mandis"] >= 2
assert "recommendations" in body
def test_best_mandi_with_location(self, client):
resp = client.get(
"/api/mandi/best?commodity=Wheat"
"&latitude=28.7&longitude=77.1&max_distance_km=500"
)
assert resp.status_code == 200
body = resp.json()
assert body["user_location"] is not None
for rec in body["recommendations"]:
assert "distance_km" in rec
assert "transport_cost_per_quintal" in rec
assert "net_price_per_quintal" in rec
assert rec["rank"] >= 1
def test_best_mandi_ranking_order(self, client):
resp = client.get("/api/mandi/best?commodity=Wheat")
body = resp.json()
recs = body["recommendations"]
if len(recs) >= 2:
for i in range(len(recs) - 1):
assert (
recs[i]["net_price_per_quintal"]
>= recs[i + 1]["net_price_per_quintal"]
)
def test_best_mandi_no_results(self, client):
resp = client.get("/api/mandi/best?commodity=Saffron")
assert resp.status_code == 200
body = resp.json()
assert body["total_mandis"] == 0
class TestMandiTrends:
"""Tests for GET /api/mandi/trends"""
def test_trends_wheat(self, client):
resp = client.get("/api/mandi/trends?commodity=Wheat&days=30")
assert resp.status_code == 200
body = resp.json()
assert body["commodity"] == "Wheat"
assert body["data_points"] >= 3
assert "trend" in body
assert "price_history" in body
assert "statistics" in body
def test_trends_statistics_fields(self, client):
resp = client.get("/api/mandi/trends?commodity=Wheat&days=30")
body = resp.json()
stats = body["statistics"]
assert "count" in stats
assert "mean" in stats
assert "median" in stats
assert "min" in stats
assert "max" in stats
assert "std_dev" in stats
def test_trends_with_state_filter(self, client):
resp = client.get("/api/mandi/trends?commodity=Wheat&state=Delhi&days=30")
assert resp.status_code == 200
body = resp.json()
assert body["state"] == "Delhi"
def test_trends_price_history_sorted(self, client):
resp = client.get("/api/mandi/trends?commodity=Wheat&days=30")
body = resp.json()
dates = [h["date"] for h in body["price_history"]]
assert dates == sorted(dates)
def test_trends_no_data(self, client):
resp = client.get("/api/mandi/trends?commodity=Saffron")
assert resp.status_code == 200
body = resp.json()
assert body["data_points"] == 0
assert "No price data" in body.get("message", "")
def test_trends_highest_lowest(self, client):
resp = client.get("/api/mandi/trends?commodity=Wheat&days=30")
body = resp.json()
if body["data_points"] > 0:
assert "highest_price_mandi" in body
assert "lowest_price_mandi" in body
assert (
body["highest_price_mandi"]["price"]
>= body["lowest_price_mandi"]["price"]
)
class TestMandiV1Routes:
"""Verify v1-prefixed routes also work."""
def test_v1_commodities(self, client):
resp = client.get("/api/v1/mandi/commodities")
assert resp.status_code == 200
assert resp.json()["total"] >= 3
def test_v1_prices(self, client):
resp = client.get("/api/v1/mandi/prices?commodity=Wheat")
assert resp.status_code == 200
assert resp.json()["total"] >= 3