"""Integration tests for Marketplace Listings API. docs/planning/economy.md US-3 (task f51c7d95e237). """ import pytest from fastapi.testclient import TestClient from app.main import app def _register(client: TestClient, username: str) -> tuple[int, dict[str, str]]: resp = client.post( "/api/auth/register", json={ "username": username, "email": f"{username}@example.com", "password": "secret123", "date_of_birth": "1990-01-01", }, ) assert resp.status_code == 201, resp.text token = resp.json()["access_token"] headers = {"Authorization": f"Bearer {token}"} me = client.get("/api/users/me", headers=headers) assert me.status_code == 200, me.text return me.json()["id"], headers def test_catalog_items_and_listings_crud(): client = TestClient(app) uid1, h1 = _register(client, "mkt_user_1") uid2, h2 = _register(client, "mkt_user_2") # 1. Create catalog item by user 1 resp = client.post( "/api/marketplace/items", headers=h1, json={ "name": "Wizard Hat", "description": "A pointy blue hat with stars", "item_type": "avatar_item", "metadata_json": {"color": "blue", "rarity": "rare"}, }, ) assert resp.status_code == 201, resp.text item_data = resp.json() assert item_data["name"] == "Wizard Hat" assert item_data["owner_id"] == uid1 item_id = item_data["id"] # 2. List catalog items resp = client.get("/api/marketplace/items", headers=h1, params={"mine": "true"}) assert resp.status_code == 200 my_items = resp.json() assert len(my_items) >= 1 assert any(i["id"] == item_id for i in my_items) resp = client.get("/api/marketplace/items", headers=h2, params={"mine": "true"}) assert resp.status_code == 200 assert not any(i["id"] == item_id for i in resp.json()) # 3. User 2 tries to list User 1's item -> 403 resp = client.post( "/api/marketplace/listings", headers=h2, json={ "catalog_item_id": item_id, "price": 100, }, ) assert resp.status_code == 403, resp.text # Invalid price <= 0 -> 422 resp = client.post( "/api/marketplace/listings", headers=h1, json={ "catalog_item_id": item_id, "price": 0, }, ) assert resp.status_code == 422 # 4. User 1 successfully lists item resp = client.post( "/api/marketplace/listings", headers=h1, json={ "catalog_item_id": item_id, "price": 250, }, ) assert resp.status_code == 201, resp.text listing = resp.json() assert listing["price"] == 250 assert listing["seller_id"] == uid1 assert listing["status"] == "active" assert listing["catalog_item"]["name"] == "Wizard Hat" listing_id = listing["id"] # 5. Search / browse listings resp = client.get("/api/marketplace/listings", params={"q": "Wizard"}) assert resp.status_code == 200, resp.text data = resp.json() assert data["total"] >= 1 assert any(l["id"] == listing_id for l in data["listings"]) # Filter by item_type resp = client.get("/api/marketplace/listings", params={"item_type": "avatar_item"}) assert resp.status_code == 200 assert any(l["id"] == listing_id for l in resp.json()["listings"]) resp = client.get("/api/marketplace/listings", params={"item_type": "experience_pass"}) assert resp.status_code == 200 assert not any(l["id"] == listing_id for l in resp.json()["listings"]) # Price range filter resp = client.get("/api/marketplace/listings", params={"min_price": 300}) assert resp.status_code == 200 assert not any(l["id"] == listing_id for l in resp.json()["listings"]) resp = client.get("/api/marketplace/listings", params={"max_price": 260}) assert resp.status_code == 200 assert any(l["id"] == listing_id for l in resp.json()["listings"]) # 6. Listing detail resp = client.get(f"/api/marketplace/listings/{listing_id}") assert resp.status_code == 200 assert resp.json()["id"] == listing_id # 7. Update listing # User 2 cannot update User 1's listing resp = client.patch( f"/api/marketplace/listings/{listing_id}", headers=h2, json={"price": 500}, ) assert resp.status_code == 403 # User 1 updates price resp = client.patch( f"/api/marketplace/listings/{listing_id}", headers=h1, json={"price": 350}, ) assert resp.status_code == 200 assert resp.json()["price"] == 350 # 8. Delist listing # User 2 cannot delist resp = client.delete(f"/api/marketplace/listings/{listing_id}", headers=h2) assert resp.status_code == 403 # User 1 delists resp = client.delete(f"/api/marketplace/listings/{listing_id}", headers=h1) assert resp.status_code == 204 # Now detail shows delisted resp = client.get(f"/api/marketplace/listings/{listing_id}") assert resp.status_code == 200 assert resp.json()["status"] == "delisted" # Default search only shows active resp = client.get("/api/marketplace/listings") assert resp.status_code == 200 assert not any(l["id"] == listing_id for l in resp.json()["listings"])