Rebrand the Rust client crate (coven/ → hh/, package+binary "hack-house"), README, CLI strings, and branch (coven → hack-house). Gitea repo renamed cmd-chat → hack-house to match. Crypto/server logic unchanged; selftest + golden-vector test still green, binary is now `hack-house`. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
149 lines
4.2 KiB
Python
149 lines
4.2 KiB
Python
import pydantic
|
|
|
|
from pydantic.dataclasses import dataclass
|
|
from sanic import json
|
|
from sanic.views import HTTPMethodView
|
|
|
|
from sanic_ext import validate
|
|
from sanic_ext.exceptions import ValidationError
|
|
|
|
|
|
SNOOPY_DATA = {"name": "Snoopy", "alter_ego": ["Flying Ace", "Joe Cool"]}
|
|
|
|
|
|
def test_validate_json(app):
|
|
@dataclass
|
|
class Pet:
|
|
name: str
|
|
alter_ego: list[str]
|
|
|
|
@app.post("/function")
|
|
@validate(json=Pet)
|
|
async def handler(_, body: Pet):
|
|
return json(
|
|
{
|
|
"is_pet": isinstance(body, Pet),
|
|
"pet": {"name": body.name, "alter_ego": body.alter_ego},
|
|
}
|
|
)
|
|
|
|
class MethodView(HTTPMethodView, attach=app, uri="/method"):
|
|
decorators = [validate(json=Pet)]
|
|
|
|
async def post(self, _, body: Pet):
|
|
return json(
|
|
{
|
|
"is_pet": isinstance(body, Pet),
|
|
"pet": {"name": body.name, "alter_ego": body.alter_ego},
|
|
}
|
|
)
|
|
|
|
_, response = app.test_client.post("/function", json=SNOOPY_DATA)
|
|
assert response.status == 200
|
|
assert response.json["is_pet"]
|
|
assert response.json["pet"] == SNOOPY_DATA
|
|
|
|
_, response = app.test_client.post("/method", json=SNOOPY_DATA)
|
|
assert response.status == 200
|
|
assert response.json["is_pet"]
|
|
assert response.json["pet"] == SNOOPY_DATA
|
|
|
|
|
|
def test_validate_form(app):
|
|
@dataclass
|
|
class Pet:
|
|
name: str
|
|
alter_ego: list[str]
|
|
|
|
@app.post("/function")
|
|
@validate(form=Pet)
|
|
async def handler(_, body: Pet):
|
|
return json(
|
|
{
|
|
"is_pet": isinstance(body, Pet),
|
|
"pet": {"name": body.name, "alter_ego": body.alter_ego},
|
|
}
|
|
)
|
|
|
|
class MethodView(HTTPMethodView, attach=app, uri="/method"):
|
|
decorators = [validate(form=Pet)]
|
|
|
|
async def post(self, _, body: Pet):
|
|
return json(
|
|
{
|
|
"is_pet": isinstance(body, Pet),
|
|
"pet": {"name": body.name, "alter_ego": body.alter_ego},
|
|
}
|
|
)
|
|
|
|
_, response = app.test_client.post("/function", data=SNOOPY_DATA)
|
|
assert response.status == 200
|
|
assert response.json["is_pet"]
|
|
assert response.json["pet"] == SNOOPY_DATA
|
|
|
|
_, response = app.test_client.post("/method", data=SNOOPY_DATA)
|
|
assert response.status == 200
|
|
assert response.json["is_pet"]
|
|
assert response.json["pet"] == SNOOPY_DATA
|
|
|
|
|
|
def test_validate_query(app):
|
|
@dataclass
|
|
class Search:
|
|
q: str
|
|
|
|
@app.get("/function")
|
|
@validate(query=Search)
|
|
async def handler(_, query: Search):
|
|
return json({"q": query.q, "is_search": isinstance(query, Search)})
|
|
|
|
class MethodView(HTTPMethodView, attach=app, uri="/method"):
|
|
decorators = [validate(query=Search)]
|
|
|
|
async def get(self, _, query: Search):
|
|
return json({"q": query.q, "is_search": isinstance(query, Search)})
|
|
|
|
_, response = app.test_client.get("/function", params={"q": "Snoopy"})
|
|
assert response.status == 200
|
|
assert response.json["is_search"]
|
|
assert response.json["q"] == "Snoopy"
|
|
|
|
_, response = app.test_client.get("/method", params={"q": "Snoopy"})
|
|
assert response.status == 200
|
|
assert response.json["is_search"]
|
|
assert response.json["q"] == "Snoopy"
|
|
|
|
|
|
class User(pydantic.BaseModel):
|
|
name: str
|
|
age: int
|
|
email: str
|
|
|
|
|
|
def test_success_validate_form_custom_message(app):
|
|
@app.post("/user")
|
|
@validate(form=User)
|
|
async def create_user(request, body: User):
|
|
return json(body.dict())
|
|
|
|
user = {"name": "Alison", "age": 25, "email": "alison@almeida.com"}
|
|
_, response = app.test_client.post("/user", data=user)
|
|
assert response.status == 200
|
|
|
|
|
|
def test_error_validate_form_custom_message(app):
|
|
async def server_error_validate_form(request, exception: ValidationError):
|
|
error = exception.extra["exception"]
|
|
return json(error, status=400)
|
|
|
|
@app.post("/user")
|
|
@validate(form=User)
|
|
async def create_user(request, body: User):
|
|
return json(body.dict())
|
|
|
|
user = {"name": "Alison", "age": 25}
|
|
|
|
app.error_handler.add(ValidationError, server_error_validate_form)
|
|
_, response = app.test_client.post("/user", data=user)
|
|
assert response.status == 400
|