committed by
GitHub
3 changed files with 671 additions and 0 deletions
@ -0,0 +1,185 @@ |
|||||
|
""" |
||||
|
Tests for the QUERY HTTP method in FastAPI. |
||||
|
|
||||
|
The QUERY method is a custom HTTP method designed for structured query operations. |
||||
|
""" |
||||
|
|
||||
|
import pytest |
||||
|
from fastapi import APIRouter, FastAPI |
||||
|
from starlette.testclient import TestClient |
||||
|
|
||||
|
|
||||
|
class TestQueryHttpMethod: |
||||
|
"""Tests for the QUERY HTTP method.""" |
||||
|
|
||||
|
@pytest.fixture |
||||
|
def app(self): |
||||
|
"""Create a test FastAPI application.""" |
||||
|
app = FastAPI() |
||||
|
|
||||
|
@app.query("/search") |
||||
|
def search(q: str, limit: int = 10): |
||||
|
"""Simple search endpoint using QUERY method.""" |
||||
|
return { |
||||
|
"query": q, |
||||
|
"limit": limit, |
||||
|
"items": [{"id": 1, "name": f"Result for {q}"}], |
||||
|
} |
||||
|
|
||||
|
return app |
||||
|
|
||||
|
def test_query_method_basic(self, app): |
||||
|
"""Test basic QUERY method request.""" |
||||
|
client = TestClient(app) |
||||
|
response = client.request("QUERY", "/search?q=python") |
||||
|
assert response.status_code == 200 |
||||
|
data = response.json() |
||||
|
assert data["query"] == "python" |
||||
|
assert data["limit"] == 10 |
||||
|
|
||||
|
def test_query_method_with_params(self, app): |
||||
|
"""Test QUERY method with multiple parameters.""" |
||||
|
client = TestClient(app) |
||||
|
response = client.request("QUERY", "/search?q=fastapi&limit=20") |
||||
|
assert response.status_code == 200 |
||||
|
data = response.json() |
||||
|
assert data["query"] == "fastapi" |
||||
|
assert data["limit"] == 20 |
||||
|
|
||||
|
def test_query_method_default_params(self, app): |
||||
|
"""Test QUERY method uses default parameter values.""" |
||||
|
client = TestClient(app) |
||||
|
response = client.request("QUERY", "/search?q=default") |
||||
|
assert response.status_code == 200 |
||||
|
data = response.json() |
||||
|
assert data["limit"] == 10 |
||||
|
|
||||
|
@pytest.fixture |
||||
|
def router_app(self): |
||||
|
"""Test QUERY method with APIRouter.""" |
||||
|
app = FastAPI() |
||||
|
router = APIRouter() |
||||
|
|
||||
|
@router.query("/items/search") |
||||
|
def search_items(name: str, skip: int = 0): |
||||
|
"""Search for items.""" |
||||
|
return { |
||||
|
"search_term": name, |
||||
|
"skip": skip, |
||||
|
"found_items": [{"id": 1, "name": name}], |
||||
|
} |
||||
|
|
||||
|
app.include_router(router) |
||||
|
return app |
||||
|
|
||||
|
def test_query_method_with_router(self, router_app): |
||||
|
"""Test QUERY method with APIRouter.""" |
||||
|
client = TestClient(router_app) |
||||
|
response = client.request("QUERY", "/items/search?name=widget&skip=5") |
||||
|
assert response.status_code == 200 |
||||
|
data = response.json() |
||||
|
assert data["search_term"] == "widget" |
||||
|
assert data["skip"] == 5 |
||||
|
|
||||
|
@pytest.fixture |
||||
|
def tagged_app(self): |
||||
|
"""Test QUERY method with tags and metadata.""" |
||||
|
app = FastAPI() |
||||
|
|
||||
|
@app.query( |
||||
|
"/search", |
||||
|
tags=["search"], |
||||
|
summary="Search endpoint", |
||||
|
description="Search for items using QUERY method", |
||||
|
) |
||||
|
def search(q: str): |
||||
|
return {"query": q, "results": []} |
||||
|
|
||||
|
return app |
||||
|
|
||||
|
def test_query_method_with_tags(self, tagged_app): |
||||
|
"""Test QUERY method request succeeds.""" |
||||
|
client = TestClient(tagged_app) |
||||
|
response = client.request("QUERY", "/search?q=tagged") |
||||
|
assert response.status_code == 200 |
||||
|
assert response.json()["query"] == "tagged" |
||||
|
|
||||
|
def test_query_method_openapi_documentation(self, tagged_app): |
||||
|
"""Test that QUERY method appears in OpenAPI documentation.""" |
||||
|
client = TestClient(tagged_app) |
||||
|
response = client.get("/openapi.json") |
||||
|
assert response.status_code == 200 |
||||
|
openapi = response.json() |
||||
|
assert "/search" in openapi["paths"] |
||||
|
|
||||
|
@pytest.fixture |
||||
|
def multiple_query_methods(self): |
||||
|
"""Test multiple QUERY endpoints.""" |
||||
|
app = FastAPI() |
||||
|
|
||||
|
@app.query("/users/search") |
||||
|
def search_users(name: str): |
||||
|
return {"type": "users", "query": name} |
||||
|
|
||||
|
@app.query("/posts/search") |
||||
|
def search_posts(title: str): |
||||
|
return {"type": "posts", "query": title} |
||||
|
|
||||
|
return app |
||||
|
|
||||
|
def test_multiple_query_endpoints(self, multiple_query_methods): |
||||
|
"""Test multiple QUERY method endpoints.""" |
||||
|
client = TestClient(multiple_query_methods) |
||||
|
|
||||
|
# Test first endpoint |
||||
|
response1 = client.request("QUERY", "/users/search?name=alice") |
||||
|
assert response1.status_code == 200 |
||||
|
assert response1.json()["type"] == "users" |
||||
|
|
||||
|
# Test second endpoint |
||||
|
response2 = client.request("QUERY", "/posts/search?title=hello") |
||||
|
assert response2.status_code == 200 |
||||
|
assert response2.json()["type"] == "posts" |
||||
|
|
||||
|
|
||||
|
class TestQueryMethodIntegration: |
||||
|
"""Test integration with FastAPI features.""" |
||||
|
|
||||
|
@pytest.fixture |
||||
|
def featured_app(self): |
||||
|
"""App with various FastAPI features.""" |
||||
|
app = FastAPI() |
||||
|
|
||||
|
@app.query("/search", status_code=200, deprecated=False) |
||||
|
def search(q: str, limit: int = 10): |
||||
|
"""Search endpoint with custom config.""" |
||||
|
return {"q": q, "limit": limit} |
||||
|
|
||||
|
@app.get("/items") |
||||
|
def list_items(): |
||||
|
"""GET endpoint for comparison.""" |
||||
|
return {"items": []} |
||||
|
|
||||
|
return app |
||||
|
|
||||
|
def test_query_and_get_coexist(self, featured_app): |
||||
|
"""Test that QUERY and GET methods can coexist.""" |
||||
|
client = TestClient(featured_app) |
||||
|
|
||||
|
# GET should work |
||||
|
get_response = client.get("/items") |
||||
|
assert get_response.status_code == 200 |
||||
|
|
||||
|
# QUERY should also work |
||||
|
query_response = client.request("QUERY", "/search?q=test") |
||||
|
assert query_response.status_code == 200 |
||||
|
|
||||
|
def test_query_method_with_status_code(self, featured_app): |
||||
|
"""Test QUERY method respects status_code parameter.""" |
||||
|
client = TestClient(featured_app) |
||||
|
response = client.request("QUERY", "/search?q=test") |
||||
|
assert response.status_code == 200 |
||||
|
|
||||
|
|
||||
|
if __name__ == "__main__": |
||||
|
pytest.main([__file__, "-v"]) |
||||
Loading…
Reference in new issue