|
1 | 1 | import json
|
2 | 2 | from collections.abc import Awaitable, Callable
|
3 | 3 | from datetime import date, datetime
|
4 |
| -from typing import Union |
| 4 | +from typing import Optional, Union |
5 | 5 |
|
6 | 6 | import pytest
|
7 | 7 | import sqlalchemy as sa
|
@@ -439,3 +439,56 @@ class Wrong(base): # type: ignore[misc,valid-type]
|
439 | 439 |
|
440 | 440 | with pytest.raises(ValueError, match="not an attribute"):
|
441 | 441 | permission_for(M, filters={Wrong.id: 1})
|
| 442 | + |
| 443 | + |
| 444 | +async def test_record_type( |
| 445 | + base: DeclarativeBase, aiohttp_client: Callable[[web.Application], Awaitable[TestClient]], |
| 446 | + login: _Login |
| 447 | +) -> None: |
| 448 | + class TestModel(base): # type: ignore[misc,valid-type] |
| 449 | + __tablename__ = "test" |
| 450 | + id: Mapped[int] = mapped_column(primary_key=True) |
| 451 | + foo: Mapped[Optional[bool]] |
| 452 | + bar: Mapped[int] |
| 453 | + |
| 454 | + app = web.Application() |
| 455 | + engine = create_async_engine("sqlite+aiosqlite:///:memory:") |
| 456 | + async with engine.begin() as conn: |
| 457 | + await conn.run_sync(base.metadata.create_all) |
| 458 | + |
| 459 | + schema: aiohttp_admin.Schema = { |
| 460 | + "security": { |
| 461 | + "check_credentials": check_credentials, |
| 462 | + "secure": False |
| 463 | + }, |
| 464 | + "resources": ({"model": SAResource(engine, TestModel)},) |
| 465 | + } |
| 466 | + app["admin"] = aiohttp_admin.setup(app, schema) |
| 467 | + |
| 468 | + admin_client = await aiohttp_client(app) |
| 469 | + assert admin_client.app |
| 470 | + h = await login(admin_client) |
| 471 | + |
| 472 | + url = app["admin"].router["test_create"].url_for() |
| 473 | + p = {"data": json.dumps({"foo": True, "bar": 5})} |
| 474 | + async with admin_client.post(url, params=p, headers=h) as resp: |
| 475 | + assert resp.status == 200 |
| 476 | + assert await resp.json() == {"data": {"id": 1, "foo": True, "bar": 5}} |
| 477 | + p = {"data": json.dumps({"foo": None, "bar": -1})} |
| 478 | + async with admin_client.post(url, params=p, headers=h) as resp: |
| 479 | + assert resp.status == 200 |
| 480 | + assert await resp.json() == {"data": {"id": 2, "foo": None, "bar": -1}} |
| 481 | + |
| 482 | + p = {"data": json.dumps({"foo": 5, "bar": "foo"})} |
| 483 | + async with admin_client.post(url, params=p, headers=h) as resp: |
| 484 | + assert resp.status == 400 |
| 485 | + errors = await resp.json() |
| 486 | + assert any(e["loc"] == ["foo"] and e["type"] == "bool_parsing" for e in errors) |
| 487 | + assert any(e["loc"] == ["bar"] and e["type"] == "int_parsing" for e in errors) |
| 488 | + |
| 489 | + p = {"data": json.dumps({"foo": "foo", "bar": None})} |
| 490 | + async with admin_client.post(url, params=p, headers=h) as resp: |
| 491 | + assert resp.status == 400 |
| 492 | + errors = await resp.json() |
| 493 | + assert any(e["loc"] == ["foo"] and e["type"] == "bool_parsing" for e in errors) |
| 494 | + assert any(e["loc"] == ["bar"] and e["type"] == "int_type" for e in errors) |
0 commit comments