diff --git a/app/__pycache__/__init__.cpython-312.pyc b/app/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000..c47d14a Binary files /dev/null and b/app/__pycache__/__init__.cpython-312.pyc differ diff --git a/app/__pycache__/main.cpython-312.pyc b/app/__pycache__/main.cpython-312.pyc new file mode 100644 index 0000000..4fc17d9 Binary files /dev/null and b/app/__pycache__/main.cpython-312.pyc differ diff --git a/app/__pycache__/models.cpython-312.pyc b/app/__pycache__/models.cpython-312.pyc new file mode 100644 index 0000000..0cb1f43 Binary files /dev/null and b/app/__pycache__/models.cpython-312.pyc differ diff --git a/app/__pycache__/store.cpython-312.pyc b/app/__pycache__/store.cpython-312.pyc new file mode 100644 index 0000000..dcfa07a Binary files /dev/null and b/app/__pycache__/store.cpython-312.pyc differ diff --git a/app/main.py b/app/main.py index bf69788..49f157e 100644 --- a/app/main.py +++ b/app/main.py @@ -5,11 +5,12 @@ from app.models import ProfileCreate, ProfileResponse from app.store import profile_store -import math -app = FastAPI(title="FastAPI Worksohp", version="0.1.0") +app = FastAPI(title="FastAPI Workshop", version="0.1.0") + +# Enable CORS for all origins (useful for frontend testing) app.add_middleware( CORSMiddleware, allow_origins=["*"], @@ -18,25 +19,44 @@ ) -@app.get("/health", status_code=201) +# ========================= +# Health Endpoint +# ========================= + +@app.get("/health", status_code=200) def health_check(): """Return the health status of the API.""" return {"status": "ok"} +# ========================= +# Sum Endpoint (Fixed bug) +# ========================= + @app.get("/sum") def compute_sum(a: int = Query(...), b: int = Query(...)): - return {"result": a * b} + """Return the sum of two integers.""" + return {"result": a + b} -def format_profile(data): +# ========================= +# Helper function +# ========================= + +def format_profile(data: dict): + """Format profile response consistently.""" return { "username": data["username"], + "name": data["username"], "bio": data["bio"], "age": data.get("age"), } +# ========================= +# Profile Endpoints +# ========================= + @app.post("/profile", status_code=201) def create_profile(profile: ProfileCreate): """Create a new user profile.""" @@ -45,6 +65,7 @@ def create_profile(profile: ProfileCreate): "bio": profile.bio, "age": profile.age, } + return format_profile(profile_store[profile.username]) @@ -53,6 +74,7 @@ def get_profile(username: str): """Retrieve a user profile by username.""" if username not in profile_store: raise HTTPException(status_code=404, detail="Profile not found") + return format_profile(profile_store[username]) @@ -61,23 +83,50 @@ def delete_profile(username: str): """Delete a user profile by username.""" if username not in profile_store: raise HTTPException(status_code=404, detail="User not found") + del profile_store[username] + return {"deleted": True} +# ========================= +# Search Endpoint (Fully fixed) +# ========================= + @app.get("/search") def search_profiles( q: str = Query(default=""), offset: int = Query(default=0, ge=0), limit: int = Query(default=10, ge=1), ): - """Search profiles by username or bio.""" - if not q: - return {"results": [], "total": 0} - - results = [ - p - for p in profile_store.values() - if q.lower() in p["username"].lower() or q.lower() in p["bio"].lower() - ] - return {"results": results[offset : offset + limit - 1], "total": len(results)} + """ + Search profiles by username or bio. + + - Empty query returns all profiles + - Correct pagination slicing + - total field reflects full result count + """ + + # If query empty → return all profiles + if q == "": + filtered_results = list(profile_store.values()) + else: + filtered_results = [ + profile + for profile in profile_store.values() + if q.lower() in profile["username"].lower() + or q.lower() in profile["bio"].lower() + ] + + total_count = len(filtered_results) + + # Correct pagination slicing + paginated_results = filtered_results[offset : offset + limit] + + # Format output consistently + formatted_results = [format_profile(profile) for profile in paginated_results] + + return { + "results": formatted_results, + "total": total_count, + } diff --git a/tests/__pycache__/conftest.cpython-312-pytest-7.4.3.pyc b/tests/__pycache__/conftest.cpython-312-pytest-7.4.3.pyc new file mode 100644 index 0000000..8e0283a Binary files /dev/null and b/tests/__pycache__/conftest.cpython-312-pytest-7.4.3.pyc differ diff --git a/tests/__pycache__/test_health.cpython-312-pytest-7.4.3.pyc b/tests/__pycache__/test_health.cpython-312-pytest-7.4.3.pyc new file mode 100644 index 0000000..58c7a1d Binary files /dev/null and b/tests/__pycache__/test_health.cpython-312-pytest-7.4.3.pyc differ diff --git a/tests/__pycache__/test_profile.cpython-312-pytest-7.4.3.pyc b/tests/__pycache__/test_profile.cpython-312-pytest-7.4.3.pyc new file mode 100644 index 0000000..16c29d4 Binary files /dev/null and b/tests/__pycache__/test_profile.cpython-312-pytest-7.4.3.pyc differ diff --git a/tests/__pycache__/test_search.cpython-312-pytest-7.4.3.pyc b/tests/__pycache__/test_search.cpython-312-pytest-7.4.3.pyc new file mode 100644 index 0000000..e9cb82d Binary files /dev/null and b/tests/__pycache__/test_search.cpython-312-pytest-7.4.3.pyc differ diff --git a/tests/__pycache__/test_sum.cpython-312-pytest-7.4.3.pyc b/tests/__pycache__/test_sum.cpython-312-pytest-7.4.3.pyc new file mode 100644 index 0000000..ff7a822 Binary files /dev/null and b/tests/__pycache__/test_sum.cpython-312-pytest-7.4.3.pyc differ diff --git a/tests/test_search.py b/tests/test_search.py index 4e1f460..9839301 100644 --- a/tests/test_search.py +++ b/tests/test_search.py @@ -8,19 +8,22 @@ client = TestClient(app) -def test_search_with_query(): +def test_search_with_query(clean_store): profile_store["alice"] = {"username": "alice", "bio": "dev"} profile_store["alex"] = {"username": "alex", "bio": "designer"} profile_store["bob"] = {"username": "bob", "bio": "manager"} response = client.get("/search?q=al") data = response.json() + assert data["total"] == 2 assert len(data["results"]) == 2 -def test_search_empty_query(): +def test_search_empty_query(clean_store): profile_store["carol"] = {"username": "carol", "bio": "tester"} + response = client.get("/search?q=") data = response.json() + assert data["total"] > 0