mirror of
https://github.com/fastapi/fastapi.git
synced 2025-12-28 00:30:58 -05:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
47391ea8fb | ||
|
|
3b1b4f034b | ||
|
|
f362fdc234 | ||
|
|
4ce34686d9 | ||
|
|
dbe83f3919 | ||
|
|
13743e115a | ||
|
|
52842fb8d3 | ||
|
|
4d4fb28f9f | ||
|
|
a1735d6d11 | ||
|
|
1b42639296 | ||
|
|
ded035a421 | ||
|
|
44c849c4fc |
4
.github/workflows/translate.yml
vendored
4
.github/workflows/translate.yml
vendored
@@ -1,8 +1,8 @@
|
||||
name: Translate
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 5 15 * *" # Run at 05:00 on the 15 of every month
|
||||
# schedule:
|
||||
# - cron: "0 5 15 * *" # Run at 05:00 on the 15 of every month
|
||||
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
|
||||
@@ -7,6 +7,18 @@ hide:
|
||||
|
||||
## Latest Changes
|
||||
|
||||
### Translations
|
||||
|
||||
* 🔧 Add LLM prompt file for Traditional Chinese, generated from the existing translations. PR [#14550](https://github.com/fastapi/fastapi/pull/14550) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 🔧 Add LLM prompt file for Simplified Chinese, generated from the existing translations. PR [#14549](https://github.com/fastapi/fastapi/pull/14549) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
### Internal
|
||||
|
||||
* 🔨 Update LLM translation script to guide reviewers to change the prompt. PR [#14614](https://github.com/fastapi/fastapi/pull/14614) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 👷 Do not run translations on cron while finishing updating existing languages. PR [#14613](https://github.com/fastapi/fastapi/pull/14613) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 🔥 Remove test variants for Pydantic v1 in test_request_params. PR [#14612](https://github.com/fastapi/fastapi/pull/14612) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 🔥 Remove Pydantic v1 specific test variants. PR [#14611](https://github.com/fastapi/fastapi/pull/14611) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
## 0.128.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
54
docs/zh-hant/llm-prompt.md
Normal file
54
docs/zh-hant/llm-prompt.md
Normal file
@@ -0,0 +1,54 @@
|
||||
### Target language
|
||||
|
||||
Translate to Traditional Chinese (繁體中文).
|
||||
|
||||
Language code: zh-hant.
|
||||
|
||||
### Grammar and tone
|
||||
|
||||
1) Use clear, concise technical Traditional Chinese consistent with existing docs.
|
||||
2) Address the reader naturally (commonly using “你/你的”).
|
||||
|
||||
### Headings
|
||||
|
||||
1) Follow existing Traditional Chinese heading style (short and descriptive).
|
||||
2) Do not add trailing punctuation to headings.
|
||||
|
||||
### Quotes and punctuation
|
||||
|
||||
1) Keep punctuation style consistent with existing Traditional Chinese docs (they often mix English terms like “FastAPI” with Chinese text).
|
||||
2) Never change punctuation inside inline code, code blocks, URLs, or file paths.
|
||||
3) For more details, please follow the [Chinese Copywriting Guidelines](https://github.com/sparanoid/chinese-copywriting-guidelines).
|
||||
|
||||
### Ellipsis
|
||||
|
||||
1) Keep ellipsis style consistent within each document, prefer `...` over `……`.
|
||||
2) Never change ellipsis in code, URLs, or CLI examples.
|
||||
|
||||
### Preferred translations / glossary
|
||||
|
||||
1. Should avoid using simplified Chinese characters and terms. Always examine if the translation can be easily comprehended by the Traditional Chinese readers.
|
||||
2. For some Python-specific terms like "pickle", "list", "dict" etc, we don't have to translate them.
|
||||
3. Use the following preferred translations when they apply in documentation prose:
|
||||
|
||||
- request (HTTP): 請求
|
||||
- response (HTTP): 回應
|
||||
- path operation: 路徑操作
|
||||
- path operation function: 路徑操作函式
|
||||
|
||||
The translation can optionally include the original English text only in the first occurrence of each page (e.g. "路徑操作 (path operation)") if the translation is hard to be comprehended by most of the Chinese readers.
|
||||
|
||||
### `///` admonitions
|
||||
|
||||
1) Keep the admonition keyword in English (do not translate `note`, `tip`, etc.).
|
||||
2) Many Traditional Chinese docs currently omit titles in `///` blocks; that is OK.
|
||||
3) If a generic title is present, prefer these canonical titles:
|
||||
|
||||
- `/// note | 注意`
|
||||
|
||||
Notes:
|
||||
|
||||
- `details` blocks exist; keep `/// details` as-is and translate only the title after `|`.
|
||||
- Example canonical titles used in existing docs:
|
||||
- `/// details | 上述指令的含義`
|
||||
- `/// details | 關於 `requirements.txt``
|
||||
46
docs/zh/llm-prompt.md
Normal file
46
docs/zh/llm-prompt.md
Normal file
@@ -0,0 +1,46 @@
|
||||
### Target language
|
||||
|
||||
Translate to Simplified Chinese (简体中文).
|
||||
|
||||
Language code: zh.
|
||||
|
||||
### Grammar and tone
|
||||
|
||||
1) Use clear, concise technical Chinese consistent with existing docs.
|
||||
2) Address the reader naturally (commonly using “你/你的”).
|
||||
|
||||
### Headings
|
||||
|
||||
1) Follow existing Simplified Chinese heading style (short and descriptive).
|
||||
2) Do not add trailing punctuation to headings.
|
||||
3) If a heading contains only the name of a FastAPI feature, do not translate it.
|
||||
|
||||
### Quotes and punctuation
|
||||
|
||||
1) Keep punctuation style consistent with existing Simplified Chinese docs (they often mix English terms like “FastAPI” with Chinese text).
|
||||
2) Never change punctuation inside inline code, code blocks, URLs, or file paths.
|
||||
|
||||
### Ellipsis
|
||||
|
||||
1) Keep ellipsis style consistent within each document, prefer `...` over `……`.
|
||||
2) Never change ellipsis in code, URLs, or CLI examples.
|
||||
|
||||
### Preferred translations / glossary
|
||||
|
||||
Use the following preferred translations when they apply in documentation prose:
|
||||
|
||||
- request (HTTP): 请求
|
||||
- response (HTTP): 响应
|
||||
- path operation: 路径操作
|
||||
- path operation function: 路径操作函数
|
||||
|
||||
### `///` admonitions
|
||||
|
||||
1) Keep the admonition keyword in English (do not translate `note`, `tip`, etc.).
|
||||
2) If a title is present, prefer these canonical titles:
|
||||
|
||||
- `/// tip | 提示`
|
||||
- `/// note | 注意`
|
||||
- `/// warning | 警告`
|
||||
- `/// info | 信息`
|
||||
- `/// danger | 危险`
|
||||
@@ -1036,9 +1036,13 @@ def make_pr(
|
||||
print("Creating PR")
|
||||
g = Github(github_token)
|
||||
gh_repo = g.get_repo(github_repository)
|
||||
pr = gh_repo.create_pull(
|
||||
title=message, body=message, base="master", head=branch_name
|
||||
body = (
|
||||
message
|
||||
+ "\n\nThis PR was created automatically using LLMs."
|
||||
+ f"\n\nIt uses the prompt file https://github.com/fastapi/fastapi/blob/master/docs/{language}/llm-prompt.md."
|
||||
+ "\n\nIn most cases, it's better to make PRs updating that file so that the LLM can do a better job generating the translations than suggesting changes in this PR."
|
||||
)
|
||||
pr = gh_repo.create_pull(title=message, body=body, base="master", head=branch_name)
|
||||
print(f"Created PR: {pr.number}")
|
||||
print("Finished")
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from typing import Union
|
||||
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
@@ -52,19 +51,13 @@ def test_openapi_schema():
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [
|
||||
{"$ref": "#/components/schemas/Foo"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "Foo",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"$ref": "#/components/schemas/Foo"}
|
||||
)
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{"$ref": "#/components/schemas/Foo"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "Foo",
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import APIRouter, FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
from inline_snapshot import snapshot
|
||||
from pydantic import BaseModel, HttpUrl
|
||||
from starlette.responses import JSONResponse
|
||||
|
||||
@@ -32,121 +32,114 @@ client = TestClient(app)
|
||||
def test_openapi_schema():
|
||||
response = client.get("/openapi.json")
|
||||
assert response.status_code == 200, response.text
|
||||
assert response.json() == {
|
||||
"openapi": "3.1.0",
|
||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||
"paths": {
|
||||
"/": {
|
||||
"post": {
|
||||
"summary": "Main Route",
|
||||
"operationId": "main_route__post",
|
||||
"parameters": [
|
||||
{
|
||||
"required": True,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"title": "Callback Url",
|
||||
"minLength": 1,
|
||||
"type": "string",
|
||||
"format": "uri",
|
||||
}
|
||||
)
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
| IsDict(
|
||||
{
|
||||
assert response.json() == snapshot(
|
||||
{
|
||||
"openapi": "3.1.0",
|
||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||
"paths": {
|
||||
"/": {
|
||||
"post": {
|
||||
"summary": "Main Route",
|
||||
"operationId": "main_route__post",
|
||||
"parameters": [
|
||||
{
|
||||
"required": True,
|
||||
"schema": {
|
||||
"title": "Callback Url",
|
||||
"maxLength": 2083,
|
||||
"minLength": 1,
|
||||
"type": "string",
|
||||
"format": "uri",
|
||||
}
|
||||
),
|
||||
"name": "callback_url",
|
||||
"in": "query",
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {"application/json": {"schema": {}}},
|
||||
},
|
||||
"name": "callback_url",
|
||||
"in": "query",
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {"application/json": {"schema": {}}},
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
"callbacks": {
|
||||
"callback_route": {
|
||||
"{$callback_url}/callback/": {
|
||||
"get": {
|
||||
"summary": "Callback Route",
|
||||
"operationId": "callback_route__callback_url__callback__get",
|
||||
"responses": {
|
||||
"400": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/CustomModel"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Bad Request",
|
||||
},
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {"schema": {}}
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"CustomModel": {
|
||||
"title": "CustomModel",
|
||||
"required": ["a"],
|
||||
"type": "object",
|
||||
"properties": {"a": {"title": "A", "type": "integer"}},
|
||||
},
|
||||
"HTTPValidationError": {
|
||||
"title": "HTTPValidationError",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"title": "Detail",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ValidationError"
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
"callbacks": {
|
||||
"callback_route": {
|
||||
"{$callback_url}/callback/": {
|
||||
"get": {
|
||||
"summary": "Callback Route",
|
||||
"operationId": "callback_route__callback_url__callback__get",
|
||||
"responses": {
|
||||
"400": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/CustomModel"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Bad Request",
|
||||
},
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {"schema": {}}
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
"ValidationError": {
|
||||
"title": "ValidationError",
|
||||
"required": ["loc", "msg", "type"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"loc": {
|
||||
"title": "Location",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [{"type": "string"}, {"type": "integer"}]
|
||||
},
|
||||
},
|
||||
"msg": {"title": "Message", "type": "string"},
|
||||
"type": {"title": "Error Type", "type": "string"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"CustomModel": {
|
||||
"title": "CustomModel",
|
||||
"required": ["a"],
|
||||
"type": "object",
|
||||
"properties": {"a": {"title": "A", "type": "integer"}},
|
||||
},
|
||||
"HTTPValidationError": {
|
||||
"title": "HTTPValidationError",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"title": "Detail",
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/components/schemas/ValidationError"},
|
||||
}
|
||||
},
|
||||
},
|
||||
"ValidationError": {
|
||||
"title": "ValidationError",
|
||||
"required": ["loc", "msg", "type"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"loc": {
|
||||
"title": "Location",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [{"type": "string"}, {"type": "integer"}]
|
||||
},
|
||||
},
|
||||
"msg": {"title": "Message", "type": "string"},
|
||||
"type": {"title": "Error Type", "type": "string"},
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from typing import Annotated
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import APIRouter, FastAPI, Query
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
@@ -32,44 +31,23 @@ client = TestClient(app)
|
||||
|
||||
foo_is_missing = {
|
||||
"detail": [
|
||||
IsDict(
|
||||
{
|
||||
"loc": ["query", "foo"],
|
||||
"msg": "Field required",
|
||||
"type": "missing",
|
||||
"input": None,
|
||||
}
|
||||
)
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
| IsDict(
|
||||
{
|
||||
"loc": ["query", "foo"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
)
|
||||
{
|
||||
"loc": ["query", "foo"],
|
||||
"msg": "Field required",
|
||||
"type": "missing",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
foo_is_short = {
|
||||
"detail": [
|
||||
IsDict(
|
||||
{
|
||||
"ctx": {"min_length": 1},
|
||||
"loc": ["query", "foo"],
|
||||
"msg": "String should have at least 1 character",
|
||||
"type": "string_too_short",
|
||||
"input": "",
|
||||
}
|
||||
)
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
| IsDict(
|
||||
{
|
||||
"ctx": {"limit_value": 1},
|
||||
"loc": ["query", "foo"],
|
||||
"msg": "ensure this value has at least 1 characters",
|
||||
"type": "value_error.any_str.min_length",
|
||||
}
|
||||
)
|
||||
{
|
||||
"ctx": {"min_length": 1},
|
||||
"loc": ["query", "foo"],
|
||||
"msg": "String should have at least 1 character",
|
||||
"type": "string_too_short",
|
||||
"input": "",
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from .main import app
|
||||
@@ -274,14 +273,10 @@ def test_openapi_schema():
|
||||
"name": "item_id",
|
||||
"in": "path",
|
||||
"required": True,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Item Id",
|
||||
}
|
||||
)
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
| IsDict({"title": "Item Id", "type": "string"}),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Item Id",
|
||||
},
|
||||
}
|
||||
],
|
||||
}
|
||||
@@ -984,14 +979,10 @@ def test_openapi_schema():
|
||||
"name": "query",
|
||||
"in": "query",
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "integer"}, {"type": "null"}],
|
||||
"title": "Query",
|
||||
}
|
||||
)
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
| IsDict({"title": "Query", "type": "integer"}),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "integer"}, {"type": "null"}],
|
||||
"title": "Query",
|
||||
},
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import Depends, FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import BaseModel
|
||||
@@ -46,29 +45,16 @@ async def no_duplicates_sub(
|
||||
def test_no_duplicates_invalid():
|
||||
response = client.post("/no-duplicates", json={"item": {"data": "myitem"}})
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "item2"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "item2"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "item2"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_no_duplicates():
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from typing import Optional
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import APIRouter, Depends, FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
@@ -54,29 +53,16 @@ async def overrider_dependency_with_sub(msg: dict = Depends(overrider_sub_depend
|
||||
def test_main_depends():
|
||||
response = client.get("/main-depends/")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "q"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "q"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "q"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_main_depends_q_foo():
|
||||
@@ -100,29 +86,16 @@ def test_main_depends_q_foo_skip_100_limit_200():
|
||||
def test_decorator_depends():
|
||||
response = client.get("/decorator-depends/")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "q"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "q"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "q"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_decorator_depends_q_foo():
|
||||
@@ -140,29 +113,16 @@ def test_decorator_depends_q_foo_skip_100_limit_200():
|
||||
def test_router_depends():
|
||||
response = client.get("/router-depends/")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "q"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "q"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "q"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_router_depends_q_foo():
|
||||
@@ -186,29 +146,16 @@ def test_router_depends_q_foo_skip_100_limit_200():
|
||||
def test_router_decorator_depends():
|
||||
response = client.get("/router-decorator-depends/")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "q"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "q"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "q"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_router_decorator_depends_q_foo():
|
||||
@@ -272,29 +219,17 @@ def test_override_with_sub_main_depends():
|
||||
app.dependency_overrides[common_parameters] = overrider_dependency_with_sub
|
||||
response = client.get("/main-depends/")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "k"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "k"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "k"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
app.dependency_overrides = {}
|
||||
|
||||
|
||||
@@ -302,29 +237,17 @@ def test_override_with_sub__main_depends_q_foo():
|
||||
app.dependency_overrides[common_parameters] = overrider_dependency_with_sub
|
||||
response = client.get("/main-depends/?q=foo")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "k"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "k"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "k"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
app.dependency_overrides = {}
|
||||
|
||||
|
||||
@@ -340,29 +263,17 @@ def test_override_with_sub_decorator_depends():
|
||||
app.dependency_overrides[common_parameters] = overrider_dependency_with_sub
|
||||
response = client.get("/decorator-depends/")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "k"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "k"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "k"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
app.dependency_overrides = {}
|
||||
|
||||
|
||||
@@ -370,29 +281,17 @@ def test_override_with_sub_decorator_depends_q_foo():
|
||||
app.dependency_overrides[common_parameters] = overrider_dependency_with_sub
|
||||
response = client.get("/decorator-depends/?q=foo")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "k"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "k"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "k"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
app.dependency_overrides = {}
|
||||
|
||||
|
||||
@@ -408,29 +307,17 @@ def test_override_with_sub_router_depends():
|
||||
app.dependency_overrides[common_parameters] = overrider_dependency_with_sub
|
||||
response = client.get("/router-depends/")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "k"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "k"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "k"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
app.dependency_overrides = {}
|
||||
|
||||
|
||||
@@ -438,29 +325,17 @@ def test_override_with_sub_router_depends_q_foo():
|
||||
app.dependency_overrides[common_parameters] = overrider_dependency_with_sub
|
||||
response = client.get("/router-depends/?q=foo")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "k"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "k"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "k"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
app.dependency_overrides = {}
|
||||
|
||||
|
||||
@@ -476,29 +351,17 @@ def test_override_with_sub_router_decorator_depends():
|
||||
app.dependency_overrides[common_parameters] = overrider_dependency_with_sub
|
||||
response = client.get("/router-decorator-depends/")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "k"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "k"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "k"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
app.dependency_overrides = {}
|
||||
|
||||
|
||||
@@ -506,29 +369,17 @@ def test_override_with_sub_router_decorator_depends_q_foo():
|
||||
app.dependency_overrides[common_parameters] = overrider_dependency_with_sub
|
||||
response = client.get("/router-decorator-depends/?q=foo")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "k"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "k"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "k"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
app.dependency_overrides = {}
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from typing import Optional
|
||||
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import FastAPI
|
||||
from fastapi.responses import JSONResponse
|
||||
from fastapi.testclient import TestClient
|
||||
@@ -328,14 +327,10 @@ def test_openapi_schema():
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"title": "Name", "type": "string"},
|
||||
"price": IsDict(
|
||||
{
|
||||
"title": "Price",
|
||||
"anyOf": [{"type": "number"}, {"type": "null"}],
|
||||
}
|
||||
)
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
| IsDict({"title": "Price", "type": "number"}),
|
||||
"price": {
|
||||
"title": "Price",
|
||||
"anyOf": [{"type": "number"}, {"type": "null"}],
|
||||
},
|
||||
},
|
||||
},
|
||||
"ValidationError": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from typing import Optional
|
||||
|
||||
import pytest
|
||||
from dirty_equals import HasRepr, IsDict, IsOneOf
|
||||
from dirty_equals import HasRepr
|
||||
from fastapi import Depends, FastAPI
|
||||
from fastapi.exceptions import ResponseValidationError
|
||||
from fastapi.testclient import TestClient
|
||||
@@ -63,23 +63,13 @@ def test_validator_is_cloned(client: TestClient):
|
||||
with pytest.raises(ResponseValidationError) as err:
|
||||
client.get("/model/modelX")
|
||||
assert err.value.errors() == [
|
||||
IsDict(
|
||||
{
|
||||
"type": "value_error",
|
||||
"loc": ("response", "name"),
|
||||
"msg": "Value error, name must end in A",
|
||||
"input": "modelX",
|
||||
"ctx": {"error": HasRepr("ValueError('name must end in A')")},
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO remove when deprecating Pydantic v1
|
||||
{
|
||||
"loc": ("response", "name"),
|
||||
"msg": "name must end in A",
|
||||
"type": "value_error",
|
||||
}
|
||||
)
|
||||
{
|
||||
"type": "value_error",
|
||||
"loc": ("response", "name"),
|
||||
"msg": "Value error, name must end in A",
|
||||
"input": "modelX",
|
||||
"ctx": {"error": HasRepr("ValueError('name must end in A')")},
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -145,23 +135,14 @@ def test_openapi_schema(client: TestClient):
|
||||
},
|
||||
"ModelA": {
|
||||
"title": "ModelA",
|
||||
"required": IsOneOf(
|
||||
["name", "description", "foo"],
|
||||
# TODO remove when deprecating Pydantic v1
|
||||
["name", "foo"],
|
||||
),
|
||||
"required": ["name", "foo"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"title": "Name", "type": "string"},
|
||||
"description": IsDict(
|
||||
{
|
||||
"title": "Description",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
}
|
||||
)
|
||||
|
|
||||
# TODO remove when deprecating Pydantic v1
|
||||
IsDict({"title": "Description", "type": "string"}),
|
||||
"description": {
|
||||
"title": "Description",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
},
|
||||
"foo": {"$ref": "#/components/schemas/ModelB"},
|
||||
"tags": {
|
||||
"additionalProperties": {"type": "string"},
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from typing import Annotated, Optional
|
||||
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import FastAPI, Form
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import BaseModel, Field
|
||||
@@ -79,68 +78,37 @@ def test_invalid_data():
|
||||
},
|
||||
)
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "int_parsing",
|
||||
"loc": ["body", "age"],
|
||||
"msg": "Input should be a valid integer, unable to parse string as an integer",
|
||||
"input": "seventy",
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "age"],
|
||||
"msg": "value is not a valid integer",
|
||||
"type": "type_error.integer",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "int_parsing",
|
||||
"loc": ["body", "age"],
|
||||
"msg": "Input should be a valid integer, unable to parse string as an integer",
|
||||
"input": "seventy",
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_no_data():
|
||||
response = client.post("/form/")
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "username"],
|
||||
"msg": "Field required",
|
||||
"input": {"tags": ["foo", "bar"], "with": "nothing"},
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "lastname"],
|
||||
"msg": "Field required",
|
||||
"input": {"tags": ["foo", "bar"], "with": "nothing"},
|
||||
},
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "username"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
{
|
||||
"loc": ["body", "lastname"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "username"],
|
||||
"msg": "Field required",
|
||||
"input": {"tags": ["foo", "bar"], "with": "nothing"},
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "lastname"],
|
||||
"msg": "Field required",
|
||||
"input": {"tags": ["foo", "bar"], "with": "nothing"},
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_extra_param_single():
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from typing import Optional
|
||||
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import APIRouter, FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
@@ -163,16 +162,10 @@ def test_openapi_schema():
|
||||
"required": False,
|
||||
"name": "user_id",
|
||||
"in": "query",
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "User Id",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "User Id", "type": "string"}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "User Id",
|
||||
},
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@@ -208,16 +201,10 @@ def test_openapi_schema():
|
||||
"required": False,
|
||||
"name": "user_id",
|
||||
"in": "query",
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "User Id",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "User Id", "type": "string"}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "User Id",
|
||||
},
|
||||
},
|
||||
],
|
||||
"responses": {
|
||||
@@ -247,16 +234,10 @@ def test_openapi_schema():
|
||||
"required": True,
|
||||
"name": "user_id",
|
||||
"in": "path",
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "User Id",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "User Id", "type": "string"}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "User Id",
|
||||
},
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@@ -292,16 +273,10 @@ def test_openapi_schema():
|
||||
"required": True,
|
||||
"name": "user_id",
|
||||
"in": "path",
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "User Id",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "User Id", "type": "string"}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "User Id",
|
||||
},
|
||||
},
|
||||
],
|
||||
"responses": {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
from decimal import Decimal
|
||||
|
||||
from dirty_equals import IsDict, IsOneOf
|
||||
from dirty_equals import IsOneOf
|
||||
from fastapi import FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
from inline_snapshot import snapshot
|
||||
from pydantic import BaseModel, condecimal
|
||||
|
||||
app = FastAPI()
|
||||
@@ -24,109 +25,65 @@ client = TestClient(app)
|
||||
def test_put_correct_body():
|
||||
response = client.post("/items/", json=[{"name": "Foo", "age": 5}])
|
||||
assert response.status_code == 200, response.text
|
||||
assert response.json() == {
|
||||
"item": [
|
||||
{
|
||||
"name": "Foo",
|
||||
"age": IsOneOf(
|
||||
5,
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
"5",
|
||||
),
|
||||
}
|
||||
]
|
||||
}
|
||||
assert response.json() == snapshot(
|
||||
{
|
||||
"item": [
|
||||
{
|
||||
"name": "Foo",
|
||||
"age": "5",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def test_jsonable_encoder_requiring_error():
|
||||
response = client.post("/items/", json=[{"name": "Foo", "age": -1.0}])
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "greater_than",
|
||||
"loc": ["body", 0, "age"],
|
||||
"msg": "Input should be greater than 0",
|
||||
"input": -1.0,
|
||||
"ctx": {"gt": 0},
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"ctx": {"limit_value": 0.0},
|
||||
"loc": ["body", 0, "age"],
|
||||
"msg": "ensure this value is greater than 0",
|
||||
"type": "value_error.number.not_gt",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "greater_than",
|
||||
"loc": ["body", 0, "age"],
|
||||
"msg": "Input should be greater than 0",
|
||||
"input": -1.0,
|
||||
"ctx": {"gt": 0},
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_put_incorrect_body_multiple():
|
||||
response = client.post("/items/", json=[{"age": "five"}, {"age": "six"}])
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", 0, "name"],
|
||||
"msg": "Field required",
|
||||
"input": {"age": "five"},
|
||||
},
|
||||
{
|
||||
"type": "decimal_parsing",
|
||||
"loc": ["body", 0, "age"],
|
||||
"msg": "Input should be a valid decimal",
|
||||
"input": "five",
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", 1, "name"],
|
||||
"msg": "Field required",
|
||||
"input": {"age": "six"},
|
||||
},
|
||||
{
|
||||
"type": "decimal_parsing",
|
||||
"loc": ["body", 1, "age"],
|
||||
"msg": "Input should be a valid decimal",
|
||||
"input": "six",
|
||||
},
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", 0, "name"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
{
|
||||
"loc": ["body", 0, "age"],
|
||||
"msg": "value is not a valid decimal",
|
||||
"type": "type_error.decimal",
|
||||
},
|
||||
{
|
||||
"loc": ["body", 1, "name"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
{
|
||||
"loc": ["body", 1, "age"],
|
||||
"msg": "value is not a valid decimal",
|
||||
"type": "type_error.decimal",
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", 0, "name"],
|
||||
"msg": "Field required",
|
||||
"input": {"age": "five"},
|
||||
},
|
||||
{
|
||||
"type": "decimal_parsing",
|
||||
"loc": ["body", 0, "age"],
|
||||
"msg": "Input should be a valid decimal",
|
||||
"input": "five",
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", 1, "name"],
|
||||
"msg": "Field required",
|
||||
"input": {"age": "six"},
|
||||
},
|
||||
{
|
||||
"type": "decimal_parsing",
|
||||
"loc": ["body", 1, "age"],
|
||||
"msg": "Input should be a valid decimal",
|
||||
"input": "six",
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_openapi_schema():
|
||||
@@ -179,31 +136,21 @@ def test_openapi_schema():
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"title": "Name", "type": "string"},
|
||||
"age": IsDict(
|
||||
{
|
||||
"title": "Age",
|
||||
"anyOf": [
|
||||
{"exclusiveMinimum": 0.0, "type": "number"},
|
||||
IsOneOf(
|
||||
# pydantic < 2.12.0
|
||||
{"type": "string"},
|
||||
# pydantic >= 2.12.0
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": r"^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$",
|
||||
},
|
||||
),
|
||||
],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"title": "Age",
|
||||
"exclusiveMinimum": 0.0,
|
||||
"type": "number",
|
||||
}
|
||||
),
|
||||
"age": {
|
||||
"title": "Age",
|
||||
"anyOf": [
|
||||
{"exclusiveMinimum": 0.0, "type": "number"},
|
||||
IsOneOf(
|
||||
# pydantic < 2.12.0
|
||||
{"type": "string"},
|
||||
# pydantic >= 2.12.0
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": r"^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$",
|
||||
},
|
||||
),
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
"ValidationError": {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import FastAPI, Query
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
@@ -22,40 +21,22 @@ def test_multi_query():
|
||||
def test_multi_query_incorrect():
|
||||
response = client.get("/items/?q=five&q=six")
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "int_parsing",
|
||||
"loc": ["query", "q", 0],
|
||||
"msg": "Input should be a valid integer, unable to parse string as an integer",
|
||||
"input": "five",
|
||||
},
|
||||
{
|
||||
"type": "int_parsing",
|
||||
"loc": ["query", "q", 1],
|
||||
"msg": "Input should be a valid integer, unable to parse string as an integer",
|
||||
"input": "six",
|
||||
},
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "q", 0],
|
||||
"msg": "value is not a valid integer",
|
||||
"type": "type_error.integer",
|
||||
},
|
||||
{
|
||||
"loc": ["query", "q", 1],
|
||||
"msg": "value is not a valid integer",
|
||||
"type": "type_error.integer",
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "int_parsing",
|
||||
"loc": ["query", "q", 0],
|
||||
"msg": "Input should be a valid integer, unable to parse string as an integer",
|
||||
"input": "five",
|
||||
},
|
||||
{
|
||||
"type": "int_parsing",
|
||||
"loc": ["query", "q", 1],
|
||||
"msg": "Input should be a valid integer, unable to parse string as an integer",
|
||||
"input": "six",
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_openapi_schema():
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from typing import Union
|
||||
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import Body, Cookie, FastAPI, Header, Path, Query
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import BaseModel
|
||||
@@ -155,26 +154,12 @@ def test_openapi_schema():
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": IsDict(
|
||||
{
|
||||
"$ref": "#/components/schemas/Item",
|
||||
"examples": [
|
||||
{"data": "Data in Body examples, example1"}
|
||||
],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
{
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
"allOf": [
|
||||
{"$ref": "#/components/schemas/Item"}
|
||||
],
|
||||
"title": "Item",
|
||||
"examples": [
|
||||
{"data": "Data in Body examples, example1"}
|
||||
],
|
||||
}
|
||||
),
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Item",
|
||||
"examples": [
|
||||
{"data": "Data in Body examples, example1"}
|
||||
],
|
||||
},
|
||||
"examples": {
|
||||
"Example One": {
|
||||
"summary": "Example One Summary",
|
||||
@@ -265,27 +250,14 @@ def test_openapi_schema():
|
||||
"name": "data",
|
||||
"in": "query",
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"examples": [
|
||||
"json_schema_query1",
|
||||
"json_schema_query2",
|
||||
],
|
||||
"title": "Data",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"examples": [
|
||||
"json_schema_query1",
|
||||
"json_schema_query2",
|
||||
],
|
||||
"type": "string",
|
||||
"title": "Data",
|
||||
}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"examples": [
|
||||
"json_schema_query1",
|
||||
"json_schema_query2",
|
||||
],
|
||||
"title": "Data",
|
||||
},
|
||||
"examples": {
|
||||
"Query One": {
|
||||
"summary": "Query One Summary",
|
||||
@@ -323,27 +295,14 @@ def test_openapi_schema():
|
||||
"name": "data",
|
||||
"in": "header",
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"examples": [
|
||||
"json_schema_header1",
|
||||
"json_schema_header2",
|
||||
],
|
||||
"title": "Data",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"type": "string",
|
||||
"examples": [
|
||||
"json_schema_header1",
|
||||
"json_schema_header2",
|
||||
],
|
||||
"title": "Data",
|
||||
}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"examples": [
|
||||
"json_schema_header1",
|
||||
"json_schema_header2",
|
||||
],
|
||||
"title": "Data",
|
||||
},
|
||||
"examples": {
|
||||
"Header One": {
|
||||
"summary": "Header One Summary",
|
||||
@@ -381,27 +340,14 @@ def test_openapi_schema():
|
||||
"name": "data",
|
||||
"in": "cookie",
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"examples": [
|
||||
"json_schema_cookie1",
|
||||
"json_schema_cookie2",
|
||||
],
|
||||
"title": "Data",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"type": "string",
|
||||
"examples": [
|
||||
"json_schema_cookie1",
|
||||
"json_schema_cookie2",
|
||||
],
|
||||
"title": "Data",
|
||||
}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"examples": [
|
||||
"json_schema_cookie1",
|
||||
"json_schema_cookie2",
|
||||
],
|
||||
"title": "Data",
|
||||
},
|
||||
"examples": {
|
||||
"Cookie One": {
|
||||
"summary": "Cookie One Summary",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from typing import Optional
|
||||
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
@@ -53,21 +52,11 @@ def test_openapi():
|
||||
"parameters": [
|
||||
{
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "integer"}, {"type": "null"}],
|
||||
"default": 50,
|
||||
"title": "Standard Query Param",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"title": "Standard Query Param",
|
||||
"type": "integer",
|
||||
"default": 50,
|
||||
}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "integer"}, {"type": "null"}],
|
||||
"default": 50,
|
||||
"title": "Standard Query Param",
|
||||
},
|
||||
"name": "standard_query_param",
|
||||
"in": "query",
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from dirty_equals import IsOneOf
|
||||
from fastapi import FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
from inline_snapshot import snapshot
|
||||
|
||||
app = FastAPI(
|
||||
servers=[
|
||||
@@ -30,39 +30,31 @@ def test_app():
|
||||
def test_openapi_schema():
|
||||
response = client.get("/openapi.json")
|
||||
assert response.status_code == 200, response.text
|
||||
assert response.json() == {
|
||||
"openapi": "3.1.0",
|
||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||
"servers": [
|
||||
{"url": "/", "description": "Default, relative server"},
|
||||
{
|
||||
"url": IsOneOf(
|
||||
"http://staging.localhost.tiangolo.com:8000/",
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
"http://staging.localhost.tiangolo.com:8000",
|
||||
),
|
||||
"description": "Staging but actually localhost still",
|
||||
},
|
||||
{
|
||||
"url": IsOneOf(
|
||||
"https://prod.example.com/",
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
"https://prod.example.com",
|
||||
)
|
||||
},
|
||||
],
|
||||
"paths": {
|
||||
"/foo": {
|
||||
"get": {
|
||||
"summary": "Foo",
|
||||
"operationId": "foo_foo_get",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {"application/json": {"schema": {}}},
|
||||
}
|
||||
},
|
||||
assert response.json() == snapshot(
|
||||
{
|
||||
"openapi": "3.1.0",
|
||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||
"servers": [
|
||||
{"url": "/", "description": "Default, relative server"},
|
||||
{
|
||||
"url": "http://staging.localhost.tiangolo.com:8000",
|
||||
"description": "Staging but actually localhost still",
|
||||
},
|
||||
{"url": "https://prod.example.com"},
|
||||
],
|
||||
"paths": {
|
||||
"/foo": {
|
||||
"get": {
|
||||
"summary": "Foo",
|
||||
"operationId": "foo_foo_get",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {"application/json": {"schema": {}}},
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from typing import Any
|
||||
|
||||
from dirty_equals import IsOneOf
|
||||
from fastapi.params import Body, Cookie, Header, Param, Path, Query
|
||||
|
||||
test_data: list[Any] = ["teststr", None, ..., 1, []]
|
||||
@@ -19,11 +18,7 @@ def test_param_repr_none():
|
||||
|
||||
|
||||
def test_param_repr_ellipsis():
|
||||
assert repr(Param(...)) == IsOneOf(
|
||||
"Param(PydanticUndefined)",
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
"Param(Ellipsis)",
|
||||
)
|
||||
assert repr(Param(...)) == "Param(PydanticUndefined)"
|
||||
|
||||
|
||||
def test_param_repr_number():
|
||||
@@ -35,16 +30,8 @@ def test_param_repr_list():
|
||||
|
||||
|
||||
def test_path_repr():
|
||||
assert repr(Path()) == IsOneOf(
|
||||
"Path(PydanticUndefined)",
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
"Path(Ellipsis)",
|
||||
)
|
||||
assert repr(Path(...)) == IsOneOf(
|
||||
"Path(PydanticUndefined)",
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
"Path(Ellipsis)",
|
||||
)
|
||||
assert repr(Path()) == "Path(PydanticUndefined)"
|
||||
assert repr(Path(...)) == "Path(PydanticUndefined)"
|
||||
|
||||
|
||||
def test_query_repr_str():
|
||||
@@ -56,11 +43,7 @@ def test_query_repr_none():
|
||||
|
||||
|
||||
def test_query_repr_ellipsis():
|
||||
assert repr(Query(...)) == IsOneOf(
|
||||
"Query(PydanticUndefined)",
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
"Query(Ellipsis)",
|
||||
)
|
||||
assert repr(Query(...)) == "Query(PydanticUndefined)"
|
||||
|
||||
|
||||
def test_query_repr_number():
|
||||
@@ -80,11 +63,7 @@ def test_header_repr_none():
|
||||
|
||||
|
||||
def test_header_repr_ellipsis():
|
||||
assert repr(Header(...)) == IsOneOf(
|
||||
"Header(PydanticUndefined)",
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
"Header(Ellipsis)",
|
||||
)
|
||||
assert repr(Header(...)) == "Header(PydanticUndefined)"
|
||||
|
||||
|
||||
def test_header_repr_number():
|
||||
@@ -104,11 +83,7 @@ def test_cookie_repr_none():
|
||||
|
||||
|
||||
def test_cookie_repr_ellipsis():
|
||||
assert repr(Cookie(...)) == IsOneOf(
|
||||
"Cookie(PydanticUndefined)",
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
"Cookie(Ellipsis)",
|
||||
)
|
||||
assert repr(Cookie(...)) == "Cookie(PydanticUndefined)"
|
||||
|
||||
|
||||
def test_cookie_repr_number():
|
||||
@@ -128,11 +103,7 @@ def test_body_repr_none():
|
||||
|
||||
|
||||
def test_body_repr_ellipsis():
|
||||
assert repr(Body(...)) == IsOneOf(
|
||||
"Body(PydanticUndefined)",
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
"Body(Ellipsis)",
|
||||
)
|
||||
assert repr(Body(...)) == "Body(PydanticUndefined)"
|
||||
|
||||
|
||||
def test_body_repr_number():
|
||||
|
||||
1182
tests/test_path.py
1182
tests/test_path.py
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,3 @@
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from .main import app
|
||||
@@ -9,29 +8,16 @@ client = TestClient(app)
|
||||
def test_query():
|
||||
response = client.get("/query")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "query"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "query"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "query"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_query_query_baz():
|
||||
@@ -43,29 +29,16 @@ def test_query_query_baz():
|
||||
def test_query_not_declared_baz():
|
||||
response = client.get("/query?not_declared=baz")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "query"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "query"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "query"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_query_optional():
|
||||
@@ -89,29 +62,16 @@ def test_query_optional_not_declared_baz():
|
||||
def test_query_int():
|
||||
response = client.get("/query/int")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "query"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "query"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "query"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_query_int_query_42():
|
||||
@@ -123,85 +83,46 @@ def test_query_int_query_42():
|
||||
def test_query_int_query_42_5():
|
||||
response = client.get("/query/int?query=42.5")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "int_parsing",
|
||||
"loc": ["query", "query"],
|
||||
"msg": "Input should be a valid integer, unable to parse string as an integer",
|
||||
"input": "42.5",
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "query"],
|
||||
"msg": "value is not a valid integer",
|
||||
"type": "type_error.integer",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "int_parsing",
|
||||
"loc": ["query", "query"],
|
||||
"msg": "Input should be a valid integer, unable to parse string as an integer",
|
||||
"input": "42.5",
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_query_int_query_baz():
|
||||
response = client.get("/query/int?query=baz")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "int_parsing",
|
||||
"loc": ["query", "query"],
|
||||
"msg": "Input should be a valid integer, unable to parse string as an integer",
|
||||
"input": "baz",
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "query"],
|
||||
"msg": "value is not a valid integer",
|
||||
"type": "type_error.integer",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "int_parsing",
|
||||
"loc": ["query", "query"],
|
||||
"msg": "Input should be a valid integer, unable to parse string as an integer",
|
||||
"input": "baz",
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_query_int_not_declared_baz():
|
||||
response = client.get("/query/int?not_declared=baz")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "query"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "query"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "query"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_query_int_optional():
|
||||
@@ -219,29 +140,16 @@ def test_query_int_optional_query_50():
|
||||
def test_query_int_optional_query_foo():
|
||||
response = client.get("/query/int/optional?query=foo")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "int_parsing",
|
||||
"loc": ["query", "query"],
|
||||
"msg": "Input should be a valid integer, unable to parse string as an integer",
|
||||
"input": "foo",
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "query"],
|
||||
"msg": "value is not a valid integer",
|
||||
"type": "type_error.integer",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "int_parsing",
|
||||
"loc": ["query", "query"],
|
||||
"msg": "Input should be a valid integer, unable to parse string as an integer",
|
||||
"input": "foo",
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_query_int_default():
|
||||
@@ -259,29 +167,16 @@ def test_query_int_default_query_50():
|
||||
def test_query_int_default_query_foo():
|
||||
response = client.get("/query/int/default?query=foo")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "int_parsing",
|
||||
"loc": ["query", "query"],
|
||||
"msg": "Input should be a valid integer, unable to parse string as an integer",
|
||||
"input": "foo",
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "query"],
|
||||
"msg": "value is not a valid integer",
|
||||
"type": "type_error.integer",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "int_parsing",
|
||||
"loc": ["query", "query"],
|
||||
"msg": "Input should be a valid integer, unable to parse string as an integer",
|
||||
"input": "foo",
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_query_param():
|
||||
@@ -299,29 +194,16 @@ def test_query_param_query_50():
|
||||
def test_query_param_required():
|
||||
response = client.get("/query/param-required")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "query"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "query"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "query"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_query_param_required_query_50():
|
||||
@@ -333,29 +215,16 @@ def test_query_param_required_query_50():
|
||||
def test_query_param_required_int():
|
||||
response = client.get("/query/param-required/int")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "query"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "query"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "query"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_query_param_required_int_query_50():
|
||||
@@ -367,29 +236,16 @@ def test_query_param_required_int_query_50():
|
||||
def test_query_param_required_int_query_foo():
|
||||
response = client.get("/query/param-required/int?query=foo")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "int_parsing",
|
||||
"loc": ["query", "query"],
|
||||
"msg": "Input should be a valid integer, unable to parse string as an integer",
|
||||
"input": "foo",
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "query"],
|
||||
"msg": "value is not a valid integer",
|
||||
"type": "type_error.integer",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "int_parsing",
|
||||
"loc": ["query", "query"],
|
||||
"msg": "Input should be a valid integer, unable to parse string as an integer",
|
||||
"input": "foo",
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_query_frozenset_query_1_query_1_query_2():
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
from typing import Annotated
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import FastAPI, Form
|
||||
from fastapi.exceptions import FastAPIDeprecationWarning
|
||||
from fastapi.testclient import TestClient
|
||||
from inline_snapshot import snapshot
|
||||
|
||||
from .utils import needs_py310
|
||||
|
||||
@@ -47,31 +47,17 @@ def test_query_nonregexquery():
|
||||
client = get_client()
|
||||
response = client.post("/items/", data={"q": "nonregexquery"})
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "string_pattern_mismatch",
|
||||
"loc": ["body", "q"],
|
||||
"msg": "String should match pattern '^fixedquery$'",
|
||||
"input": "nonregexquery",
|
||||
"ctx": {"pattern": "^fixedquery$"},
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"ctx": {"pattern": "^fixedquery$"},
|
||||
"loc": ["body", "q"],
|
||||
"msg": 'string does not match regex "^fixedquery$"',
|
||||
"type": "value_error.str.regex",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "string_pattern_mismatch",
|
||||
"loc": ["body", "q"],
|
||||
"msg": "String should match pattern '^fixedquery$'",
|
||||
"input": "nonregexquery",
|
||||
"ctx": {"pattern": "^fixedquery$"},
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@needs_py310
|
||||
@@ -79,104 +65,88 @@ def test_openapi_schema():
|
||||
client = get_client()
|
||||
response = client.get("/openapi.json")
|
||||
assert response.status_code == 200, response.text
|
||||
# insert_assert(response.json())
|
||||
assert response.json() == {
|
||||
"openapi": "3.1.0",
|
||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||
"paths": {
|
||||
"/items/": {
|
||||
"post": {
|
||||
"summary": "Read Items",
|
||||
"operationId": "read_items_items__post",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/x-www-form-urlencoded": {
|
||||
"schema": IsDict(
|
||||
{
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/Body_read_items_items__post"
|
||||
}
|
||||
],
|
||||
"title": "Body",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
assert response.json() == snapshot(
|
||||
{
|
||||
"openapi": "3.1.0",
|
||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||
"paths": {
|
||||
"/items/": {
|
||||
"post": {
|
||||
"summary": "Read Items",
|
||||
"operationId": "read_items_items__post",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/x-www-form-urlencoded": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Body_read_items_items__post"
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {"application/json": {"schema": {}}},
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {"application/json": {"schema": {}}},
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"Body_read_items_items__post": {
|
||||
"properties": {
|
||||
"q": IsDict(
|
||||
{
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"Body_read_items_items__post": {
|
||||
"properties": {
|
||||
"q": {
|
||||
"anyOf": [
|
||||
{"type": "string", "pattern": "^fixedquery$"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "Q",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"type": "string", "pattern": "^fixedquery$", "title": "Q"}
|
||||
)
|
||||
},
|
||||
"type": "object",
|
||||
"title": "Body_read_items_items__post",
|
||||
},
|
||||
"HTTPValidationError": {
|
||||
"properties": {
|
||||
"detail": {
|
||||
"items": {"$ref": "#/components/schemas/ValidationError"},
|
||||
"type": "array",
|
||||
"title": "Detail",
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"title": "HTTPValidationError",
|
||||
},
|
||||
"ValidationError": {
|
||||
"properties": {
|
||||
"loc": {
|
||||
"items": {
|
||||
"anyOf": [{"type": "string"}, {"type": "integer"}]
|
||||
},
|
||||
"type": "array",
|
||||
"title": "Location",
|
||||
},
|
||||
"msg": {"type": "string", "title": "Message"},
|
||||
"type": {"type": "string", "title": "Error Type"},
|
||||
"type": "object",
|
||||
"title": "Body_read_items_items__post",
|
||||
},
|
||||
"type": "object",
|
||||
"required": ["loc", "msg", "type"],
|
||||
"title": "ValidationError",
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
"HTTPValidationError": {
|
||||
"properties": {
|
||||
"detail": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ValidationError"
|
||||
},
|
||||
"type": "array",
|
||||
"title": "Detail",
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"title": "HTTPValidationError",
|
||||
},
|
||||
"ValidationError": {
|
||||
"properties": {
|
||||
"loc": {
|
||||
"items": {
|
||||
"anyOf": [{"type": "string"}, {"type": "integer"}]
|
||||
},
|
||||
"type": "array",
|
||||
"title": "Location",
|
||||
},
|
||||
"msg": {"type": "string", "title": "Message"},
|
||||
"type": {"type": "string", "title": "Error Type"},
|
||||
},
|
||||
"type": "object",
|
||||
"required": ["loc", "msg", "type"],
|
||||
"title": "ValidationError",
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from typing import Annotated
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import FastAPI, Query
|
||||
from fastapi.exceptions import FastAPIDeprecationWarning
|
||||
from fastapi.testclient import TestClient
|
||||
@@ -47,31 +46,17 @@ def test_query_params_str_validations_item_query_nonregexquery():
|
||||
client = get_client()
|
||||
response = client.get("/items/", params={"q": "nonregexquery"})
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "string_pattern_mismatch",
|
||||
"loc": ["query", "q"],
|
||||
"msg": "String should match pattern '^fixedquery$'",
|
||||
"input": "nonregexquery",
|
||||
"ctx": {"pattern": "^fixedquery$"},
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"ctx": {"pattern": "^fixedquery$"},
|
||||
"loc": ["query", "q"],
|
||||
"msg": 'string does not match regex "^fixedquery$"',
|
||||
"type": "value_error.str.regex",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "string_pattern_mismatch",
|
||||
"loc": ["query", "q"],
|
||||
"msg": "String should match pattern '^fixedquery$'",
|
||||
"input": "nonregexquery",
|
||||
"ctx": {"pattern": "^fixedquery$"},
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@needs_py310
|
||||
@@ -93,23 +78,13 @@ def test_openapi_schema():
|
||||
"name": "q",
|
||||
"in": "query",
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [
|
||||
{"type": "string", "pattern": "^fixedquery$"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "Q",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^fixedquery$",
|
||||
"title": "Q",
|
||||
}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{"type": "string", "pattern": "^fixedquery$"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "Q",
|
||||
},
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from typing import Annotated, Union
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict, IsOneOf, IsPartialDict
|
||||
from dirty_equals import IsOneOf, IsPartialDict
|
||||
from fastapi import Body, FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import BaseModel, Field
|
||||
@@ -59,28 +59,16 @@ def test_required_list_str_missing(path: str, json: Union[dict, None]):
|
||||
client = TestClient(app)
|
||||
response = client.post(path, json=json)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": IsOneOf(["body", "p"], ["body"]),
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {}),
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": IsOneOf(["body", "p"], ["body"]),
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": IsOneOf(["body", "p"], ["body"]),
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {}),
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -148,29 +136,16 @@ def test_required_list_alias_missing(path: str, json: Union[dict, None]):
|
||||
client = TestClient(app)
|
||||
response = client.post(path, json=json)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": IsOneOf(["body", "p_alias"], ["body"]),
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {}),
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": IsOneOf(["body", "p_alias"], ["body"]),
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": IsOneOf(["body", "p_alias"], ["body"]),
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {}),
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -181,29 +156,16 @@ def test_required_list_alias_by_name(path: str):
|
||||
client = TestClient(app)
|
||||
response = client.post(path, json={"p": ["hello", "world"]})
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {"p": ["hello", "world"]}),
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "p_alias"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {"p": ["hello", "world"]}),
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from typing import Annotated, Optional
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import Body, FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import BaseModel, Field
|
||||
@@ -38,30 +37,19 @@ def test_optional_list_str_schema(path: str):
|
||||
openapi = app.openapi()
|
||||
body_model_name = get_body_model_name(openapi, path)
|
||||
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == IsDict(
|
||||
{
|
||||
"properties": {
|
||||
"p": {
|
||||
"anyOf": [
|
||||
{"items": {"type": "string"}, "type": "array"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P",
|
||||
},
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == {
|
||||
"properties": {
|
||||
"p": {
|
||||
"anyOf": [
|
||||
{"items": {"type": "string"}, "type": "array"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P",
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"properties": {
|
||||
"p": {"items": {"type": "string"}, "type": "array", "title": "P"},
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
)
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
|
||||
|
||||
def test_optional_list_str_missing():
|
||||
@@ -75,29 +63,16 @@ def test_model_optional_list_str_missing():
|
||||
client = TestClient(app)
|
||||
response = client.post("/model-optional-list-str")
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"input": None,
|
||||
"loc": ["body"],
|
||||
"msg": "Field required",
|
||||
"type": "missing",
|
||||
},
|
||||
],
|
||||
}
|
||||
) | IsDict(
|
||||
{
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
],
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"input": None,
|
||||
"loc": ["body"],
|
||||
"msg": "Field required",
|
||||
"type": "missing",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -153,34 +128,19 @@ def test_optional_list_str_alias_schema(path: str):
|
||||
openapi = app.openapi()
|
||||
body_model_name = get_body_model_name(openapi, path)
|
||||
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == IsDict(
|
||||
{
|
||||
"properties": {
|
||||
"p_alias": {
|
||||
"anyOf": [
|
||||
{"items": {"type": "string"}, "type": "array"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Alias",
|
||||
},
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == {
|
||||
"properties": {
|
||||
"p_alias": {
|
||||
"anyOf": [
|
||||
{"items": {"type": "string"}, "type": "array"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Alias",
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"properties": {
|
||||
"p_alias": {
|
||||
"items": {"type": "string"},
|
||||
"type": "array",
|
||||
"title": "P Alias",
|
||||
},
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
)
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
|
||||
|
||||
def test_optional_list_alias_missing():
|
||||
@@ -194,29 +154,16 @@ def test_model_optional_list_alias_missing():
|
||||
client = TestClient(app)
|
||||
response = client.post("/model-optional-list-alias")
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"input": None,
|
||||
"loc": ["body"],
|
||||
"msg": "Field required",
|
||||
"type": "missing",
|
||||
},
|
||||
],
|
||||
}
|
||||
) | IsDict(
|
||||
{
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
],
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"input": None,
|
||||
"loc": ["body"],
|
||||
"msg": "Field required",
|
||||
"type": "missing",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -289,34 +236,19 @@ def test_optional_list_validation_alias_schema(path: str):
|
||||
openapi = app.openapi()
|
||||
body_model_name = get_body_model_name(openapi, path)
|
||||
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == IsDict(
|
||||
{
|
||||
"properties": {
|
||||
"p_val_alias": {
|
||||
"anyOf": [
|
||||
{"items": {"type": "string"}, "type": "array"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Val Alias",
|
||||
},
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == {
|
||||
"properties": {
|
||||
"p_val_alias": {
|
||||
"anyOf": [
|
||||
{"items": {"type": "string"}, "type": "array"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Val Alias",
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"properties": {
|
||||
"p_val_alias": {
|
||||
"items": {"type": "string"},
|
||||
"type": "array",
|
||||
"title": "P Val Alias",
|
||||
},
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
)
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
|
||||
|
||||
def test_optional_list_validation_alias_missing():
|
||||
@@ -330,29 +262,16 @@ def test_model_optional_list_validation_alias_missing():
|
||||
client = TestClient(app)
|
||||
response = client.post("/model-optional-list-validation-alias")
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"input": None,
|
||||
"loc": ["body"],
|
||||
"msg": "Field required",
|
||||
"type": "missing",
|
||||
},
|
||||
],
|
||||
}
|
||||
) | IsDict(
|
||||
{
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
],
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"input": None,
|
||||
"loc": ["body"],
|
||||
"msg": "Field required",
|
||||
"type": "missing",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -438,34 +357,19 @@ def test_optional_list_alias_and_validation_alias_schema(path: str):
|
||||
openapi = app.openapi()
|
||||
body_model_name = get_body_model_name(openapi, path)
|
||||
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == IsDict(
|
||||
{
|
||||
"properties": {
|
||||
"p_val_alias": {
|
||||
"anyOf": [
|
||||
{"items": {"type": "string"}, "type": "array"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Val Alias",
|
||||
},
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == {
|
||||
"properties": {
|
||||
"p_val_alias": {
|
||||
"anyOf": [
|
||||
{"items": {"type": "string"}, "type": "array"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Val Alias",
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"properties": {
|
||||
"p_val_alias": {
|
||||
"items": {"type": "string"},
|
||||
"type": "array",
|
||||
"title": "P Val Alias",
|
||||
},
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
)
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
|
||||
|
||||
def test_optional_list_alias_and_validation_alias_missing():
|
||||
@@ -479,29 +383,16 @@ def test_model_optional_list_alias_and_validation_alias_missing():
|
||||
client = TestClient(app)
|
||||
response = client.post("/model-optional-list-alias-and-validation-alias")
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"input": None,
|
||||
"loc": ["body"],
|
||||
"msg": "Field required",
|
||||
"type": "missing",
|
||||
},
|
||||
],
|
||||
}
|
||||
) | IsDict(
|
||||
{
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
],
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"input": None,
|
||||
"loc": ["body"],
|
||||
"msg": "Field required",
|
||||
"type": "missing",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from typing import Annotated, Optional
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import Body, FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import BaseModel, Field
|
||||
@@ -36,27 +35,16 @@ def test_optional_str_schema(path: str):
|
||||
openapi = app.openapi()
|
||||
body_model_name = get_body_model_name(openapi, path)
|
||||
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == IsDict(
|
||||
{
|
||||
"properties": {
|
||||
"p": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "P",
|
||||
},
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == {
|
||||
"properties": {
|
||||
"p": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "P",
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"properties": {
|
||||
"p": {"type": "string", "title": "P"},
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
)
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
|
||||
|
||||
def test_optional_str_missing():
|
||||
@@ -70,29 +58,16 @@ def test_model_optional_str_missing():
|
||||
client = TestClient(app)
|
||||
response = client.post("/model-optional-str")
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"input": None,
|
||||
"loc": ["body"],
|
||||
"msg": "Field required",
|
||||
"type": "missing",
|
||||
},
|
||||
],
|
||||
}
|
||||
) | IsDict(
|
||||
{
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
],
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"input": None,
|
||||
"loc": ["body"],
|
||||
"msg": "Field required",
|
||||
"type": "missing",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -148,27 +123,16 @@ def test_optional_str_alias_schema(path: str):
|
||||
openapi = app.openapi()
|
||||
body_model_name = get_body_model_name(openapi, path)
|
||||
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == IsDict(
|
||||
{
|
||||
"properties": {
|
||||
"p_alias": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "P Alias",
|
||||
},
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == {
|
||||
"properties": {
|
||||
"p_alias": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "P Alias",
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"properties": {
|
||||
"p_alias": {"type": "string", "title": "P Alias"},
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
)
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
|
||||
|
||||
def test_optional_alias_missing():
|
||||
@@ -182,29 +146,16 @@ def test_model_optional_alias_missing():
|
||||
client = TestClient(app)
|
||||
response = client.post("/model-optional-alias")
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"input": None,
|
||||
"loc": ["body"],
|
||||
"msg": "Field required",
|
||||
"type": "missing",
|
||||
},
|
||||
],
|
||||
}
|
||||
) | IsDict(
|
||||
{
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
],
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"input": None,
|
||||
"loc": ["body"],
|
||||
"msg": "Field required",
|
||||
"type": "missing",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -274,27 +225,16 @@ def test_optional_validation_alias_schema(path: str):
|
||||
openapi = app.openapi()
|
||||
body_model_name = get_body_model_name(openapi, path)
|
||||
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == IsDict(
|
||||
{
|
||||
"properties": {
|
||||
"p_val_alias": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "P Val Alias",
|
||||
},
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == {
|
||||
"properties": {
|
||||
"p_val_alias": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "P Val Alias",
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"properties": {
|
||||
"p_val_alias": {"type": "string", "title": "P Val Alias"},
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
)
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
|
||||
|
||||
def test_optional_validation_alias_missing():
|
||||
@@ -308,29 +248,16 @@ def test_model_optional_validation_alias_missing():
|
||||
client = TestClient(app)
|
||||
response = client.post("/model-optional-validation-alias")
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"input": None,
|
||||
"loc": ["body"],
|
||||
"msg": "Field required",
|
||||
"type": "missing",
|
||||
},
|
||||
],
|
||||
}
|
||||
) | IsDict(
|
||||
{
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
],
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"input": None,
|
||||
"loc": ["body"],
|
||||
"msg": "Field required",
|
||||
"type": "missing",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -413,27 +340,16 @@ def test_optional_alias_and_validation_alias_schema(path: str):
|
||||
openapi = app.openapi()
|
||||
body_model_name = get_body_model_name(openapi, path)
|
||||
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == IsDict(
|
||||
{
|
||||
"properties": {
|
||||
"p_val_alias": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "P Val Alias",
|
||||
},
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == {
|
||||
"properties": {
|
||||
"p_val_alias": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "P Val Alias",
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"properties": {
|
||||
"p_val_alias": {"type": "string", "title": "P Val Alias"},
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
)
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
|
||||
|
||||
def test_optional_alias_and_validation_alias_missing():
|
||||
@@ -447,29 +363,16 @@ def test_model_optional_alias_and_validation_alias_missing():
|
||||
client = TestClient(app)
|
||||
response = client.post("/model-optional-alias-and-validation-alias")
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"input": None,
|
||||
"loc": ["body"],
|
||||
"msg": "Field required",
|
||||
"type": "missing",
|
||||
},
|
||||
],
|
||||
}
|
||||
) | IsDict(
|
||||
{
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
],
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"input": None,
|
||||
"loc": ["body"],
|
||||
"msg": "Field required",
|
||||
"type": "missing",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from typing import Annotated, Any, Union
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict, IsOneOf
|
||||
from dirty_equals import IsOneOf
|
||||
from fastapi import Body, FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import BaseModel, Field
|
||||
@@ -55,29 +55,16 @@ def test_required_str_missing(path: str, json: Union[dict[str, Any], None]):
|
||||
client = TestClient(app)
|
||||
response = client.post(path, json=json)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": IsOneOf(["body"], ["body", "p"]),
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {}),
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": IsOneOf(["body"], ["body", "p"]),
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": IsOneOf(["body"], ["body", "p"]),
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {}),
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -141,29 +128,16 @@ def test_required_alias_missing(path: str, json: Union[dict[str, Any], None]):
|
||||
client = TestClient(app)
|
||||
response = client.post(path, json=json)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": IsOneOf(["body", "p_alias"], ["body"]),
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {}),
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": IsOneOf(["body", "p_alias"], ["body"]),
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": IsOneOf(["body", "p_alias"], ["body"]),
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {}),
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -174,29 +148,16 @@ def test_required_alias_by_name(path: str):
|
||||
client = TestClient(app)
|
||||
response = client.post(path, json={"p": "hello"})
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {"p": "hello"}),
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": IsOneOf(["body", "p_alias"], ["body"]),
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {"p": "hello"}),
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from typing import Annotated, Optional
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import Cookie, FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import BaseModel, Field
|
||||
@@ -32,26 +31,15 @@ async def read_model_optional_str(p: Annotated[CookieModelOptionalStr, Cookie()]
|
||||
)
|
||||
def test_optional_str_schema(path: str):
|
||||
assert app.openapi()["paths"][path]["get"]["parameters"] == [
|
||||
IsDict(
|
||||
{
|
||||
"required": False,
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "P",
|
||||
},
|
||||
"name": "p",
|
||||
"in": "cookie",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"required": False,
|
||||
"schema": {"title": "P", "type": "string"},
|
||||
"name": "p",
|
||||
"in": "cookie",
|
||||
}
|
||||
)
|
||||
{
|
||||
"required": False,
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "P",
|
||||
},
|
||||
"name": "p",
|
||||
"in": "cookie",
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -104,26 +92,15 @@ async def read_model_optional_alias(p: Annotated[CookieModelOptionalAlias, Cooki
|
||||
)
|
||||
def test_optional_str_alias_schema(path: str):
|
||||
assert app.openapi()["paths"][path]["get"]["parameters"] == [
|
||||
IsDict(
|
||||
{
|
||||
"required": False,
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "P Alias",
|
||||
},
|
||||
"name": "p_alias",
|
||||
"in": "cookie",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"required": False,
|
||||
"schema": {"title": "P Alias", "type": "string"},
|
||||
"name": "p_alias",
|
||||
"in": "cookie",
|
||||
}
|
||||
)
|
||||
{
|
||||
"required": False,
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "P Alias",
|
||||
},
|
||||
"name": "p_alias",
|
||||
"in": "cookie",
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from typing import Annotated
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict, IsOneOf
|
||||
from dirty_equals import IsOneOf
|
||||
from fastapi import Cookie, FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import BaseModel, Field
|
||||
@@ -49,29 +49,16 @@ def test_required_str_missing(path: str):
|
||||
client = TestClient(app)
|
||||
response = client.get(path)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["cookie", "p"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {}),
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["cookie", "p"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["cookie", "p"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {}),
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -127,29 +114,16 @@ def test_required_alias_missing(path: str):
|
||||
client = TestClient(app)
|
||||
response = client.get(path)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["cookie", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {}),
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["cookie", "p_alias"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["cookie", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {}),
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -164,32 +138,19 @@ def test_required_alias_by_name(path: str):
|
||||
client.cookies.set("p", "hello")
|
||||
response = client.get(path)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["cookie", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(
|
||||
None,
|
||||
{"p": "hello"},
|
||||
),
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["cookie", "p_alias"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["cookie", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(
|
||||
None,
|
||||
{"p": "hello"},
|
||||
),
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from typing import Annotated
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import FastAPI, File, UploadFile
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
@@ -36,27 +35,11 @@ def test_list_schema(path: str):
|
||||
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == {
|
||||
"properties": {
|
||||
"p": (
|
||||
IsDict(
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {"type": "string", "format": "binary"},
|
||||
},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P",
|
||||
},
|
||||
)
|
||||
| IsDict(
|
||||
{
|
||||
"type": "array",
|
||||
"items": {"type": "string", "format": "binary"},
|
||||
"title": "P",
|
||||
},
|
||||
)
|
||||
)
|
||||
"p": {
|
||||
"type": "array",
|
||||
"items": {"type": "string", "format": "binary"},
|
||||
"title": "P",
|
||||
},
|
||||
},
|
||||
"required": ["p"],
|
||||
"title": body_model_name,
|
||||
@@ -75,29 +58,16 @@ def test_list_missing(path: str):
|
||||
client = TestClient(app)
|
||||
response = client.post(path)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "p"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "p"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "p"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -143,27 +113,11 @@ def test_list_alias_schema(path: str):
|
||||
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == {
|
||||
"properties": {
|
||||
"p_alias": (
|
||||
IsDict(
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {"type": "string", "format": "binary"},
|
||||
},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Alias",
|
||||
},
|
||||
)
|
||||
| IsDict(
|
||||
{
|
||||
"type": "array",
|
||||
"items": {"type": "string", "format": "binary"},
|
||||
"title": "P Alias",
|
||||
},
|
||||
)
|
||||
)
|
||||
"p_alias": {
|
||||
"type": "array",
|
||||
"items": {"type": "string", "format": "binary"},
|
||||
"title": "P Alias",
|
||||
},
|
||||
},
|
||||
"required": ["p_alias"],
|
||||
"title": body_model_name,
|
||||
@@ -182,29 +136,16 @@ def test_list_alias_missing(path: str):
|
||||
client = TestClient(app)
|
||||
response = client.post(path)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "p_alias"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -218,29 +159,16 @@ def test_list_alias_by_name(path: str):
|
||||
client = TestClient(app)
|
||||
response = client.post(path, files=[("p", b"hello"), ("p", b"world")])
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "p_alias"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -291,27 +219,11 @@ def test_list_validation_alias_schema(path: str):
|
||||
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == {
|
||||
"properties": {
|
||||
"p_val_alias": (
|
||||
IsDict(
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {"type": "string", "format": "binary"},
|
||||
},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Val Alias",
|
||||
},
|
||||
)
|
||||
| IsDict(
|
||||
{
|
||||
"type": "array",
|
||||
"items": {"type": "string", "format": "binary"},
|
||||
"title": "P Val Alias",
|
||||
},
|
||||
)
|
||||
)
|
||||
"p_val_alias": {
|
||||
"type": "array",
|
||||
"items": {"type": "string", "format": "binary"},
|
||||
"title": "P Val Alias",
|
||||
},
|
||||
},
|
||||
"required": ["p_val_alias"],
|
||||
"title": body_model_name,
|
||||
@@ -424,27 +336,11 @@ def test_list_alias_and_validation_alias_schema(path: str):
|
||||
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == {
|
||||
"properties": {
|
||||
"p_val_alias": (
|
||||
IsDict(
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {"type": "string", "format": "binary"},
|
||||
},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Val Alias",
|
||||
},
|
||||
)
|
||||
| IsDict(
|
||||
{
|
||||
"type": "array",
|
||||
"items": {"type": "string", "format": "binary"},
|
||||
"title": "P Val Alias",
|
||||
},
|
||||
)
|
||||
)
|
||||
"p_val_alias": {
|
||||
"type": "array",
|
||||
"items": {"type": "string", "format": "binary"},
|
||||
"title": "P Val Alias",
|
||||
},
|
||||
},
|
||||
"required": ["p_val_alias"],
|
||||
"title": body_model_name,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from typing import Annotated, Optional
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import FastAPI, File, UploadFile
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
@@ -36,21 +35,13 @@ def test_optional_schema(path: str):
|
||||
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == {
|
||||
"properties": {
|
||||
"p": (
|
||||
IsDict(
|
||||
{
|
||||
"anyOf": [
|
||||
{"type": "string", "format": "binary"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "P", "type": "string", "format": "binary"}
|
||||
)
|
||||
),
|
||||
"p": {
|
||||
"anyOf": [
|
||||
{"type": "string", "format": "binary"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P",
|
||||
}
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
@@ -116,21 +107,13 @@ def test_optional_alias_schema(path: str):
|
||||
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == {
|
||||
"properties": {
|
||||
"p_alias": (
|
||||
IsDict(
|
||||
{
|
||||
"anyOf": [
|
||||
{"type": "string", "format": "binary"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Alias",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "P Alias", "type": "string", "format": "binary"}
|
||||
)
|
||||
),
|
||||
"p_alias": {
|
||||
"anyOf": [
|
||||
{"type": "string", "format": "binary"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Alias",
|
||||
}
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
@@ -215,21 +198,13 @@ def test_optional_validation_alias_schema(path: str):
|
||||
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == {
|
||||
"properties": {
|
||||
"p_val_alias": (
|
||||
IsDict(
|
||||
{
|
||||
"anyOf": [
|
||||
{"type": "string", "format": "binary"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Val Alias",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "P Val Alias", "type": "string", "format": "binary"}
|
||||
)
|
||||
),
|
||||
"p_val_alias": {
|
||||
"anyOf": [
|
||||
{"type": "string", "format": "binary"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Val Alias",
|
||||
}
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
@@ -319,21 +294,13 @@ def test_optional_alias_and_validation_alias_schema(path: str):
|
||||
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == {
|
||||
"properties": {
|
||||
"p_val_alias": (
|
||||
IsDict(
|
||||
{
|
||||
"anyOf": [
|
||||
{"type": "string", "format": "binary"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Val Alias",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "P Val Alias", "type": "string", "format": "binary"}
|
||||
)
|
||||
),
|
||||
"p_val_alias": {
|
||||
"anyOf": [
|
||||
{"type": "string", "format": "binary"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Val Alias",
|
||||
}
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from typing import Annotated, Optional
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import FastAPI, File, UploadFile
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
@@ -38,28 +37,16 @@ def test_optional_list_schema(path: str):
|
||||
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == {
|
||||
"properties": {
|
||||
"p": (
|
||||
IsDict(
|
||||
"p": {
|
||||
"anyOf": [
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {"type": "string", "format": "binary"},
|
||||
},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"title": "P",
|
||||
"type": "array",
|
||||
"items": {"type": "string", "format": "binary"},
|
||||
},
|
||||
)
|
||||
),
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P",
|
||||
}
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
@@ -125,28 +112,16 @@ def test_optional_list_alias_schema(path: str):
|
||||
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == {
|
||||
"properties": {
|
||||
"p_alias": (
|
||||
IsDict(
|
||||
"p_alias": {
|
||||
"anyOf": [
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {"type": "string", "format": "binary"},
|
||||
},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Alias",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"title": "P Alias",
|
||||
"type": "array",
|
||||
"items": {"type": "string", "format": "binary"},
|
||||
}
|
||||
)
|
||||
),
|
||||
},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Alias",
|
||||
}
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
@@ -228,28 +203,16 @@ def test_optional_validation_alias_schema(path: str):
|
||||
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == {
|
||||
"properties": {
|
||||
"p_val_alias": (
|
||||
IsDict(
|
||||
"p_val_alias": {
|
||||
"anyOf": [
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {"type": "string", "format": "binary"},
|
||||
},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Val Alias",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"title": "P Val Alias",
|
||||
"type": "array",
|
||||
"items": {"type": "string", "format": "binary"},
|
||||
}
|
||||
)
|
||||
),
|
||||
},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Val Alias",
|
||||
}
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
@@ -336,28 +299,16 @@ def test_optional_list_alias_and_validation_alias_schema(path: str):
|
||||
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == {
|
||||
"properties": {
|
||||
"p_val_alias": (
|
||||
IsDict(
|
||||
"p_val_alias": {
|
||||
"anyOf": [
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {"type": "string", "format": "binary"},
|
||||
},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Val Alias",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"title": "P Val Alias",
|
||||
"type": "array",
|
||||
"items": {"type": "string", "format": "binary"},
|
||||
}
|
||||
)
|
||||
),
|
||||
},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Val Alias",
|
||||
}
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from typing import Annotated
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import FastAPI, File, UploadFile
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
@@ -55,29 +54,16 @@ def test_required_missing(path: str):
|
||||
client = TestClient(app)
|
||||
response = client.post(path)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "p"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "p"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "p"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -142,29 +128,16 @@ def test_required_alias_missing(path: str):
|
||||
client = TestClient(app)
|
||||
response = client.post(path)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "p_alias"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -178,29 +151,16 @@ def test_required_alias_by_name(path: str):
|
||||
client = TestClient(app)
|
||||
response = client.post(path, files=[("p", b"hello")])
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "p_alias"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from typing import Annotated
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict, IsOneOf, IsPartialDict
|
||||
from dirty_equals import IsOneOf, IsPartialDict
|
||||
from fastapi import FastAPI, Form
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import BaseModel, Field
|
||||
@@ -58,28 +58,16 @@ def test_required_list_str_missing(path: str):
|
||||
client = TestClient(app)
|
||||
response = client.post(path)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "p"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {}),
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "p"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "p"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {}),
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -146,29 +134,16 @@ def test_required_list_alias_missing(path: str):
|
||||
client = TestClient(app)
|
||||
response = client.post(path)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {}),
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "p_alias"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {}),
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -182,29 +157,16 @@ def test_required_list_alias_by_name(path: str):
|
||||
client = TestClient(app)
|
||||
response = client.post(path, data={"p": ["hello", "world"]})
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {"p": ["hello", "world"]}),
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "p_alias"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {"p": ["hello", "world"]}),
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from typing import Annotated, Optional
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import FastAPI, Form
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import BaseModel, Field
|
||||
@@ -38,30 +37,19 @@ def test_optional_list_str_schema(path: str):
|
||||
openapi = app.openapi()
|
||||
body_model_name = get_body_model_name(openapi, path)
|
||||
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == IsDict(
|
||||
{
|
||||
"properties": {
|
||||
"p": {
|
||||
"anyOf": [
|
||||
{"items": {"type": "string"}, "type": "array"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P",
|
||||
},
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == {
|
||||
"properties": {
|
||||
"p": {
|
||||
"anyOf": [
|
||||
{"items": {"type": "string"}, "type": "array"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P",
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"properties": {
|
||||
"p": {"items": {"type": "string"}, "type": "array", "title": "P"},
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
)
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -119,34 +107,19 @@ def test_optional_list_str_alias_schema(path: str):
|
||||
openapi = app.openapi()
|
||||
body_model_name = get_body_model_name(openapi, path)
|
||||
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == IsDict(
|
||||
{
|
||||
"properties": {
|
||||
"p_alias": {
|
||||
"anyOf": [
|
||||
{"items": {"type": "string"}, "type": "array"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Alias",
|
||||
},
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == {
|
||||
"properties": {
|
||||
"p_alias": {
|
||||
"anyOf": [
|
||||
{"items": {"type": "string"}, "type": "array"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Alias",
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"properties": {
|
||||
"p_alias": {
|
||||
"items": {"type": "string"},
|
||||
"type": "array",
|
||||
"title": "P Alias",
|
||||
},
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
)
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -217,34 +190,19 @@ def test_optional_list_validation_alias_schema(path: str):
|
||||
openapi = app.openapi()
|
||||
body_model_name = get_body_model_name(openapi, path)
|
||||
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == IsDict(
|
||||
{
|
||||
"properties": {
|
||||
"p_val_alias": {
|
||||
"anyOf": [
|
||||
{"items": {"type": "string"}, "type": "array"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Val Alias",
|
||||
},
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == {
|
||||
"properties": {
|
||||
"p_val_alias": {
|
||||
"anyOf": [
|
||||
{"items": {"type": "string"}, "type": "array"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Val Alias",
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"properties": {
|
||||
"p_val_alias": {
|
||||
"items": {"type": "string"},
|
||||
"type": "array",
|
||||
"title": "P Val Alias",
|
||||
},
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
)
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -326,34 +284,19 @@ def test_optional_list_alias_and_validation_alias_schema(path: str):
|
||||
openapi = app.openapi()
|
||||
body_model_name = get_body_model_name(openapi, path)
|
||||
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == IsDict(
|
||||
{
|
||||
"properties": {
|
||||
"p_val_alias": {
|
||||
"anyOf": [
|
||||
{"items": {"type": "string"}, "type": "array"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Val Alias",
|
||||
},
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == {
|
||||
"properties": {
|
||||
"p_val_alias": {
|
||||
"anyOf": [
|
||||
{"items": {"type": "string"}, "type": "array"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Val Alias",
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"properties": {
|
||||
"p_val_alias": {
|
||||
"items": {"type": "string"},
|
||||
"type": "array",
|
||||
"title": "P Val Alias",
|
||||
},
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
)
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from typing import Annotated, Optional
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import FastAPI, Form
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import BaseModel, Field
|
||||
@@ -36,27 +35,16 @@ def test_optional_str_schema(path: str):
|
||||
openapi = app.openapi()
|
||||
body_model_name = get_body_model_name(openapi, path)
|
||||
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == IsDict(
|
||||
{
|
||||
"properties": {
|
||||
"p": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "P",
|
||||
},
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == {
|
||||
"properties": {
|
||||
"p": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "P",
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"properties": {
|
||||
"p": {"type": "string", "title": "P"},
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
)
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -112,27 +100,16 @@ def test_optional_str_alias_schema(path: str):
|
||||
openapi = app.openapi()
|
||||
body_model_name = get_body_model_name(openapi, path)
|
||||
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == IsDict(
|
||||
{
|
||||
"properties": {
|
||||
"p_alias": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "P Alias",
|
||||
},
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == {
|
||||
"properties": {
|
||||
"p_alias": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "P Alias",
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"properties": {
|
||||
"p_alias": {"type": "string", "title": "P Alias"},
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
)
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -200,27 +177,16 @@ def test_optional_validation_alias_schema(path: str):
|
||||
openapi = app.openapi()
|
||||
body_model_name = get_body_model_name(openapi, path)
|
||||
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == IsDict(
|
||||
{
|
||||
"properties": {
|
||||
"p_val_alias": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "P Val Alias",
|
||||
},
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == {
|
||||
"properties": {
|
||||
"p_val_alias": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "P Val Alias",
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"properties": {
|
||||
"p_val_alias": {"type": "string", "title": "P Val Alias"},
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
)
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -303,27 +269,16 @@ def test_optional_alias_and_validation_alias_schema(path: str):
|
||||
openapi = app.openapi()
|
||||
body_model_name = get_body_model_name(openapi, path)
|
||||
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == IsDict(
|
||||
{
|
||||
"properties": {
|
||||
"p_val_alias": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "P Val Alias",
|
||||
},
|
||||
assert app.openapi()["components"]["schemas"][body_model_name] == {
|
||||
"properties": {
|
||||
"p_val_alias": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "P Val Alias",
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"properties": {
|
||||
"p_val_alias": {"type": "string", "title": "P Val Alias"},
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
)
|
||||
},
|
||||
"title": body_model_name,
|
||||
"type": "object",
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from typing import Annotated
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict, IsOneOf
|
||||
from dirty_equals import IsOneOf
|
||||
from fastapi import FastAPI, Form
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import BaseModel, Field
|
||||
@@ -54,29 +54,16 @@ def test_required_str_missing(path: str):
|
||||
client = TestClient(app)
|
||||
response = client.post(path)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "p"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {}),
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "p"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "p"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {}),
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -137,29 +124,16 @@ def test_required_alias_missing(path: str):
|
||||
client = TestClient(app)
|
||||
response = client.post(path)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {}),
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "p_alias"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {}),
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -170,29 +144,16 @@ def test_required_alias_by_name(path: str):
|
||||
client = TestClient(app)
|
||||
response = client.post(path, data={"p": "hello"})
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {"p": "hello"}),
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "p_alias"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {"p": "hello"}),
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from typing import Annotated
|
||||
|
||||
import pytest
|
||||
from dirty_equals import AnyThing, IsDict, IsOneOf, IsPartialDict
|
||||
from dirty_equals import AnyThing, IsOneOf, IsPartialDict
|
||||
from fastapi import FastAPI, Header
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import BaseModel, Field
|
||||
@@ -53,28 +53,16 @@ def test_required_list_str_missing(path: str):
|
||||
client = TestClient(app)
|
||||
response = client.get(path)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "p"],
|
||||
"msg": "Field required",
|
||||
"input": AnyThing,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["header", "p"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "p"],
|
||||
"msg": "Field required",
|
||||
"input": AnyThing,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -135,29 +123,16 @@ def test_required_list_alias_missing(path: str):
|
||||
client = TestClient(app)
|
||||
response = client.get(path)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": AnyThing,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["header", "p_alias"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": AnyThing,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -171,29 +146,16 @@ def test_required_list_alias_by_name(path: str):
|
||||
client = TestClient(app)
|
||||
response = client.get(path, headers=[("p", "hello"), ("p", "world")])
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, IsPartialDict({"p": ["hello", "world"]})),
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["header", "p_alias"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, IsPartialDict({"p": ["hello", "world"]})),
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from typing import Annotated, Optional
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import FastAPI, Header
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import BaseModel, Field
|
||||
@@ -36,29 +35,18 @@ async def read_model_optional_list_str(
|
||||
)
|
||||
def test_optional_list_str_schema(path: str):
|
||||
assert app.openapi()["paths"][path]["get"]["parameters"] == [
|
||||
IsDict(
|
||||
{
|
||||
"required": False,
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{"items": {"type": "string"}, "type": "array"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P",
|
||||
},
|
||||
"name": "p",
|
||||
"in": "header",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"required": False,
|
||||
"schema": {"items": {"type": "string"}, "type": "array", "title": "P"},
|
||||
"name": "p",
|
||||
"in": "header",
|
||||
}
|
||||
)
|
||||
{
|
||||
"required": False,
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{"items": {"type": "string"}, "type": "array"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P",
|
||||
},
|
||||
"name": "p",
|
||||
"in": "header",
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -112,33 +100,18 @@ async def read_model_optional_list_alias(
|
||||
)
|
||||
def test_optional_list_str_alias_schema(path: str):
|
||||
assert app.openapi()["paths"][path]["get"]["parameters"] == [
|
||||
IsDict(
|
||||
{
|
||||
"required": False,
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{"items": {"type": "string"}, "type": "array"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Alias",
|
||||
},
|
||||
"name": "p_alias",
|
||||
"in": "header",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"required": False,
|
||||
"schema": {
|
||||
"items": {"type": "string"},
|
||||
"type": "array",
|
||||
"title": "P Alias",
|
||||
},
|
||||
"name": "p_alias",
|
||||
"in": "header",
|
||||
}
|
||||
)
|
||||
{
|
||||
"required": False,
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{"items": {"type": "string"}, "type": "array"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Alias",
|
||||
},
|
||||
"name": "p_alias",
|
||||
"in": "header",
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from typing import Annotated, Optional
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import FastAPI, Header
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import BaseModel, Field
|
||||
@@ -32,26 +31,15 @@ async def read_model_optional_str(p: Annotated[HeaderModelOptionalStr, Header()]
|
||||
)
|
||||
def test_optional_str_schema(path: str):
|
||||
assert app.openapi()["paths"][path]["get"]["parameters"] == [
|
||||
IsDict(
|
||||
{
|
||||
"required": False,
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "P",
|
||||
},
|
||||
"name": "p",
|
||||
"in": "header",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"required": False,
|
||||
"schema": {"title": "P", "type": "string"},
|
||||
"name": "p",
|
||||
"in": "header",
|
||||
}
|
||||
)
|
||||
{
|
||||
"required": False,
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "P",
|
||||
},
|
||||
"name": "p",
|
||||
"in": "header",
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -103,26 +91,15 @@ async def read_model_optional_alias(p: Annotated[HeaderModelOptionalAlias, Heade
|
||||
)
|
||||
def test_optional_str_alias_schema(path: str):
|
||||
assert app.openapi()["paths"][path]["get"]["parameters"] == [
|
||||
IsDict(
|
||||
{
|
||||
"required": False,
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "P Alias",
|
||||
},
|
||||
"name": "p_alias",
|
||||
"in": "header",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"required": False,
|
||||
"schema": {"title": "P Alias", "type": "string"},
|
||||
"name": "p_alias",
|
||||
"in": "header",
|
||||
}
|
||||
)
|
||||
{
|
||||
"required": False,
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "P Alias",
|
||||
},
|
||||
"name": "p_alias",
|
||||
"in": "header",
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from typing import Annotated
|
||||
|
||||
import pytest
|
||||
from dirty_equals import AnyThing, IsDict, IsOneOf, IsPartialDict
|
||||
from dirty_equals import AnyThing, IsOneOf, IsPartialDict
|
||||
from fastapi import FastAPI, Header
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import BaseModel, Field
|
||||
@@ -49,29 +49,16 @@ def test_required_str_missing(path: str):
|
||||
client = TestClient(app)
|
||||
response = client.get(path)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "p"],
|
||||
"msg": "Field required",
|
||||
"input": AnyThing,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["header", "p"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "p"],
|
||||
"msg": "Field required",
|
||||
"input": AnyThing,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -126,29 +113,16 @@ def test_required_alias_missing(path: str):
|
||||
client = TestClient(app)
|
||||
response = client.get(path)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": AnyThing,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["header", "p_alias"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": AnyThing,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -162,29 +136,16 @@ def test_required_alias_by_name(path: str):
|
||||
client = TestClient(app)
|
||||
response = client.get(path, headers={"p": "hello"})
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, IsPartialDict({"p": "hello"})),
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["header", "p_alias"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, IsPartialDict({"p": "hello"})),
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from typing import Annotated
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict, IsOneOf
|
||||
from dirty_equals import IsOneOf
|
||||
from fastapi import FastAPI, Query
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import BaseModel, Field
|
||||
@@ -53,28 +53,16 @@ def test_required_list_str_missing(path: str):
|
||||
client = TestClient(app)
|
||||
response = client.get(path)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "p"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {}),
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "p"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "p"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {}),
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -135,29 +123,16 @@ def test_required_list_alias_missing(path: str):
|
||||
client = TestClient(app)
|
||||
response = client.get(path)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {}),
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "p_alias"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {}),
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -171,29 +146,16 @@ def test_required_list_alias_by_name(path: str):
|
||||
client = TestClient(app)
|
||||
response = client.get(f"{path}?p=hello&p=world")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {"p": ["hello", "world"]}),
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "p_alias"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {"p": ["hello", "world"]}),
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from typing import Annotated, Optional
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import FastAPI, Query
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import BaseModel, Field
|
||||
@@ -36,29 +35,18 @@ async def read_model_optional_list_str(
|
||||
)
|
||||
def test_optional_list_str_schema(path: str):
|
||||
assert app.openapi()["paths"][path]["get"]["parameters"] == [
|
||||
IsDict(
|
||||
{
|
||||
"required": False,
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{"items": {"type": "string"}, "type": "array"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P",
|
||||
},
|
||||
"name": "p",
|
||||
"in": "query",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"required": False,
|
||||
"schema": {"items": {"type": "string"}, "type": "array", "title": "P"},
|
||||
"name": "p",
|
||||
"in": "query",
|
||||
}
|
||||
)
|
||||
{
|
||||
"required": False,
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{"items": {"type": "string"}, "type": "array"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P",
|
||||
},
|
||||
"name": "p",
|
||||
"in": "query",
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -112,33 +100,18 @@ async def read_model_optional_list_alias(
|
||||
)
|
||||
def test_optional_list_str_alias_schema(path: str):
|
||||
assert app.openapi()["paths"][path]["get"]["parameters"] == [
|
||||
IsDict(
|
||||
{
|
||||
"required": False,
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{"items": {"type": "string"}, "type": "array"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Alias",
|
||||
},
|
||||
"name": "p_alias",
|
||||
"in": "query",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"required": False,
|
||||
"schema": {
|
||||
"items": {"type": "string"},
|
||||
"type": "array",
|
||||
"title": "P Alias",
|
||||
},
|
||||
"name": "p_alias",
|
||||
"in": "query",
|
||||
}
|
||||
)
|
||||
{
|
||||
"required": False,
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{"items": {"type": "string"}, "type": "array"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "P Alias",
|
||||
},
|
||||
"name": "p_alias",
|
||||
"in": "query",
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from typing import Annotated, Optional
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import FastAPI, Query
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import BaseModel, Field
|
||||
@@ -32,26 +31,15 @@ async def read_model_optional_str(p: Annotated[QueryModelOptionalStr, Query()]):
|
||||
)
|
||||
def test_optional_str_schema(path: str):
|
||||
assert app.openapi()["paths"][path]["get"]["parameters"] == [
|
||||
IsDict(
|
||||
{
|
||||
"required": False,
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "P",
|
||||
},
|
||||
"name": "p",
|
||||
"in": "query",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"required": False,
|
||||
"schema": {"title": "P", "type": "string"},
|
||||
"name": "p",
|
||||
"in": "query",
|
||||
}
|
||||
)
|
||||
{
|
||||
"required": False,
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "P",
|
||||
},
|
||||
"name": "p",
|
||||
"in": "query",
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -103,26 +91,15 @@ async def read_model_optional_alias(p: Annotated[QueryModelOptionalAlias, Query(
|
||||
)
|
||||
def test_optional_str_alias_schema(path: str):
|
||||
assert app.openapi()["paths"][path]["get"]["parameters"] == [
|
||||
IsDict(
|
||||
{
|
||||
"required": False,
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "P Alias",
|
||||
},
|
||||
"name": "p_alias",
|
||||
"in": "query",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"required": False,
|
||||
"schema": {"title": "P Alias", "type": "string"},
|
||||
"name": "p_alias",
|
||||
"in": "query",
|
||||
}
|
||||
)
|
||||
{
|
||||
"required": False,
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "P Alias",
|
||||
},
|
||||
"name": "p_alias",
|
||||
"in": "query",
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from typing import Annotated
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict, IsOneOf
|
||||
from dirty_equals import IsOneOf
|
||||
from fastapi import FastAPI, Query
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import BaseModel, Field
|
||||
@@ -49,29 +49,16 @@ def test_required_str_missing(path: str):
|
||||
client = TestClient(app)
|
||||
response = client.get(path)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "p"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {}),
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "p"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "p"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {}),
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -126,29 +113,16 @@ def test_required_alias_missing(path: str):
|
||||
client = TestClient(app)
|
||||
response = client.get(path)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {}),
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "p_alias"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(None, {}),
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -162,32 +136,19 @@ def test_required_alias_by_name(path: str):
|
||||
client = TestClient(app)
|
||||
response = client.get(f"{path}?p=hello")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(
|
||||
None,
|
||||
{"p": "hello"},
|
||||
),
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "p_alias"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "p_alias"],
|
||||
"msg": "Field required",
|
||||
"input": IsOneOf(
|
||||
None,
|
||||
{"p": "hello"},
|
||||
),
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from typing import Union
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import Body, Cookie, FastAPI, Header, Path, Query
|
||||
from fastapi.exceptions import FastAPIDeprecationWarning
|
||||
from fastapi.testclient import TestClient
|
||||
@@ -336,28 +335,13 @@ def test_openapi_schema():
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": IsDict(
|
||||
{
|
||||
"$ref": "#/components/schemas/Item",
|
||||
"examples": [
|
||||
{"data": "Data in Body examples, example1"},
|
||||
{"data": "Data in Body examples, example2"},
|
||||
],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove this when deprecating Pydantic v1
|
||||
{
|
||||
"allOf": [
|
||||
{"$ref": "#/components/schemas/Item"}
|
||||
],
|
||||
"title": "Item",
|
||||
"examples": [
|
||||
{"data": "Data in Body examples, example1"},
|
||||
{"data": "Data in Body examples, example2"},
|
||||
],
|
||||
}
|
||||
)
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Item",
|
||||
"examples": [
|
||||
{"data": "Data in Body examples, example1"},
|
||||
{"data": "Data in Body examples, example2"},
|
||||
],
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": True,
|
||||
@@ -387,28 +371,13 @@ def test_openapi_schema():
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": IsDict(
|
||||
{
|
||||
"$ref": "#/components/schemas/Item",
|
||||
"examples": [
|
||||
{"data": "examples example_examples 1"},
|
||||
{"data": "examples example_examples 2"},
|
||||
],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove this when deprecating Pydantic v1
|
||||
{
|
||||
"allOf": [
|
||||
{"$ref": "#/components/schemas/Item"}
|
||||
],
|
||||
"title": "Item",
|
||||
"examples": [
|
||||
{"data": "examples example_examples 1"},
|
||||
{"data": "examples example_examples 2"},
|
||||
],
|
||||
},
|
||||
),
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Item",
|
||||
"examples": [
|
||||
{"data": "examples example_examples 1"},
|
||||
{"data": "examples example_examples 2"},
|
||||
],
|
||||
},
|
||||
"example": {"data": "Overridden example"},
|
||||
}
|
||||
},
|
||||
@@ -539,16 +508,10 @@ def test_openapi_schema():
|
||||
"parameters": [
|
||||
{
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Data",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: Remove this when deprecating Pydantic v1
|
||||
{"title": "Data", "type": "string"}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Data",
|
||||
},
|
||||
"example": "query1",
|
||||
"name": "data",
|
||||
"in": "query",
|
||||
@@ -579,21 +542,11 @@ def test_openapi_schema():
|
||||
"parameters": [
|
||||
{
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Data",
|
||||
"examples": ["query1", "query2"],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: Remove this when deprecating Pydantic v1
|
||||
{
|
||||
"type": "string",
|
||||
"title": "Data",
|
||||
"examples": ["query1", "query2"],
|
||||
}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Data",
|
||||
"examples": ["query1", "query2"],
|
||||
},
|
||||
"name": "data",
|
||||
"in": "query",
|
||||
}
|
||||
@@ -623,21 +576,11 @@ def test_openapi_schema():
|
||||
"parameters": [
|
||||
{
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Data",
|
||||
"examples": ["query1", "query2"],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: Remove this when deprecating Pydantic v1
|
||||
{
|
||||
"type": "string",
|
||||
"title": "Data",
|
||||
"examples": ["query1", "query2"],
|
||||
}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Data",
|
||||
"examples": ["query1", "query2"],
|
||||
},
|
||||
"example": "query_overridden",
|
||||
"name": "data",
|
||||
"in": "query",
|
||||
@@ -668,16 +611,10 @@ def test_openapi_schema():
|
||||
"parameters": [
|
||||
{
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Data",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: Remove this when deprecating Pydantic v1
|
||||
{"title": "Data", "type": "string"}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Data",
|
||||
},
|
||||
"example": "header1",
|
||||
"name": "data",
|
||||
"in": "header",
|
||||
@@ -708,21 +645,11 @@ def test_openapi_schema():
|
||||
"parameters": [
|
||||
{
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Data",
|
||||
"examples": ["header1", "header2"],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: Remove this when deprecating Pydantic v1
|
||||
{
|
||||
"type": "string",
|
||||
"title": "Data",
|
||||
"examples": ["header1", "header2"],
|
||||
}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Data",
|
||||
"examples": ["header1", "header2"],
|
||||
},
|
||||
"name": "data",
|
||||
"in": "header",
|
||||
}
|
||||
@@ -752,21 +679,11 @@ def test_openapi_schema():
|
||||
"parameters": [
|
||||
{
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Data",
|
||||
"examples": ["header1", "header2"],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: Remove this when deprecating Pydantic v1
|
||||
{
|
||||
"title": "Data",
|
||||
"type": "string",
|
||||
"examples": ["header1", "header2"],
|
||||
}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Data",
|
||||
"examples": ["header1", "header2"],
|
||||
},
|
||||
"example": "header_overridden",
|
||||
"name": "data",
|
||||
"in": "header",
|
||||
@@ -797,16 +714,10 @@ def test_openapi_schema():
|
||||
"parameters": [
|
||||
{
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Data",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: Remove this when deprecating Pydantic v1
|
||||
{"title": "Data", "type": "string"}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Data",
|
||||
},
|
||||
"example": "cookie1",
|
||||
"name": "data",
|
||||
"in": "cookie",
|
||||
@@ -837,21 +748,11 @@ def test_openapi_schema():
|
||||
"parameters": [
|
||||
{
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Data",
|
||||
"examples": ["cookie1", "cookie2"],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: Remove this when deprecating Pydantic v1
|
||||
{
|
||||
"title": "Data",
|
||||
"type": "string",
|
||||
"examples": ["cookie1", "cookie2"],
|
||||
}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Data",
|
||||
"examples": ["cookie1", "cookie2"],
|
||||
},
|
||||
"name": "data",
|
||||
"in": "cookie",
|
||||
}
|
||||
@@ -881,21 +782,11 @@ def test_openapi_schema():
|
||||
"parameters": [
|
||||
{
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Data",
|
||||
"examples": ["cookie1", "cookie2"],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: Remove this when deprecating Pydantic v1
|
||||
{
|
||||
"title": "Data",
|
||||
"type": "string",
|
||||
"examples": ["cookie1", "cookie2"],
|
||||
}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Data",
|
||||
"examples": ["cookie1", "cookie2"],
|
||||
},
|
||||
"example": "cookie_overridden",
|
||||
"name": "data",
|
||||
"in": "cookie",
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import Depends, FastAPI, Security
|
||||
from fastapi.security import OAuth2, OAuth2PasswordRequestFormStrict
|
||||
from fastapi.testclient import TestClient
|
||||
@@ -64,79 +63,43 @@ def test_security_oauth2_password_bearer_no_header():
|
||||
def test_strict_login_no_data():
|
||||
response = client.post("/login")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "grant_type"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "username"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "password"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "grant_type"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
{
|
||||
"loc": ["body", "username"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
{
|
||||
"loc": ["body", "password"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "grant_type"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "username"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "password"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_strict_login_no_grant_type():
|
||||
response = client.post("/login", data={"username": "johndoe", "password": "secret"})
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "grant_type"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "grant_type"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "grant_type"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -153,31 +116,17 @@ def test_strict_login_incorrect_grant_type(grant_type: str):
|
||||
data={"username": "johndoe", "password": "secret", "grant_type": grant_type},
|
||||
)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "string_pattern_mismatch",
|
||||
"loc": ["body", "grant_type"],
|
||||
"msg": "String should match pattern '^password$'",
|
||||
"input": grant_type,
|
||||
"ctx": {"pattern": "^password$"},
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "grant_type"],
|
||||
"msg": 'string does not match regex "^password$"',
|
||||
"type": "value_error.str.regex",
|
||||
"ctx": {"pattern": "^password$"},
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "string_pattern_mismatch",
|
||||
"loc": ["body", "grant_type"],
|
||||
"msg": "String should match pattern '^password$'",
|
||||
"input": grant_type,
|
||||
"ctx": {"pattern": "^password$"},
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_strict_login_correct_grant_type():
|
||||
@@ -264,26 +213,14 @@ def test_openapi_schema():
|
||||
"username": {"title": "Username", "type": "string"},
|
||||
"password": {"title": "Password", "type": "string"},
|
||||
"scope": {"title": "Scope", "type": "string", "default": ""},
|
||||
"client_id": IsDict(
|
||||
{
|
||||
"title": "Client Id",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Client Id", "type": "string"}
|
||||
),
|
||||
"client_secret": IsDict(
|
||||
{
|
||||
"title": "Client Secret",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Client Secret", "type": "string"}
|
||||
),
|
||||
"client_id": {
|
||||
"title": "Client Id",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
},
|
||||
"client_secret": {
|
||||
"title": "Client Secret",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
},
|
||||
},
|
||||
},
|
||||
"ValidationError": {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from typing import Optional
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import Depends, FastAPI, Security
|
||||
from fastapi.security import OAuth2, OAuth2PasswordRequestFormStrict
|
||||
from fastapi.testclient import TestClient
|
||||
@@ -67,79 +66,43 @@ def test_security_oauth2_password_bearer_no_header():
|
||||
def test_strict_login_no_data():
|
||||
response = client.post("/login")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "grant_type"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "username"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "password"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "grant_type"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
{
|
||||
"loc": ["body", "username"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
{
|
||||
"loc": ["body", "password"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "grant_type"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "username"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "password"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_strict_login_no_grant_type():
|
||||
response = client.post("/login", data={"username": "johndoe", "password": "secret"})
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "grant_type"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "grant_type"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "grant_type"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -156,31 +119,17 @@ def test_strict_login_incorrect_grant_type(grant_type: str):
|
||||
data={"username": "johndoe", "password": "secret", "grant_type": grant_type},
|
||||
)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "string_pattern_mismatch",
|
||||
"loc": ["body", "grant_type"],
|
||||
"msg": "String should match pattern '^password$'",
|
||||
"input": grant_type,
|
||||
"ctx": {"pattern": "^password$"},
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "grant_type"],
|
||||
"msg": 'string does not match regex "^password$"',
|
||||
"type": "value_error.str.regex",
|
||||
"ctx": {"pattern": "^password$"},
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "string_pattern_mismatch",
|
||||
"loc": ["body", "grant_type"],
|
||||
"msg": "String should match pattern '^password$'",
|
||||
"input": grant_type,
|
||||
"ctx": {"pattern": "^password$"},
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_strict_login_correct_data():
|
||||
@@ -267,26 +216,14 @@ def test_openapi_schema():
|
||||
"username": {"title": "Username", "type": "string"},
|
||||
"password": {"title": "Password", "type": "string"},
|
||||
"scope": {"title": "Scope", "type": "string", "default": ""},
|
||||
"client_id": IsDict(
|
||||
{
|
||||
"title": "Client Id",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Client Id", "type": "string"}
|
||||
),
|
||||
"client_secret": IsDict(
|
||||
{
|
||||
"title": "Client Secret",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Client Secret", "type": "string"}
|
||||
),
|
||||
"client_id": {
|
||||
"title": "Client Id",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
},
|
||||
"client_secret": {
|
||||
"title": "Client Secret",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
},
|
||||
},
|
||||
},
|
||||
"ValidationError": {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from typing import Optional
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import Depends, FastAPI, Security
|
||||
from fastapi.security import OAuth2, OAuth2PasswordRequestFormStrict
|
||||
from fastapi.testclient import TestClient
|
||||
@@ -68,79 +67,43 @@ def test_security_oauth2_password_bearer_no_header():
|
||||
def test_strict_login_None():
|
||||
response = client.post("/login", data=None)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "grant_type"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "username"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "password"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "grant_type"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
{
|
||||
"loc": ["body", "username"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
{
|
||||
"loc": ["body", "password"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "grant_type"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "username"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "password"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_strict_login_no_grant_type():
|
||||
response = client.post("/login", data={"username": "johndoe", "password": "secret"})
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "grant_type"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "grant_type"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "grant_type"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -157,31 +120,17 @@ def test_strict_login_incorrect_grant_type(grant_type: str):
|
||||
data={"username": "johndoe", "password": "secret", "grant_type": grant_type},
|
||||
)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "string_pattern_mismatch",
|
||||
"loc": ["body", "grant_type"],
|
||||
"msg": "String should match pattern '^password$'",
|
||||
"input": grant_type,
|
||||
"ctx": {"pattern": "^password$"},
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "grant_type"],
|
||||
"msg": 'string does not match regex "^password$"',
|
||||
"type": "value_error.str.regex",
|
||||
"ctx": {"pattern": "^password$"},
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "string_pattern_mismatch",
|
||||
"loc": ["body", "grant_type"],
|
||||
"msg": "String should match pattern '^password$'",
|
||||
"input": grant_type,
|
||||
"ctx": {"pattern": "^password$"},
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_strict_login_correct_correct_grant_type():
|
||||
@@ -268,26 +217,14 @@ def test_openapi_schema():
|
||||
"username": {"title": "Username", "type": "string"},
|
||||
"password": {"title": "Password", "type": "string"},
|
||||
"scope": {"title": "Scope", "type": "string", "default": ""},
|
||||
"client_id": IsDict(
|
||||
{
|
||||
"title": "Client Id",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Client Id", "type": "string"}
|
||||
),
|
||||
"client_secret": IsDict(
|
||||
{
|
||||
"title": "Client Secret",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Client Secret", "type": "string"}
|
||||
),
|
||||
"client_id": {
|
||||
"title": "Client Id",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
},
|
||||
"client_secret": {
|
||||
"title": "Client Secret",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
},
|
||||
},
|
||||
},
|
||||
"ValidationError": {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from typing import Optional
|
||||
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import APIRouter, FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import BaseModel, HttpUrl
|
||||
@@ -99,30 +98,18 @@ def test_openapi_schema():
|
||||
"parameters": [
|
||||
{
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"title": "Callback Url",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uri",
|
||||
"minLength": 1,
|
||||
"maxLength": 2083,
|
||||
},
|
||||
{"type": "null"},
|
||||
],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"title": "Callback Url",
|
||||
"maxLength": 2083,
|
||||
"minLength": 1,
|
||||
"type": "string",
|
||||
"format": "uri",
|
||||
}
|
||||
),
|
||||
"schema": {
|
||||
"title": "Callback Url",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uri",
|
||||
"minLength": 1,
|
||||
"maxLength": 2083,
|
||||
},
|
||||
{"type": "null"},
|
||||
],
|
||||
},
|
||||
"name": "callback_url",
|
||||
"in": "query",
|
||||
}
|
||||
@@ -262,16 +249,10 @@ def test_openapi_schema():
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {"title": "Id", "type": "string"},
|
||||
"title": IsDict(
|
||||
{
|
||||
"title": "Title",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Title", "type": "string"}
|
||||
),
|
||||
"title": {
|
||||
"title": "Title",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
},
|
||||
"customer": {"title": "Customer", "type": "string"},
|
||||
"total": {"title": "Total", "type": "number"},
|
||||
},
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import FastAPI, Form
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import BaseModel
|
||||
@@ -125,31 +124,16 @@ def test_openapi_schema():
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": IsDict(
|
||||
{
|
||||
"title": "Square",
|
||||
"maxItems": 2,
|
||||
"minItems": 2,
|
||||
"type": "array",
|
||||
"prefixItems": [
|
||||
{"$ref": "#/components/schemas/Coordinate"},
|
||||
{"$ref": "#/components/schemas/Coordinate"},
|
||||
],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"title": "Square",
|
||||
"maxItems": 2,
|
||||
"minItems": 2,
|
||||
"type": "array",
|
||||
"items": [
|
||||
{"$ref": "#/components/schemas/Coordinate"},
|
||||
{"$ref": "#/components/schemas/Coordinate"},
|
||||
],
|
||||
}
|
||||
)
|
||||
"schema": {
|
||||
"title": "Square",
|
||||
"maxItems": 2,
|
||||
"minItems": 2,
|
||||
"type": "array",
|
||||
"prefixItems": [
|
||||
{"$ref": "#/components/schemas/Coordinate"},
|
||||
{"$ref": "#/components/schemas/Coordinate"},
|
||||
],
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": True,
|
||||
@@ -212,28 +196,16 @@ def test_openapi_schema():
|
||||
"required": ["values"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"values": IsDict(
|
||||
{
|
||||
"title": "Values",
|
||||
"maxItems": 2,
|
||||
"minItems": 2,
|
||||
"type": "array",
|
||||
"prefixItems": [
|
||||
{"type": "integer"},
|
||||
{"type": "integer"},
|
||||
],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"title": "Values",
|
||||
"maxItems": 2,
|
||||
"minItems": 2,
|
||||
"type": "array",
|
||||
"items": [{"type": "integer"}, {"type": "integer"}],
|
||||
}
|
||||
)
|
||||
"values": {
|
||||
"title": "Values",
|
||||
"maxItems": 2,
|
||||
"minItems": 2,
|
||||
"type": "array",
|
||||
"prefixItems": [
|
||||
{"type": "integer"},
|
||||
{"type": "integer"},
|
||||
],
|
||||
}
|
||||
},
|
||||
},
|
||||
"Coordinate": {
|
||||
@@ -264,26 +236,15 @@ def test_openapi_schema():
|
||||
"items": {
|
||||
"title": "Items",
|
||||
"type": "array",
|
||||
"items": IsDict(
|
||||
{
|
||||
"maxItems": 2,
|
||||
"minItems": 2,
|
||||
"type": "array",
|
||||
"prefixItems": [
|
||||
{"type": "string"},
|
||||
{"type": "string"},
|
||||
],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"maxItems": 2,
|
||||
"minItems": 2,
|
||||
"type": "array",
|
||||
"items": [{"type": "string"}, {"type": "string"}],
|
||||
}
|
||||
),
|
||||
"items": {
|
||||
"maxItems": 2,
|
||||
"minItems": 2,
|
||||
"type": "array",
|
||||
"prefixItems": [
|
||||
{"type": "string"},
|
||||
{"type": "string"},
|
||||
],
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
@@ -3,7 +3,6 @@ import os
|
||||
import shutil
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from tests.utils import needs_py310
|
||||
@@ -80,16 +79,10 @@ def test_openapi_schema(client: TestClient):
|
||||
},
|
||||
{
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "boolean"}, {"type": "null"}],
|
||||
"title": "Img",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Img", "type": "boolean"}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "boolean"}, {"type": "null"}],
|
||||
"title": "Img",
|
||||
},
|
||||
"name": "img",
|
||||
"in": "query",
|
||||
},
|
||||
|
||||
@@ -3,7 +3,6 @@ import os
|
||||
import shutil
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from tests.utils import needs_py310
|
||||
@@ -83,16 +82,10 @@ def test_openapi_schema(client: TestClient):
|
||||
},
|
||||
{
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "boolean"}, {"type": "null"}],
|
||||
"title": "Img",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Img", "type": "boolean"}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "boolean"}, {"type": "null"}],
|
||||
"title": "Img",
|
||||
},
|
||||
"name": "img",
|
||||
"in": "query",
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from dirty_equals import IsOneOf
|
||||
from fastapi.testclient import TestClient
|
||||
from inline_snapshot import snapshot
|
||||
|
||||
from docs_src.behind_a_proxy.tutorial003_py39 import app
|
||||
|
||||
@@ -15,40 +15,34 @@ def test_main():
|
||||
def test_openapi_schema():
|
||||
response = client.get("/openapi.json")
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {
|
||||
"openapi": "3.1.0",
|
||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||
"servers": [
|
||||
{"url": "/api/v1"},
|
||||
{
|
||||
"url": IsOneOf(
|
||||
"https://stag.example.com/",
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
"https://stag.example.com",
|
||||
),
|
||||
"description": "Staging environment",
|
||||
},
|
||||
{
|
||||
"url": IsOneOf(
|
||||
"https://prod.example.com/",
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
"https://prod.example.com",
|
||||
),
|
||||
"description": "Production environment",
|
||||
},
|
||||
],
|
||||
"paths": {
|
||||
"/app": {
|
||||
"get": {
|
||||
"summary": "Read Main",
|
||||
"operationId": "read_main_app_get",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {"application/json": {"schema": {}}},
|
||||
}
|
||||
},
|
||||
assert response.json() == snapshot(
|
||||
{
|
||||
"openapi": "3.1.0",
|
||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||
"servers": [
|
||||
{"url": "/api/v1"},
|
||||
{
|
||||
"url": "https://stag.example.com",
|
||||
"description": "Staging environment",
|
||||
},
|
||||
{
|
||||
"url": "https://prod.example.com",
|
||||
"description": "Production environment",
|
||||
},
|
||||
],
|
||||
"paths": {
|
||||
"/app": {
|
||||
"get": {
|
||||
"summary": "Read Main",
|
||||
"operationId": "read_main_app_get",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {"application/json": {"schema": {}}},
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from dirty_equals import IsOneOf
|
||||
from fastapi.testclient import TestClient
|
||||
from inline_snapshot import snapshot
|
||||
|
||||
from docs_src.behind_a_proxy.tutorial004_py39 import app
|
||||
|
||||
@@ -15,39 +15,33 @@ def test_main():
|
||||
def test_openapi_schema():
|
||||
response = client.get("/openapi.json")
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {
|
||||
"openapi": "3.1.0",
|
||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||
"servers": [
|
||||
{
|
||||
"url": IsOneOf(
|
||||
"https://stag.example.com/",
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
"https://stag.example.com",
|
||||
),
|
||||
"description": "Staging environment",
|
||||
},
|
||||
{
|
||||
"url": IsOneOf(
|
||||
"https://prod.example.com/",
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
"https://prod.example.com",
|
||||
),
|
||||
"description": "Production environment",
|
||||
},
|
||||
],
|
||||
"paths": {
|
||||
"/app": {
|
||||
"get": {
|
||||
"summary": "Read Main",
|
||||
"operationId": "read_main_app_get",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {"application/json": {"schema": {}}},
|
||||
}
|
||||
},
|
||||
assert response.json() == snapshot(
|
||||
{
|
||||
"openapi": "3.1.0",
|
||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||
"servers": [
|
||||
{
|
||||
"url": "https://stag.example.com",
|
||||
"description": "Staging environment",
|
||||
},
|
||||
{
|
||||
"url": "https://prod.example.com",
|
||||
"description": "Production environment",
|
||||
},
|
||||
],
|
||||
"paths": {
|
||||
"/app": {
|
||||
"get": {
|
||||
"summary": "Read Main",
|
||||
"operationId": "read_main_app_get",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {"application/json": {"schema": {}}},
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
|
||||
@@ -28,29 +27,16 @@ def test_users_token_jessica(client: TestClient):
|
||||
def test_users_with_no_token(client: TestClient):
|
||||
response = client.get("/users")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "token"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_users_foo_token_jessica(client: TestClient):
|
||||
@@ -62,29 +48,16 @@ def test_users_foo_token_jessica(client: TestClient):
|
||||
def test_users_foo_with_no_token(client: TestClient):
|
||||
response = client.get("/users/foo")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "token"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_users_me_token_jessica(client: TestClient):
|
||||
@@ -96,29 +69,16 @@ def test_users_me_token_jessica(client: TestClient):
|
||||
def test_users_me_with_no_token(client: TestClient):
|
||||
response = client.get("/users/me")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "token"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_users_token_monica_with_no_jessica(client: TestClient):
|
||||
@@ -141,29 +101,16 @@ def test_items_token_jessica(client: TestClient):
|
||||
def test_items_with_no_token_jessica(client: TestClient):
|
||||
response = client.get("/items", headers={"X-Token": "fake-super-secret-token"})
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "token"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_items_plumbus_token_jessica(client: TestClient):
|
||||
@@ -187,29 +134,16 @@ def test_items_plumbus_with_no_token(client: TestClient):
|
||||
"/items/plumbus", headers={"X-Token": "fake-super-secret-token"}
|
||||
)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "token"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_items_with_invalid_token(client: TestClient):
|
||||
@@ -227,57 +161,31 @@ def test_items_bar_with_invalid_token(client: TestClient):
|
||||
def test_items_with_missing_x_token_header(client: TestClient):
|
||||
response = client.get("/items?token=jessica")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "x-token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["header", "x-token"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "x-token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_items_plumbus_with_missing_x_token_header(client: TestClient):
|
||||
response = client.get("/items/plumbus?token=jessica")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "x-token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["header", "x-token"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "x-token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_root_token_jessica(client: TestClient):
|
||||
@@ -289,68 +197,37 @@ def test_root_token_jessica(client: TestClient):
|
||||
def test_root_with_no_token(client: TestClient):
|
||||
response = client.get("/")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "token"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_put_no_header(client: TestClient):
|
||||
response = client.put("/items/foo")
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "x-token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "token"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
{
|
||||
"loc": ["header", "x-token"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "x-token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_put_invalid_header(client: TestClient):
|
||||
|
||||
@@ -2,7 +2,6 @@ import importlib
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from ...utils import needs_py310
|
||||
@@ -74,124 +73,67 @@ def test_post_with_str_float_description_tax(client: TestClient):
|
||||
def test_post_with_only_name(client: TestClient):
|
||||
response = client.post("/items/", json={"name": "Foo"})
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "price"],
|
||||
"msg": "Field required",
|
||||
"input": {"name": "Foo"},
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "price"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "price"],
|
||||
"msg": "Field required",
|
||||
"input": {"name": "Foo"},
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_post_with_only_name_price(client: TestClient):
|
||||
response = client.post("/items/", json={"name": "Foo", "price": "twenty"})
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "float_parsing",
|
||||
"loc": ["body", "price"],
|
||||
"msg": "Input should be a valid number, unable to parse string as a number",
|
||||
"input": "twenty",
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "price"],
|
||||
"msg": "value is not a valid float",
|
||||
"type": "type_error.float",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "float_parsing",
|
||||
"loc": ["body", "price"],
|
||||
"msg": "Input should be a valid number, unable to parse string as a number",
|
||||
"input": "twenty",
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_post_with_no_data(client: TestClient):
|
||||
response = client.post("/items/", json={})
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "name"],
|
||||
"msg": "Field required",
|
||||
"input": {},
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "price"],
|
||||
"msg": "Field required",
|
||||
"input": {},
|
||||
},
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "name"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
{
|
||||
"loc": ["body", "price"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "name"],
|
||||
"msg": "Field required",
|
||||
"input": {},
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "price"],
|
||||
"msg": "Field required",
|
||||
"input": {},
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_post_with_none(client: TestClient):
|
||||
response = client.post("/items/", json=None)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_post_broken_body(client: TestClient):
|
||||
@@ -201,67 +143,32 @@ def test_post_broken_body(client: TestClient):
|
||||
content="{some broken json}",
|
||||
)
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "json_invalid",
|
||||
"loc": ["body", 1],
|
||||
"msg": "JSON decode error",
|
||||
"input": {},
|
||||
"ctx": {
|
||||
"error": "Expecting property name enclosed in double quotes"
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", 1],
|
||||
"msg": "Expecting property name enclosed in double quotes: line 1 column 2 (char 1)",
|
||||
"type": "value_error.jsondecode",
|
||||
"ctx": {
|
||||
"msg": "Expecting property name enclosed in double quotes",
|
||||
"doc": "{some broken json}",
|
||||
"pos": 1,
|
||||
"lineno": 1,
|
||||
"colno": 2,
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "json_invalid",
|
||||
"loc": ["body", 1],
|
||||
"msg": "JSON decode error",
|
||||
"input": {},
|
||||
"ctx": {"error": "Expecting property name enclosed in double quotes"},
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_post_form_for_json(client: TestClient):
|
||||
response = client.post("/items/", data={"name": "Foo", "price": 50.5})
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "model_attributes_type",
|
||||
"loc": ["body"],
|
||||
"msg": "Input should be a valid dictionary or object to extract fields from",
|
||||
"input": "name=Foo&price=50.5",
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body"],
|
||||
"msg": "value is not a valid dict",
|
||||
"type": "type_error.dict",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "model_attributes_type",
|
||||
"loc": ["body"],
|
||||
"msg": "Input should be a valid dictionary or object to extract fields from",
|
||||
"input": "name=Foo&price=50.5",
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_explicit_content_type(client: TestClient):
|
||||
@@ -302,84 +209,46 @@ def test_wrong_headers(client: TestClient):
|
||||
"/items/", content=data, headers={"Content-Type": "text/plain"}
|
||||
)
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "model_attributes_type",
|
||||
"loc": ["body"],
|
||||
"msg": "Input should be a valid dictionary or object to extract fields from",
|
||||
"input": '{"name": "Foo", "price": 50.5}',
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body"],
|
||||
"msg": "value is not a valid dict",
|
||||
"type": "type_error.dict",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "model_attributes_type",
|
||||
"loc": ["body"],
|
||||
"msg": "Input should be a valid dictionary or object to extract fields from",
|
||||
"input": '{"name": "Foo", "price": 50.5}',
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
response = client.post(
|
||||
"/items/", content=data, headers={"Content-Type": "application/geo+json-seq"}
|
||||
)
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "model_attributes_type",
|
||||
"loc": ["body"],
|
||||
"msg": "Input should be a valid dictionary or object to extract fields from",
|
||||
"input": '{"name": "Foo", "price": 50.5}',
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body"],
|
||||
"msg": "value is not a valid dict",
|
||||
"type": "type_error.dict",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "model_attributes_type",
|
||||
"loc": ["body"],
|
||||
"msg": "Input should be a valid dictionary or object to extract fields from",
|
||||
"input": '{"name": "Foo", "price": 50.5}',
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
response = client.post(
|
||||
"/items/", content=data, headers={"Content-Type": "application/not-really-json"}
|
||||
)
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "model_attributes_type",
|
||||
"loc": ["body"],
|
||||
"msg": "Input should be a valid dictionary or object to extract fields from",
|
||||
"input": '{"name": "Foo", "price": 50.5}',
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body"],
|
||||
"msg": "value is not a valid dict",
|
||||
"type": "type_error.dict",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "model_attributes_type",
|
||||
"loc": ["body"],
|
||||
"msg": "Input should be a valid dictionary or object to extract fields from",
|
||||
"input": '{"name": "Foo", "price": 50.5}',
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_other_exceptions(client: TestClient):
|
||||
@@ -435,26 +304,14 @@ def test_openapi_schema(client: TestClient):
|
||||
"properties": {
|
||||
"name": {"title": "Name", "type": "string"},
|
||||
"price": {"title": "Price", "type": "number"},
|
||||
"description": IsDict(
|
||||
{
|
||||
"title": "Description",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Description", "type": "string"}
|
||||
),
|
||||
"tax": IsDict(
|
||||
{
|
||||
"title": "Tax",
|
||||
"anyOf": [{"type": "number"}, {"type": "null"}],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Tax", "type": "number"}
|
||||
),
|
||||
"description": {
|
||||
"title": "Description",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
},
|
||||
"tax": {
|
||||
"title": "Tax",
|
||||
"anyOf": [{"type": "number"}, {"type": "null"}],
|
||||
},
|
||||
},
|
||||
},
|
||||
"ValidationError": {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from ...utils import needs_py310
|
||||
@@ -59,31 +58,17 @@ def test_items_6(client: TestClient):
|
||||
def test_invalid_price(client: TestClient):
|
||||
response = client.put("/items/5", json={"item": {"name": "Foo", "price": -3.0}})
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "greater_than",
|
||||
"loc": ["body", "item", "price"],
|
||||
"msg": "Input should be greater than 0",
|
||||
"input": -3.0,
|
||||
"ctx": {"gt": 0.0},
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"ctx": {"limit_value": 0},
|
||||
"loc": ["body", "item", "price"],
|
||||
"msg": "ensure this value is greater than 0",
|
||||
"type": "value_error.number.not_gt",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "greater_than",
|
||||
"loc": ["body", "item", "price"],
|
||||
"msg": "Input should be greater than 0",
|
||||
"input": -3.0,
|
||||
"ctx": {"gt": 0.0},
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_openapi_schema(client: TestClient):
|
||||
@@ -142,39 +127,23 @@ def test_openapi_schema(client: TestClient):
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"title": "Name", "type": "string"},
|
||||
"description": IsDict(
|
||||
{
|
||||
"title": "The description of the item",
|
||||
"anyOf": [
|
||||
{"maxLength": 300, "type": "string"},
|
||||
{"type": "null"},
|
||||
],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"title": "The description of the item",
|
||||
"maxLength": 300,
|
||||
"type": "string",
|
||||
}
|
||||
),
|
||||
"description": {
|
||||
"title": "The description of the item",
|
||||
"anyOf": [
|
||||
{"maxLength": 300, "type": "string"},
|
||||
{"type": "null"},
|
||||
],
|
||||
},
|
||||
"price": {
|
||||
"title": "Price",
|
||||
"exclusiveMinimum": 0.0,
|
||||
"type": "number",
|
||||
"description": "The price must be greater than zero",
|
||||
},
|
||||
"tax": IsDict(
|
||||
{
|
||||
"title": "Tax",
|
||||
"anyOf": [{"type": "number"}, {"type": "null"}],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Tax", "type": "number"}
|
||||
),
|
||||
"tax": {
|
||||
"title": "Tax",
|
||||
"anyOf": [{"type": "number"}, {"type": "null"}],
|
||||
},
|
||||
},
|
||||
},
|
||||
"Body_update_item_items__item_id__put": {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from ...utils import needs_py310
|
||||
@@ -53,29 +52,16 @@ def test_post_no_body(client: TestClient):
|
||||
def test_post_id_foo(client: TestClient):
|
||||
response = client.put("/items/foo", json=None)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "int_parsing",
|
||||
"loc": ["path", "item_id"],
|
||||
"msg": "Input should be a valid integer, unable to parse string as an integer",
|
||||
"input": "foo",
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["path", "item_id"],
|
||||
"msg": "value is not a valid integer",
|
||||
"type": "type_error.integer",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "int_parsing",
|
||||
"loc": ["path", "item_id"],
|
||||
"msg": "Input should be a valid integer, unable to parse string as an integer",
|
||||
"input": "foo",
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_openapi_schema(client: TestClient):
|
||||
@@ -119,16 +105,10 @@ def test_openapi_schema(client: TestClient):
|
||||
},
|
||||
{
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Q",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Q", "type": "string"}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Q",
|
||||
},
|
||||
"name": "q",
|
||||
"in": "query",
|
||||
},
|
||||
@@ -136,19 +116,13 @@ def test_openapi_schema(client: TestClient):
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [
|
||||
{"$ref": "#/components/schemas/Item"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "Item",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"$ref": "#/components/schemas/Item"}
|
||||
)
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{"$ref": "#/components/schemas/Item"},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "Item",
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -163,27 +137,15 @@ def test_openapi_schema(client: TestClient):
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"title": "Name", "type": "string"},
|
||||
"description": IsDict(
|
||||
{
|
||||
"title": "Description",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Description", "type": "string"}
|
||||
),
|
||||
"description": {
|
||||
"title": "Description",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
},
|
||||
"price": {"title": "Price", "type": "number"},
|
||||
"tax": IsDict(
|
||||
{
|
||||
"title": "Tax",
|
||||
"anyOf": [{"type": "number"}, {"type": "null"}],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Tax", "type": "number"}
|
||||
),
|
||||
"tax": {
|
||||
"title": "Tax",
|
||||
"anyOf": [{"type": "number"}, {"type": "null"}],
|
||||
},
|
||||
},
|
||||
},
|
||||
"ValidationError": {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from ...utils import needs_py310
|
||||
@@ -49,101 +48,55 @@ def test_post_body_valid(client: TestClient):
|
||||
def test_post_body_no_data(client: TestClient):
|
||||
response = client.put("/items/5", json=None)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "item"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "user"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "importance"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "item"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
{
|
||||
"loc": ["body", "user"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
{
|
||||
"loc": ["body", "importance"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "item"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "user"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "importance"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_post_body_empty_list(client: TestClient):
|
||||
response = client.put("/items/5", json=[])
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "item"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "user"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "importance"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "item"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
{
|
||||
"loc": ["body", "user"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
{
|
||||
"loc": ["body", "importance"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "item"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "user"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "importance"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_openapi_schema(client: TestClient):
|
||||
@@ -202,27 +155,15 @@ def test_openapi_schema(client: TestClient):
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"title": "Name", "type": "string"},
|
||||
"description": IsDict(
|
||||
{
|
||||
"title": "Description",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Description", "type": "string"}
|
||||
),
|
||||
"description": {
|
||||
"title": "Description",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
},
|
||||
"price": {"title": "Price", "type": "number"},
|
||||
"tax": IsDict(
|
||||
{
|
||||
"title": "Tax",
|
||||
"anyOf": [{"type": "number"}, {"type": "null"}],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Tax", "type": "number"}
|
||||
),
|
||||
"tax": {
|
||||
"title": "Tax",
|
||||
"anyOf": [{"type": "number"}, {"type": "null"}],
|
||||
},
|
||||
},
|
||||
},
|
||||
"User": {
|
||||
@@ -231,16 +172,10 @@ def test_openapi_schema(client: TestClient):
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"username": {"title": "Username", "type": "string"},
|
||||
"full_name": IsDict(
|
||||
{
|
||||
"title": "Full Name",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Full Name", "type": "string"}
|
||||
),
|
||||
"full_name": {
|
||||
"title": "Full Name",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
},
|
||||
},
|
||||
},
|
||||
"Body_update_item_items__item_id__put": {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
|
||||
@@ -29,29 +28,16 @@ def test_post_invalid_body(client: TestClient):
|
||||
data = {"foo": 2.2, "3": 3.3}
|
||||
response = client.post("/index-weights/", json=data)
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "int_parsing",
|
||||
"loc": ["body", "foo", "[key]"],
|
||||
"msg": "Input should be a valid integer, unable to parse string as an integer",
|
||||
"input": "foo",
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "__key__"],
|
||||
"msg": "value is not a valid integer",
|
||||
"type": "type_error.integer",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "int_parsing",
|
||||
"loc": ["body", "foo", "[key]"],
|
||||
"msg": "Input should be a valid integer, unable to parse string as an integer",
|
||||
"input": "foo",
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_openapi_schema(client: TestClient):
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
from inline_snapshot import snapshot
|
||||
|
||||
@@ -54,30 +53,16 @@ def test_cookie_param_model_invalid(client: TestClient):
|
||||
response = client.get("/items/")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == snapshot(
|
||||
IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["cookie", "session_id"],
|
||||
"msg": "Field required",
|
||||
"input": {},
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "value_error.missing",
|
||||
"loc": ["cookie", "session_id"],
|
||||
"msg": "field required",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["cookie", "session_id"],
|
||||
"msg": "Field required",
|
||||
"input": {},
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -115,37 +100,19 @@ def test_openapi_schema(client: TestClient):
|
||||
"name": "fatebook_tracker",
|
||||
"in": "cookie",
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Fatebook Tracker",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"type": "string",
|
||||
"title": "Fatebook Tracker",
|
||||
}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Fatebook Tracker",
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "googall_tracker",
|
||||
"in": "cookie",
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Googall Tracker",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"type": "string",
|
||||
"title": "Googall Tracker",
|
||||
}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Googall Tracker",
|
||||
},
|
||||
},
|
||||
],
|
||||
"responses": {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
from inline_snapshot import snapshot
|
||||
|
||||
@@ -72,30 +71,16 @@ def test_cookie_param_model_extra(client: TestClient):
|
||||
response = c.get("/items/")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == snapshot(
|
||||
IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "extra_forbidden",
|
||||
"loc": ["cookie", "extra"],
|
||||
"msg": "Extra inputs are not permitted",
|
||||
"input": "track-me-here-too",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "value_error.extra",
|
||||
"loc": ["cookie", "extra"],
|
||||
"msg": "extra fields not permitted",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "extra_forbidden",
|
||||
"loc": ["cookie", "extra"],
|
||||
"msg": "Extra inputs are not permitted",
|
||||
"input": "track-me-here-too",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -134,19 +119,10 @@ def test_openapi_schema(client: TestClient):
|
||||
"name": "googall_tracker",
|
||||
"in": "cookie",
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Googall Tracker",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"type": "string",
|
||||
"title": "Googall Tracker",
|
||||
}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Googall Tracker",
|
||||
},
|
||||
},
|
||||
],
|
||||
"responses": {
|
||||
|
||||
@@ -2,7 +2,6 @@ import importlib
|
||||
from types import ModuleType
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from ...utils import needs_py310
|
||||
@@ -75,16 +74,10 @@ def test_openapi_schema(mod: ModuleType):
|
||||
"parameters": [
|
||||
{
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Ads Id",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Ads Id", "type": "string"}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Ads Id",
|
||||
},
|
||||
"name": "ads_id",
|
||||
"in": "cookie",
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict, IsOneOf
|
||||
from dirty_equals import IsOneOf
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from tests.utils import needs_py310
|
||||
@@ -30,34 +30,17 @@ def test_endpoint_works(client: TestClient):
|
||||
|
||||
def test_exception_handler_body_access(client: TestClient):
|
||||
response = client.post("/", json={"numbers": [1, 2, 3]})
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": {
|
||||
"errors": [
|
||||
{
|
||||
"type": "list_type",
|
||||
"loc": ["body"],
|
||||
"msg": "Input should be a valid list",
|
||||
"input": {"numbers": [1, 2, 3]},
|
||||
}
|
||||
],
|
||||
# httpx 0.28.0 switches to compact JSON https://github.com/encode/httpx/issues/3363
|
||||
"body": IsOneOf('{"numbers": [1, 2, 3]}', '{"numbers":[1,2,3]}'),
|
||||
}
|
||||
assert response.json() == {
|
||||
"detail": {
|
||||
"errors": [
|
||||
{
|
||||
"type": "list_type",
|
||||
"loc": ["body"],
|
||||
"msg": "Input should be a valid list",
|
||||
"input": {"numbers": [1, 2, 3]},
|
||||
}
|
||||
],
|
||||
# httpx 0.28.0 switches to compact JSON https://github.com/encode/httpx/issues/3363
|
||||
"body": IsOneOf('{"numbers": [1, 2, 3]}', '{"numbers":[1,2,3]}'),
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": {
|
||||
# httpx 0.28.0 switches to compact JSON https://github.com/encode/httpx/issues/3363
|
||||
"body": IsOneOf('{"numbers": [1, 2, 3]}', '{"numbers":[1,2,3]}'),
|
||||
"errors": [
|
||||
{
|
||||
"loc": ["body"],
|
||||
"msg": "value is not a valid list",
|
||||
"type": "type_error.list",
|
||||
}
|
||||
],
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from tests.utils import needs_py310
|
||||
@@ -36,29 +35,16 @@ def test_post_item(client: TestClient):
|
||||
def test_post_invalid_item(client: TestClient):
|
||||
response = client.post("/items/", json={"name": "Foo", "price": "invalid price"})
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "float_parsing",
|
||||
"loc": ["body", "price"],
|
||||
"msg": "Input should be a valid number, unable to parse string as a number",
|
||||
"input": "invalid price",
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "price"],
|
||||
"msg": "value is not a valid float",
|
||||
"type": "type_error.float",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "float_parsing",
|
||||
"loc": ["body", "price"],
|
||||
"msg": "Input should be a valid number, unable to parse string as a number",
|
||||
"input": "invalid price",
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_openapi_schema(client: TestClient):
|
||||
@@ -119,26 +105,14 @@ def test_openapi_schema(client: TestClient):
|
||||
"properties": {
|
||||
"name": {"title": "Name", "type": "string"},
|
||||
"price": {"title": "Price", "type": "number"},
|
||||
"description": IsDict(
|
||||
{
|
||||
"title": "Description",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Description", "type": "string"}
|
||||
),
|
||||
"tax": IsDict(
|
||||
{
|
||||
"title": "Tax",
|
||||
"anyOf": [{"type": "number"}, {"type": "null"}],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Tax", "type": "number"}
|
||||
),
|
||||
"description": {
|
||||
"title": "Description",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
},
|
||||
"tax": {
|
||||
"title": "Tax",
|
||||
"anyOf": [{"type": "number"}, {"type": "null"}],
|
||||
},
|
||||
},
|
||||
},
|
||||
"ValidationError": {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict, IsOneOf
|
||||
from fastapi.testclient import TestClient
|
||||
from inline_snapshot import snapshot
|
||||
|
||||
from tests.utils import needs_py310
|
||||
|
||||
@@ -37,77 +37,53 @@ def test_get_item(client: TestClient):
|
||||
def test_openapi_schema(client: TestClient):
|
||||
response = client.get("/openapi.json")
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {
|
||||
"openapi": "3.1.0",
|
||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||
"paths": {
|
||||
"/items/next": {
|
||||
"get": {
|
||||
"summary": "Read Next Item",
|
||||
"operationId": "read_next_item_items_next_get",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {"$ref": "#/components/schemas/Item"}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
assert response.json() == snapshot(
|
||||
{
|
||||
"openapi": "3.1.0",
|
||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||
"paths": {
|
||||
"/items/next": {
|
||||
"get": {
|
||||
"summary": "Read Next Item",
|
||||
"operationId": "read_next_item_items_next_get",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {"$ref": "#/components/schemas/Item"}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"Item": {
|
||||
"title": "Item",
|
||||
"required": IsOneOf(
|
||||
["name", "price", "tags", "description", "tax"],
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
["name", "price"],
|
||||
),
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"title": "Name", "type": "string"},
|
||||
"price": {"title": "Price", "type": "number"},
|
||||
"tags": IsDict(
|
||||
{
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"Item": {
|
||||
"title": "Item",
|
||||
"required": ["name", "price"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"title": "Name", "type": "string"},
|
||||
"price": {"title": "Price", "type": "number"},
|
||||
"tags": {
|
||||
"title": "Tags",
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"title": "Tags",
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
}
|
||||
),
|
||||
"description": IsDict(
|
||||
{
|
||||
},
|
||||
"description": {
|
||||
"title": "Description",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Description", "type": "string"}
|
||||
),
|
||||
"tax": IsDict(
|
||||
{
|
||||
},
|
||||
"tax": {
|
||||
"title": "Tax",
|
||||
"anyOf": [{"type": "number"}, {"type": "null"}],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Tax", "type": "number"}
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
|
||||
@@ -22,40 +21,22 @@ def get_client(request: pytest.FixtureRequest):
|
||||
def test_get_no_headers(client: TestClient):
|
||||
response = client.get("/items/")
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "x-token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "x-key"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["header", "x-token"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
{
|
||||
"loc": ["header", "x-key"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "x-token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "x-key"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_get_invalid_one_header(client: TestClient):
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
|
||||
@@ -22,79 +21,43 @@ def get_client(request: pytest.FixtureRequest):
|
||||
def test_get_no_headers_items(client: TestClient):
|
||||
response = client.get("/items/")
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "x-token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "x-key"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["header", "x-token"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
{
|
||||
"loc": ["header", "x-key"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "x-token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "x-key"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_get_no_headers_users(client: TestClient):
|
||||
response = client.get("/users/")
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "x-token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "x-key"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["header", "x-token"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
{
|
||||
"loc": ["header", "x-key"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "x-token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "x-key"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_get_invalid_one_header_items(client: TestClient):
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
from inline_snapshot import snapshot
|
||||
|
||||
from ...utils import needs_py310
|
||||
|
||||
@@ -47,146 +47,117 @@ def test_extra_types(client: TestClient):
|
||||
def test_openapi_schema(client: TestClient):
|
||||
response = client.get("/openapi.json")
|
||||
assert response.status_code == 200, response.text
|
||||
assert response.json() == {
|
||||
"openapi": "3.1.0",
|
||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||
"paths": {
|
||||
"/items/{item_id}": {
|
||||
"put": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {"application/json": {"schema": {}}},
|
||||
assert response.json() == snapshot(
|
||||
{
|
||||
"openapi": "3.1.0",
|
||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||
"paths": {
|
||||
"/items/{item_id}": {
|
||||
"put": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {"application/json": {"schema": {}}},
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"summary": "Read Items",
|
||||
"operationId": "read_items_items__item_id__put",
|
||||
"parameters": [
|
||||
{
|
||||
"required": True,
|
||||
"schema": {
|
||||
"title": "Item Id",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
},
|
||||
"name": "item_id",
|
||||
"in": "path",
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"required": True,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
"$ref": "#/components/schemas/Body_read_items_items__item_id__put"
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
"summary": "Read Items",
|
||||
"operationId": "read_items_items__item_id__put",
|
||||
"parameters": [
|
||||
{
|
||||
"required": True,
|
||||
"schema": {
|
||||
"title": "Item Id",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
},
|
||||
"name": "item_id",
|
||||
"in": "path",
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"required": True,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": IsDict(
|
||||
{
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/Body_read_items_items__item_id__put"
|
||||
}
|
||||
],
|
||||
"title": "Body",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"$ref": "#/components/schemas/Body_read_items_items__item_id__put"
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"Body_read_items_items__item_id__put": {
|
||||
"title": "Body_read_items_items__item_id__put",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"start_datetime": {
|
||||
"title": "Start Datetime",
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
},
|
||||
"end_datetime": {
|
||||
"title": "End Datetime",
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
},
|
||||
"repeat_at": IsDict(
|
||||
{
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"Body_read_items_items__item_id__put": {
|
||||
"title": "Body_read_items_items__item_id__put",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"start_datetime": {
|
||||
"title": "Start Datetime",
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
},
|
||||
"end_datetime": {
|
||||
"title": "End Datetime",
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
},
|
||||
"repeat_at": {
|
||||
"title": "Repeat At",
|
||||
"anyOf": [
|
||||
{"type": "string", "format": "time"},
|
||||
{"type": "null"},
|
||||
],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"title": "Repeat At",
|
||||
"type": "string",
|
||||
"format": "time",
|
||||
}
|
||||
),
|
||||
"process_after": IsDict(
|
||||
{
|
||||
},
|
||||
"process_after": {
|
||||
"title": "Process After",
|
||||
"type": "string",
|
||||
"format": "duration",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"title": "Process After",
|
||||
"type": "number",
|
||||
"format": "time-delta",
|
||||
}
|
||||
),
|
||||
},
|
||||
"required": ["start_datetime", "end_datetime", "process_after"],
|
||||
},
|
||||
"ValidationError": {
|
||||
"title": "ValidationError",
|
||||
"required": ["loc", "msg", "type"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"loc": {
|
||||
"title": "Location",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [{"type": "string"}, {"type": "integer"}]
|
||||
},
|
||||
},
|
||||
"msg": {"title": "Message", "type": "string"},
|
||||
"type": {"title": "Error Type", "type": "string"},
|
||||
"required": ["start_datetime", "end_datetime", "process_after"],
|
||||
},
|
||||
},
|
||||
"HTTPValidationError": {
|
||||
"title": "HTTPValidationError",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"title": "Detail",
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/components/schemas/ValidationError"},
|
||||
}
|
||||
"ValidationError": {
|
||||
"title": "ValidationError",
|
||||
"required": ["loc", "msg", "type"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"loc": {
|
||||
"title": "Location",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [{"type": "string"}, {"type": "integer"}]
|
||||
},
|
||||
},
|
||||
"msg": {"title": "Message", "type": "string"},
|
||||
"type": {"title": "Error Type", "type": "string"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
"HTTPValidationError": {
|
||||
"title": "HTTPValidationError",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"title": "Detail",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ValidationError"
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsOneOf
|
||||
from fastapi.testclient import TestClient
|
||||
from inline_snapshot import snapshot
|
||||
|
||||
from ...utils import needs_py310
|
||||
|
||||
@@ -43,107 +43,115 @@ def test_get_plane(client: TestClient):
|
||||
def test_openapi_schema(client: TestClient):
|
||||
response = client.get("/openapi.json")
|
||||
assert response.status_code == 200, response.text
|
||||
assert response.json() == {
|
||||
"openapi": "3.1.0",
|
||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||
"paths": {
|
||||
"/items/{item_id}": {
|
||||
"get": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"title": "Response Read Item Items Item Id Get",
|
||||
"anyOf": [
|
||||
{"$ref": "#/components/schemas/PlaneItem"},
|
||||
{"$ref": "#/components/schemas/CarItem"},
|
||||
],
|
||||
assert response.json() == snapshot(
|
||||
{
|
||||
"openapi": "3.1.0",
|
||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||
"paths": {
|
||||
"/items/{item_id}": {
|
||||
"get": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"title": "Response Read Item Items Item Id Get",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/PlaneItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/CarItem"
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
"summary": "Read Item",
|
||||
"operationId": "read_item_items__item_id__get",
|
||||
"parameters": [
|
||||
{
|
||||
"required": True,
|
||||
"schema": {"title": "Item Id", "type": "string"},
|
||||
"name": "item_id",
|
||||
"in": "path",
|
||||
}
|
||||
],
|
||||
"summary": "Read Item",
|
||||
"operationId": "read_item_items__item_id__get",
|
||||
"parameters": [
|
||||
{
|
||||
"required": True,
|
||||
"schema": {"title": "Item Id", "type": "string"},
|
||||
"name": "item_id",
|
||||
"in": "path",
|
||||
}
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"PlaneItem": {
|
||||
"title": "PlaneItem",
|
||||
"required": IsOneOf(
|
||||
["description", "type", "size"],
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
["description", "size"],
|
||||
),
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"description": {"title": "Description", "type": "string"},
|
||||
"type": {"title": "Type", "type": "string", "default": "plane"},
|
||||
"size": {"title": "Size", "type": "integer"},
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"PlaneItem": {
|
||||
"title": "PlaneItem",
|
||||
"required": ["description", "size"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"description": {"title": "Description", "type": "string"},
|
||||
"type": {
|
||||
"title": "Type",
|
||||
"type": "string",
|
||||
"default": "plane",
|
||||
},
|
||||
"size": {"title": "Size", "type": "integer"},
|
||||
},
|
||||
},
|
||||
},
|
||||
"CarItem": {
|
||||
"title": "CarItem",
|
||||
"required": IsOneOf(
|
||||
["description", "type"],
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
["description"],
|
||||
),
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"description": {"title": "Description", "type": "string"},
|
||||
"type": {"title": "Type", "type": "string", "default": "car"},
|
||||
},
|
||||
},
|
||||
"ValidationError": {
|
||||
"title": "ValidationError",
|
||||
"required": ["loc", "msg", "type"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"loc": {
|
||||
"title": "Location",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [{"type": "string"}, {"type": "integer"}]
|
||||
"CarItem": {
|
||||
"title": "CarItem",
|
||||
"required": ["description"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"description": {"title": "Description", "type": "string"},
|
||||
"type": {
|
||||
"title": "Type",
|
||||
"type": "string",
|
||||
"default": "car",
|
||||
},
|
||||
},
|
||||
"msg": {"title": "Message", "type": "string"},
|
||||
"type": {"title": "Error Type", "type": "string"},
|
||||
},
|
||||
},
|
||||
"HTTPValidationError": {
|
||||
"title": "HTTPValidationError",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"title": "Detail",
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/components/schemas/ValidationError"},
|
||||
}
|
||||
"ValidationError": {
|
||||
"title": "ValidationError",
|
||||
"required": ["loc", "msg", "type"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"loc": {
|
||||
"title": "Location",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [{"type": "string"}, {"type": "integer"}]
|
||||
},
|
||||
},
|
||||
"msg": {"title": "Message", "type": "string"},
|
||||
"type": {"title": "Error Type", "type": "string"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
"HTTPValidationError": {
|
||||
"title": "HTTPValidationError",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"title": "Detail",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ValidationError"
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from docs_src.handling_errors.tutorial005_py39 import app
|
||||
@@ -9,31 +8,17 @@ client = TestClient(app)
|
||||
def test_post_validation_error():
|
||||
response = client.post("/items/", json={"title": "towel", "size": "XL"})
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "int_parsing",
|
||||
"loc": ["body", "size"],
|
||||
"msg": "Input should be a valid integer, unable to parse string as an integer",
|
||||
"input": "XL",
|
||||
}
|
||||
],
|
||||
"body": {"title": "towel", "size": "XL"},
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "size"],
|
||||
"msg": "value is not a valid integer",
|
||||
"type": "type_error.integer",
|
||||
}
|
||||
],
|
||||
"body": {"title": "towel", "size": "XL"},
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "int_parsing",
|
||||
"loc": ["body", "size"],
|
||||
"msg": "Input should be a valid integer, unable to parse string as an integer",
|
||||
"input": "XL",
|
||||
}
|
||||
],
|
||||
"body": {"title": "towel", "size": "XL"},
|
||||
}
|
||||
|
||||
|
||||
def test_post():
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from docs_src.handling_errors.tutorial006_py39 import app
|
||||
@@ -9,29 +8,16 @@ client = TestClient(app)
|
||||
def test_get_validation_error():
|
||||
response = client.get("/items/foo")
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "int_parsing",
|
||||
"loc": ["path", "item_id"],
|
||||
"msg": "Input should be a valid integer, unable to parse string as an integer",
|
||||
"input": "foo",
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["path", "item_id"],
|
||||
"msg": "value is not a valid integer",
|
||||
"type": "type_error.integer",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "int_parsing",
|
||||
"loc": ["path", "item_id"],
|
||||
"msg": "Input should be a valid integer, unable to parse string as an integer",
|
||||
"input": "foo",
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_get_http_error():
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
from inline_snapshot import snapshot
|
||||
|
||||
@@ -63,29 +62,19 @@ def test_header_param_model_invalid(client: TestClient):
|
||||
assert response.json() == snapshot(
|
||||
{
|
||||
"detail": [
|
||||
IsDict(
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "save_data"],
|
||||
"msg": "Field required",
|
||||
"input": {
|
||||
"x_tag": [],
|
||||
"host": "testserver",
|
||||
"accept": "*/*",
|
||||
"accept-encoding": "gzip, deflate",
|
||||
"connection": "keep-alive",
|
||||
"user-agent": "testclient",
|
||||
},
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"type": "value_error.missing",
|
||||
"loc": ["header", "save_data"],
|
||||
"msg": "field required",
|
||||
}
|
||||
)
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "save_data"],
|
||||
"msg": "Field required",
|
||||
"input": {
|
||||
"x_tag": [],
|
||||
"host": "testserver",
|
||||
"accept": "*/*",
|
||||
"accept-encoding": "gzip, deflate",
|
||||
"connection": "keep-alive",
|
||||
"user-agent": "testclient",
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
@@ -136,37 +125,19 @@ def test_openapi_schema(client: TestClient):
|
||||
"name": "if-modified-since",
|
||||
"in": "header",
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "If Modified Since",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"type": "string",
|
||||
"title": "If Modified Since",
|
||||
}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "If Modified Since",
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "traceparent",
|
||||
"in": "header",
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Traceparent",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"type": "string",
|
||||
"title": "Traceparent",
|
||||
}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Traceparent",
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "x-tag",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
from inline_snapshot import snapshot
|
||||
|
||||
@@ -64,22 +63,12 @@ def test_header_param_model_invalid(client: TestClient):
|
||||
assert response.json() == snapshot(
|
||||
{
|
||||
"detail": [
|
||||
IsDict(
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "save_data"],
|
||||
"msg": "Field required",
|
||||
"input": {"x_tag": [], "host": "testserver"},
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"type": "value_error.missing",
|
||||
"loc": ["header", "save_data"],
|
||||
"msg": "field required",
|
||||
}
|
||||
)
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "save_data"],
|
||||
"msg": "Field required",
|
||||
"input": {"x_tag": [], "host": "testserver"},
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
@@ -93,22 +82,12 @@ def test_header_param_model_extra(client: TestClient):
|
||||
assert response.json() == snapshot(
|
||||
{
|
||||
"detail": [
|
||||
IsDict(
|
||||
{
|
||||
"type": "extra_forbidden",
|
||||
"loc": ["header", "tool"],
|
||||
"msg": "Extra inputs are not permitted",
|
||||
"input": "plumbus",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"type": "value_error.extra",
|
||||
"loc": ["header", "tool"],
|
||||
"msg": "extra fields not permitted",
|
||||
}
|
||||
)
|
||||
{
|
||||
"type": "extra_forbidden",
|
||||
"loc": ["header", "tool"],
|
||||
"msg": "Extra inputs are not permitted",
|
||||
"input": "plumbus",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
@@ -143,37 +122,19 @@ def test_openapi_schema(client: TestClient):
|
||||
"name": "if-modified-since",
|
||||
"in": "header",
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "If Modified Since",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"type": "string",
|
||||
"title": "If Modified Since",
|
||||
}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "If Modified Since",
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "traceparent",
|
||||
"in": "header",
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Traceparent",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"type": "string",
|
||||
"title": "Traceparent",
|
||||
}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Traceparent",
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "x-tag",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
from inline_snapshot import snapshot
|
||||
|
||||
@@ -60,33 +59,23 @@ def test_header_param_model_no_underscore(client: TestClient):
|
||||
assert response.json() == snapshot(
|
||||
{
|
||||
"detail": [
|
||||
IsDict(
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "save_data"],
|
||||
"msg": "Field required",
|
||||
"input": {
|
||||
"host": "testserver",
|
||||
"traceparent": "123",
|
||||
"x_tag": [],
|
||||
"accept": "*/*",
|
||||
"accept-encoding": "gzip, deflate",
|
||||
"connection": "keep-alive",
|
||||
"user-agent": "testclient",
|
||||
"save-data": "true",
|
||||
"if-modified-since": "yesterday",
|
||||
"x-tag": ["one", "two"],
|
||||
},
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"type": "value_error.missing",
|
||||
"loc": ["header", "save_data"],
|
||||
"msg": "field required",
|
||||
}
|
||||
)
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "save_data"],
|
||||
"msg": "Field required",
|
||||
"input": {
|
||||
"host": "testserver",
|
||||
"traceparent": "123",
|
||||
"x_tag": [],
|
||||
"accept": "*/*",
|
||||
"accept-encoding": "gzip, deflate",
|
||||
"connection": "keep-alive",
|
||||
"user-agent": "testclient",
|
||||
"save-data": "true",
|
||||
"if-modified-since": "yesterday",
|
||||
"x-tag": ["one", "two"],
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
@@ -110,29 +99,19 @@ def test_header_param_model_invalid(client: TestClient):
|
||||
assert response.json() == snapshot(
|
||||
{
|
||||
"detail": [
|
||||
IsDict(
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "save_data"],
|
||||
"msg": "Field required",
|
||||
"input": {
|
||||
"x_tag": [],
|
||||
"host": "testserver",
|
||||
"accept": "*/*",
|
||||
"accept-encoding": "gzip, deflate",
|
||||
"connection": "keep-alive",
|
||||
"user-agent": "testclient",
|
||||
},
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"type": "value_error.missing",
|
||||
"loc": ["header", "save_data"],
|
||||
"msg": "field required",
|
||||
}
|
||||
)
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "save_data"],
|
||||
"msg": "Field required",
|
||||
"input": {
|
||||
"x_tag": [],
|
||||
"host": "testserver",
|
||||
"accept": "*/*",
|
||||
"accept-encoding": "gzip, deflate",
|
||||
"connection": "keep-alive",
|
||||
"user-agent": "testclient",
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
@@ -183,37 +162,19 @@ def test_openapi_schema(client: TestClient):
|
||||
"name": "if_modified_since",
|
||||
"in": "header",
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "If Modified Since",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"type": "string",
|
||||
"title": "If Modified Since",
|
||||
}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "If Modified Since",
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "traceparent",
|
||||
"in": "header",
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Traceparent",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"type": "string",
|
||||
"title": "Traceparent",
|
||||
}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Traceparent",
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "x_tag",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from ...utils import needs_py310
|
||||
@@ -67,16 +66,10 @@ def test_openapi_schema(client: TestClient):
|
||||
"parameters": [
|
||||
{
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "User-Agent",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "User-Agent", "type": "string"}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "User-Agent",
|
||||
},
|
||||
"name": "user-agent",
|
||||
"in": "header",
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from ...utils import needs_py310
|
||||
@@ -78,16 +77,10 @@ def test_openapi_schema(client: TestClient):
|
||||
"parameters": [
|
||||
{
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Strange Header",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Strange Header", "type": "string"}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Strange Header",
|
||||
},
|
||||
"name": "strange_header",
|
||||
"in": "header",
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from ...utils import needs_py310
|
||||
@@ -56,23 +55,13 @@ def test_openapi_schema(client: TestClient):
|
||||
"parameters": [
|
||||
{
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"title": "X-Token",
|
||||
"anyOf": [
|
||||
{"type": "array", "items": {"type": "string"}},
|
||||
{"type": "null"},
|
||||
],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"title": "X-Token",
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
}
|
||||
),
|
||||
"schema": {
|
||||
"title": "X-Token",
|
||||
"anyOf": [
|
||||
{"type": "array", "items": {"type": "string"}},
|
||||
{"type": "null"},
|
||||
],
|
||||
},
|
||||
"name": "x-token",
|
||||
"in": "header",
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ import importlib
|
||||
from types import ModuleType
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from tests.utils import needs_py310
|
||||
@@ -55,30 +54,18 @@ def test_openapi_schema(client: TestClient):
|
||||
"parameters": [
|
||||
{
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uri",
|
||||
"minLength": 1,
|
||||
"maxLength": 2083,
|
||||
},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "Callback Url",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"title": "Callback Url",
|
||||
"maxLength": 2083,
|
||||
"minLength": 1,
|
||||
"type": "string",
|
||||
"format": "uri",
|
||||
}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uri",
|
||||
"minLength": 1,
|
||||
"maxLength": 2083,
|
||||
},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "Callback Url",
|
||||
},
|
||||
"name": "callback_url",
|
||||
"in": "query",
|
||||
}
|
||||
@@ -171,16 +158,10 @@ def test_openapi_schema(client: TestClient):
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {"title": "Id", "type": "string"},
|
||||
"title": IsDict(
|
||||
{
|
||||
"title": "Title",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Title", "type": "string"}
|
||||
),
|
||||
"title": {
|
||||
"title": "Title",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
},
|
||||
"customer": {"title": "Customer", "type": "string"},
|
||||
"total": {"title": "Total", "type": "number"},
|
||||
},
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from docs_src.path_params.tutorial005_py39 import app
|
||||
@@ -27,31 +26,17 @@ def test_get_enums_resnet():
|
||||
def test_get_enums_invalid():
|
||||
response = client.get("/models/foo")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "enum",
|
||||
"loc": ["path", "model_name"],
|
||||
"msg": "Input should be 'alexnet', 'resnet' or 'lenet'",
|
||||
"input": "foo",
|
||||
"ctx": {"expected": "'alexnet', 'resnet' or 'lenet'"},
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"ctx": {"enum_values": ["alexnet", "resnet", "lenet"]},
|
||||
"loc": ["path", "model_name"],
|
||||
"msg": "value is not a valid enumeration member; permitted: 'alexnet', 'resnet', 'lenet'",
|
||||
"type": "type_error.enum",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "enum",
|
||||
"loc": ["path", "model_name"],
|
||||
"msg": "Input should be 'alexnet', 'resnet' or 'lenet'",
|
||||
"input": "foo",
|
||||
"ctx": {"expected": "'alexnet', 'resnet' or 'lenet'"},
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_openapi_schema():
|
||||
@@ -106,22 +91,11 @@ def test_openapi_schema():
|
||||
}
|
||||
},
|
||||
},
|
||||
"ModelName": IsDict(
|
||||
{
|
||||
"title": "ModelName",
|
||||
"enum": ["alexnet", "resnet", "lenet"],
|
||||
"type": "string",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
{
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
"title": "ModelName",
|
||||
"enum": ["alexnet", "resnet", "lenet"],
|
||||
"type": "string",
|
||||
"description": "An enumeration.",
|
||||
}
|
||||
),
|
||||
"ModelName": {
|
||||
"title": "ModelName",
|
||||
"enum": ["alexnet", "resnet", "lenet"],
|
||||
"type": "string",
|
||||
},
|
||||
"ValidationError": {
|
||||
"title": "ValidationError",
|
||||
"required": ["loc", "msg", "type"],
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
from inline_snapshot import snapshot
|
||||
|
||||
@@ -65,61 +64,31 @@ def test_query_param_model_invalid(client: TestClient):
|
||||
)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == snapshot(
|
||||
IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "less_than_equal",
|
||||
"loc": ["query", "limit"],
|
||||
"msg": "Input should be less than or equal to 100",
|
||||
"input": "150",
|
||||
"ctx": {"le": 100},
|
||||
},
|
||||
{
|
||||
"type": "greater_than_equal",
|
||||
"loc": ["query", "offset"],
|
||||
"msg": "Input should be greater than or equal to 0",
|
||||
"input": "-1",
|
||||
"ctx": {"ge": 0},
|
||||
},
|
||||
{
|
||||
"type": "literal_error",
|
||||
"loc": ["query", "order_by"],
|
||||
"msg": "Input should be 'created_at' or 'updated_at'",
|
||||
"input": "invalid",
|
||||
"ctx": {"expected": "'created_at' or 'updated_at'"},
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "value_error.number.not_le",
|
||||
"loc": ["query", "limit"],
|
||||
"msg": "ensure this value is less than or equal to 100",
|
||||
"ctx": {"limit_value": 100},
|
||||
},
|
||||
{
|
||||
"type": "value_error.number.not_ge",
|
||||
"loc": ["query", "offset"],
|
||||
"msg": "ensure this value is greater than or equal to 0",
|
||||
"ctx": {"limit_value": 0},
|
||||
},
|
||||
{
|
||||
"type": "value_error.const",
|
||||
"loc": ["query", "order_by"],
|
||||
"msg": "unexpected value; permitted: 'created_at', 'updated_at'",
|
||||
"ctx": {
|
||||
"given": "invalid",
|
||||
"permitted": ["created_at", "updated_at"],
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "less_than_equal",
|
||||
"loc": ["query", "limit"],
|
||||
"msg": "Input should be less than or equal to 100",
|
||||
"input": "150",
|
||||
"ctx": {"le": 100},
|
||||
},
|
||||
{
|
||||
"type": "greater_than_equal",
|
||||
"loc": ["query", "offset"],
|
||||
"msg": "Input should be greater than or equal to 0",
|
||||
"input": "-1",
|
||||
"ctx": {"ge": 0},
|
||||
},
|
||||
{
|
||||
"type": "literal_error",
|
||||
"loc": ["query", "order_by"],
|
||||
"msg": "Input should be 'created_at' or 'updated_at'",
|
||||
"input": "invalid",
|
||||
"ctx": {"expected": "'created_at' or 'updated_at'"},
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
from inline_snapshot import snapshot
|
||||
|
||||
@@ -65,61 +64,31 @@ def test_query_param_model_invalid(client: TestClient):
|
||||
)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == snapshot(
|
||||
IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "less_than_equal",
|
||||
"loc": ["query", "limit"],
|
||||
"msg": "Input should be less than or equal to 100",
|
||||
"input": "150",
|
||||
"ctx": {"le": 100},
|
||||
},
|
||||
{
|
||||
"type": "greater_than_equal",
|
||||
"loc": ["query", "offset"],
|
||||
"msg": "Input should be greater than or equal to 0",
|
||||
"input": "-1",
|
||||
"ctx": {"ge": 0},
|
||||
},
|
||||
{
|
||||
"type": "literal_error",
|
||||
"loc": ["query", "order_by"],
|
||||
"msg": "Input should be 'created_at' or 'updated_at'",
|
||||
"input": "invalid",
|
||||
"ctx": {"expected": "'created_at' or 'updated_at'"},
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "value_error.number.not_le",
|
||||
"loc": ["query", "limit"],
|
||||
"msg": "ensure this value is less than or equal to 100",
|
||||
"ctx": {"limit_value": 100},
|
||||
},
|
||||
{
|
||||
"type": "value_error.number.not_ge",
|
||||
"loc": ["query", "offset"],
|
||||
"msg": "ensure this value is greater than or equal to 0",
|
||||
"ctx": {"limit_value": 0},
|
||||
},
|
||||
{
|
||||
"type": "value_error.const",
|
||||
"loc": ["query", "order_by"],
|
||||
"msg": "unexpected value; permitted: 'created_at', 'updated_at'",
|
||||
"ctx": {
|
||||
"given": "invalid",
|
||||
"permitted": ["created_at", "updated_at"],
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "less_than_equal",
|
||||
"loc": ["query", "limit"],
|
||||
"msg": "Input should be less than or equal to 100",
|
||||
"input": "150",
|
||||
"ctx": {"le": 100},
|
||||
},
|
||||
{
|
||||
"type": "greater_than_equal",
|
||||
"loc": ["query", "offset"],
|
||||
"msg": "Input should be greater than or equal to 0",
|
||||
"input": "-1",
|
||||
"ctx": {"ge": 0},
|
||||
},
|
||||
{
|
||||
"type": "literal_error",
|
||||
"loc": ["query", "order_by"],
|
||||
"msg": "Input should be 'created_at' or 'updated_at'",
|
||||
"input": "invalid",
|
||||
"ctx": {"expected": "'created_at' or 'updated_at'"},
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -138,22 +107,12 @@ def test_query_param_model_extra(client: TestClient):
|
||||
assert response.json() == snapshot(
|
||||
{
|
||||
"detail": [
|
||||
IsDict(
|
||||
{
|
||||
"type": "extra_forbidden",
|
||||
"loc": ["query", "tool"],
|
||||
"msg": "Extra inputs are not permitted",
|
||||
"input": "plumbus",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"type": "value_error.extra",
|
||||
"loc": ["query", "tool"],
|
||||
"msg": "extra fields not permitted",
|
||||
}
|
||||
)
|
||||
{
|
||||
"type": "extra_forbidden",
|
||||
"loc": ["query", "tool"],
|
||||
"msg": "Extra inputs are not permitted",
|
||||
"input": "plumbus",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from docs_src.query_params.tutorial005_py39 import app
|
||||
@@ -15,29 +14,16 @@ def test_foo_needy_very():
|
||||
def test_foo_no_needy():
|
||||
response = client.get("/items/foo")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "needy"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "needy"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "needy"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_openapi_schema():
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from ...utils import needs_py310
|
||||
@@ -35,51 +34,28 @@ def test_foo_needy_very(client: TestClient):
|
||||
def test_foo_no_needy(client: TestClient):
|
||||
response = client.get("/items/foo?skip=a&limit=b")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "needy"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "int_parsing",
|
||||
"loc": ["query", "skip"],
|
||||
"msg": "Input should be a valid integer, unable to parse string as an integer",
|
||||
"input": "a",
|
||||
},
|
||||
{
|
||||
"type": "int_parsing",
|
||||
"loc": ["query", "limit"],
|
||||
"msg": "Input should be a valid integer, unable to parse string as an integer",
|
||||
"input": "b",
|
||||
},
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["query", "needy"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
{
|
||||
"loc": ["query", "skip"],
|
||||
"msg": "value is not a valid integer",
|
||||
"type": "type_error.integer",
|
||||
},
|
||||
{
|
||||
"loc": ["query", "limit"],
|
||||
"msg": "value is not a valid integer",
|
||||
"type": "type_error.integer",
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["query", "needy"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "int_parsing",
|
||||
"loc": ["query", "skip"],
|
||||
"msg": "Input should be a valid integer, unable to parse string as an integer",
|
||||
"input": "a",
|
||||
},
|
||||
{
|
||||
"type": "int_parsing",
|
||||
"loc": ["query", "limit"],
|
||||
"msg": "Input should be a valid integer, unable to parse string as an integer",
|
||||
"input": "b",
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_openapi_schema(client: TestClient):
|
||||
@@ -134,16 +110,10 @@ def test_openapi_schema(client: TestClient):
|
||||
},
|
||||
{
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "integer"}, {"type": "null"}],
|
||||
"title": "Limit",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Limit", "type": "integer"}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [{"type": "integer"}, {"type": "null"}],
|
||||
"title": "Limit",
|
||||
},
|
||||
"name": "limit",
|
||||
"in": "query",
|
||||
},
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi._compat import PYDANTIC_VERSION_MINOR_TUPLE
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
@@ -50,31 +49,17 @@ def test_query_params_str_validations_q_fixedquery(client: TestClient):
|
||||
def test_query_params_str_validations_item_query_nonregexquery(client: TestClient):
|
||||
response = client.get("/items/", params={"item-query": "nonregexquery"})
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "string_pattern_mismatch",
|
||||
"loc": ["query", "item-query"],
|
||||
"msg": "String should match pattern '^fixedquery$'",
|
||||
"input": "nonregexquery",
|
||||
"ctx": {"pattern": "^fixedquery$"},
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"ctx": {"pattern": "^fixedquery$"},
|
||||
"loc": ["query", "item-query"],
|
||||
"msg": 'string does not match regex "^fixedquery$"',
|
||||
"type": "value_error.str.regex",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "string_pattern_mismatch",
|
||||
"loc": ["query", "item-query"],
|
||||
"msg": "String should match pattern '^fixedquery$'",
|
||||
"input": "nonregexquery",
|
||||
"ctx": {"pattern": "^fixedquery$"},
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_openapi_schema(client: TestClient):
|
||||
@@ -109,38 +94,25 @@ def test_openapi_schema(client: TestClient):
|
||||
"description": "Query string for the items to search in the database that have a good match",
|
||||
"required": False,
|
||||
"deprecated": True,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 50,
|
||||
"pattern": "^fixedquery$",
|
||||
},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "Query string",
|
||||
"description": "Query string for the items to search in the database that have a good match",
|
||||
# See https://github.com/pydantic/pydantic/blob/80353c29a824c55dea4667b328ba8f329879ac9f/tests/test_fastapi.sh#L25-L34.
|
||||
**(
|
||||
{"deprecated": True}
|
||||
if PYDANTIC_VERSION_MINOR_TUPLE >= (2, 10)
|
||||
else {}
|
||||
),
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"title": "Query string",
|
||||
"maxLength": 50,
|
||||
"minLength": 3,
|
||||
"pattern": "^fixedquery$",
|
||||
"type": "string",
|
||||
"description": "Query string for the items to search in the database that have a good match",
|
||||
}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 50,
|
||||
"pattern": "^fixedquery$",
|
||||
},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "Query string",
|
||||
"description": "Query string for the items to search in the database that have a good match",
|
||||
# See https://github.com/pydantic/pydantic/blob/80353c29a824c55dea4667b328ba8f329879ac9f/tests/test_fastapi.sh#L25-L34.
|
||||
**(
|
||||
{"deprecated": True}
|
||||
if PYDANTIC_VERSION_MINOR_TUPLE >= (2, 10)
|
||||
else {}
|
||||
),
|
||||
},
|
||||
"name": "item-query",
|
||||
"in": "query",
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from ...utils import needs_py310
|
||||
@@ -69,23 +68,13 @@ def test_openapi_schema(client: TestClient):
|
||||
"parameters": [
|
||||
{
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [
|
||||
{"type": "array", "items": {"type": "string"}},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "Q",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"title": "Q",
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
}
|
||||
),
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{"type": "array", "items": {"type": "string"}},
|
||||
{"type": "null"},
|
||||
],
|
||||
"title": "Q",
|
||||
},
|
||||
"name": "q",
|
||||
"in": "query",
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
|
||||
@@ -22,57 +21,31 @@ def get_client(request: pytest.FixtureRequest):
|
||||
def test_post_form_no_body(client: TestClient):
|
||||
response = client.post("/files/")
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "file"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "file"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "file"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_post_body_json(client: TestClient):
|
||||
response = client.post("/files/", json={"file": "Foo"})
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "file"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "file"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "file"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_post_file(tmp_path, client: TestClient):
|
||||
|
||||
@@ -2,8 +2,8 @@ import importlib
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
from inline_snapshot import snapshot
|
||||
|
||||
from ...utils import needs_py310
|
||||
|
||||
@@ -59,166 +59,132 @@ def test_post_upload_file(tmp_path: Path, client: TestClient):
|
||||
def test_openapi_schema(client: TestClient):
|
||||
response = client.get("/openapi.json")
|
||||
assert response.status_code == 200, response.text
|
||||
assert response.json() == {
|
||||
"openapi": "3.1.0",
|
||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||
"paths": {
|
||||
"/files/": {
|
||||
"post": {
|
||||
"summary": "Create File",
|
||||
"operationId": "create_file_files__post",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"multipart/form-data": {
|
||||
"schema": IsDict(
|
||||
{
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/Body_create_file_files__post"
|
||||
}
|
||||
],
|
||||
"title": "Body",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
assert response.json() == snapshot(
|
||||
{
|
||||
"openapi": "3.1.0",
|
||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||
"paths": {
|
||||
"/files/": {
|
||||
"post": {
|
||||
"summary": "Create File",
|
||||
"operationId": "create_file_files__post",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"multipart/form-data": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Body_create_file_files__post"
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {"application/json": {"schema": {}}},
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {"application/json": {"schema": {}}},
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
"/uploadfile/": {
|
||||
"post": {
|
||||
"summary": "Create Upload File",
|
||||
"operationId": "create_upload_file_uploadfile__post",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"multipart/form-data": {
|
||||
"schema": IsDict(
|
||||
{
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/Body_create_upload_file_uploadfile__post"
|
||||
}
|
||||
],
|
||||
"title": "Body",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
}
|
||||
},
|
||||
"/uploadfile/": {
|
||||
"post": {
|
||||
"summary": "Create Upload File",
|
||||
"operationId": "create_upload_file_uploadfile__post",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"multipart/form-data": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Body_create_upload_file_uploadfile__post"
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {"application/json": {"schema": {}}},
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {"application/json": {"schema": {}}},
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"Body_create_file_files__post": {
|
||||
"title": "Body_create_file_files__post",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"file": {
|
||||
"title": "File",
|
||||
"anyOf": [
|
||||
{"type": "string", "format": "binary"},
|
||||
{"type": "null"},
|
||||
],
|
||||
}
|
||||
},
|
||||
},
|
||||
"Body_create_upload_file_uploadfile__post": {
|
||||
"title": "Body_create_upload_file_uploadfile__post",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"file": {
|
||||
"title": "File",
|
||||
"anyOf": [
|
||||
{"type": "string", "format": "binary"},
|
||||
{"type": "null"},
|
||||
],
|
||||
}
|
||||
},
|
||||
},
|
||||
"HTTPValidationError": {
|
||||
"title": "HTTPValidationError",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"title": "Detail",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ValidationError"
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
"ValidationError": {
|
||||
"title": "ValidationError",
|
||||
"required": ["loc", "msg", "type"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"loc": {
|
||||
"title": "Location",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [{"type": "string"}, {"type": "integer"}]
|
||||
},
|
||||
},
|
||||
"msg": {"title": "Message", "type": "string"},
|
||||
"type": {"title": "Error Type", "type": "string"},
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"Body_create_file_files__post": {
|
||||
"title": "Body_create_file_files__post",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"file": IsDict(
|
||||
{
|
||||
"title": "File",
|
||||
"anyOf": [
|
||||
{"type": "string", "format": "binary"},
|
||||
{"type": "null"},
|
||||
],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "File", "type": "string", "format": "binary"}
|
||||
)
|
||||
},
|
||||
},
|
||||
"Body_create_upload_file_uploadfile__post": {
|
||||
"title": "Body_create_upload_file_uploadfile__post",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"file": IsDict(
|
||||
{
|
||||
"title": "File",
|
||||
"anyOf": [
|
||||
{"type": "string", "format": "binary"},
|
||||
{"type": "null"},
|
||||
],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "File", "type": "string", "format": "binary"}
|
||||
)
|
||||
},
|
||||
},
|
||||
"HTTPValidationError": {
|
||||
"title": "HTTPValidationError",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"title": "Detail",
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/components/schemas/ValidationError"},
|
||||
}
|
||||
},
|
||||
},
|
||||
"ValidationError": {
|
||||
"title": "ValidationError",
|
||||
"required": ["loc", "msg", "type"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"loc": {
|
||||
"title": "Location",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [{"type": "string"}, {"type": "integer"}]
|
||||
},
|
||||
},
|
||||
"msg": {"title": "Message", "type": "string"},
|
||||
"type": {"title": "Error Type", "type": "string"},
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
@@ -28,57 +27,31 @@ def get_client(app: FastAPI):
|
||||
def test_post_form_no_body(client: TestClient):
|
||||
response = client.post("/files/")
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "files"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "files"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "files"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_post_body_json(client: TestClient):
|
||||
response = client.post("/files/", json={"file": "Foo"})
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "files"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "files"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "files"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_post_files(tmp_path, app: FastAPI):
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
|
||||
@@ -28,135 +27,73 @@ def test_post_body_form(client: TestClient):
|
||||
def test_post_body_form_no_password(client: TestClient):
|
||||
response = client.post("/login/", data={"username": "Foo"})
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "password"],
|
||||
"msg": "Field required",
|
||||
"input": {"username": "Foo"},
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "password"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "password"],
|
||||
"msg": "Field required",
|
||||
"input": {"username": "Foo"},
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_post_body_form_no_username(client: TestClient):
|
||||
response = client.post("/login/", data={"password": "secret"})
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "username"],
|
||||
"msg": "Field required",
|
||||
"input": {"password": "secret"},
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "username"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "username"],
|
||||
"msg": "Field required",
|
||||
"input": {"password": "secret"},
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_post_body_form_no_data(client: TestClient):
|
||||
response = client.post("/login/")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "username"],
|
||||
"msg": "Field required",
|
||||
"input": {},
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "password"],
|
||||
"msg": "Field required",
|
||||
"input": {},
|
||||
},
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "username"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
{
|
||||
"loc": ["body", "password"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "username"],
|
||||
"msg": "Field required",
|
||||
"input": {},
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "password"],
|
||||
"msg": "Field required",
|
||||
"input": {},
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_post_body_json(client: TestClient):
|
||||
response = client.post("/login/", json={"username": "Foo", "password": "secret"})
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "username"],
|
||||
"msg": "Field required",
|
||||
"input": {},
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "password"],
|
||||
"msg": "Field required",
|
||||
"input": {},
|
||||
},
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "username"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
{
|
||||
"loc": ["body", "password"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "username"],
|
||||
"msg": "Field required",
|
||||
"input": {},
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "password"],
|
||||
"msg": "Field required",
|
||||
"input": {},
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_openapi_schema(client: TestClient):
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
|
||||
@@ -28,135 +27,73 @@ def test_post_body_form(client: TestClient):
|
||||
def test_post_body_form_no_password(client: TestClient):
|
||||
response = client.post("/login/", data={"username": "Foo"})
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "password"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "password"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "password"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_post_body_form_no_username(client: TestClient):
|
||||
response = client.post("/login/", data={"password": "secret"})
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "username"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "username"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "username"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_post_body_form_no_data(client: TestClient):
|
||||
response = client.post("/login/")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "username"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "password"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "username"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
{
|
||||
"loc": ["body", "password"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "username"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "password"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_post_body_json(client: TestClient):
|
||||
response = client.post("/login/", json={"username": "Foo", "password": "secret"})
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "username"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "password"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "username"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
{
|
||||
"loc": ["body", "password"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "username"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "password"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_openapi_schema(client: TestClient):
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi import FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
@@ -28,140 +27,76 @@ def get_client(app: FastAPI):
|
||||
def test_post_form_no_body(client: TestClient):
|
||||
response = client.post("/files/")
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "file"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "fileb"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "file"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
{
|
||||
"loc": ["body", "fileb"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
{
|
||||
"loc": ["body", "token"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "file"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "fileb"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_post_form_no_file(client: TestClient):
|
||||
response = client.post("/files/", data={"token": "foo"})
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "file"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "fileb"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "file"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
{
|
||||
"loc": ["body", "fileb"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "file"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "fileb"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_post_body_json(client: TestClient):
|
||||
response = client.post("/files/", json={"file": "Foo", "token": "Bar"})
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "file"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "fileb"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "file"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
{
|
||||
"loc": ["body", "fileb"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
{
|
||||
"loc": ["body", "token"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "file"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "fileb"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_post_file_no_token(tmp_path, app: FastAPI):
|
||||
@@ -172,40 +107,22 @@ def test_post_file_no_token(tmp_path, app: FastAPI):
|
||||
with path.open("rb") as file:
|
||||
response = client.post("/files/", files={"file": file})
|
||||
assert response.status_code == 422, response.text
|
||||
assert response.json() == IsDict(
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "fileb"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
) | IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": ["body", "fileb"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
{
|
||||
"loc": ["body", "token"],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing",
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
assert response.json() == {
|
||||
"detail": [
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "fileb"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["body", "token"],
|
||||
"msg": "Field required",
|
||||
"input": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_post_files_and_token(tmp_path, app: FastAPI):
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict, IsOneOf
|
||||
from fastapi.testclient import TestClient
|
||||
from inline_snapshot import snapshot
|
||||
|
||||
from ...utils import needs_py310
|
||||
|
||||
@@ -42,125 +42,115 @@ def test_post_user(client: TestClient):
|
||||
def test_openapi_schema(client: TestClient):
|
||||
response = client.get("/openapi.json")
|
||||
assert response.status_code == 200, response.text
|
||||
assert response.json() == {
|
||||
"openapi": "3.1.0",
|
||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||
"paths": {
|
||||
"/user/": {
|
||||
"post": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {"$ref": "#/components/schemas/UserOut"}
|
||||
}
|
||||
assert response.json() == snapshot(
|
||||
{
|
||||
"openapi": "3.1.0",
|
||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||
"paths": {
|
||||
"/user/": {
|
||||
"post": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UserOut"
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"summary": "Create User",
|
||||
"operationId": "create_user_user__post",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
"schema": {"$ref": "#/components/schemas/UserIn"}
|
||||
}
|
||||
},
|
||||
"required": True,
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"UserOut": {
|
||||
"title": "UserOut",
|
||||
"required": ["username", "email"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"username": {"title": "Username", "type": "string"},
|
||||
"email": {
|
||||
"title": "Email",
|
||||
"type": "string",
|
||||
"format": "email",
|
||||
},
|
||||
"full_name": {
|
||||
"title": "Full Name",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
},
|
||||
},
|
||||
},
|
||||
"summary": "Create User",
|
||||
"operationId": "create_user_user__post",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {"$ref": "#/components/schemas/UserIn"}
|
||||
"UserIn": {
|
||||
"title": "UserIn",
|
||||
"required": ["username", "password", "email"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"username": {"title": "Username", "type": "string"},
|
||||
"password": {"title": "Password", "type": "string"},
|
||||
"email": {
|
||||
"title": "Email",
|
||||
"type": "string",
|
||||
"format": "email",
|
||||
},
|
||||
"full_name": {
|
||||
"title": "Full Name",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
},
|
||||
},
|
||||
},
|
||||
"ValidationError": {
|
||||
"title": "ValidationError",
|
||||
"required": ["loc", "msg", "type"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"loc": {
|
||||
"title": "Location",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [{"type": "string"}, {"type": "integer"}]
|
||||
},
|
||||
},
|
||||
"msg": {"title": "Message", "type": "string"},
|
||||
"type": {"title": "Error Type", "type": "string"},
|
||||
},
|
||||
},
|
||||
"HTTPValidationError": {
|
||||
"title": "HTTPValidationError",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"title": "Detail",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ValidationError"
|
||||
},
|
||||
}
|
||||
},
|
||||
"required": True,
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"UserOut": {
|
||||
"title": "UserOut",
|
||||
"required": IsOneOf(
|
||||
["username", "email", "full_name"],
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
["username", "email"],
|
||||
),
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"username": {"title": "Username", "type": "string"},
|
||||
"email": {
|
||||
"title": "Email",
|
||||
"type": "string",
|
||||
"format": "email",
|
||||
},
|
||||
"full_name": IsDict(
|
||||
{
|
||||
"title": "Full Name",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Full Name", "type": "string"}
|
||||
),
|
||||
},
|
||||
},
|
||||
"UserIn": {
|
||||
"title": "UserIn",
|
||||
"required": ["username", "password", "email"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"username": {"title": "Username", "type": "string"},
|
||||
"password": {"title": "Password", "type": "string"},
|
||||
"email": {
|
||||
"title": "Email",
|
||||
"type": "string",
|
||||
"format": "email",
|
||||
},
|
||||
"full_name": IsDict(
|
||||
{
|
||||
"title": "Full Name",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Full Name", "type": "string"}
|
||||
),
|
||||
},
|
||||
},
|
||||
"ValidationError": {
|
||||
"title": "ValidationError",
|
||||
"required": ["loc", "msg", "type"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"loc": {
|
||||
"title": "Location",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [{"type": "string"}, {"type": "integer"}]
|
||||
},
|
||||
},
|
||||
"msg": {"title": "Message", "type": "string"},
|
||||
"type": {"title": "Error Type", "type": "string"},
|
||||
},
|
||||
},
|
||||
"HTTPValidationError": {
|
||||
"title": "HTTPValidationError",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"title": "Detail",
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/components/schemas/ValidationError"},
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict, IsOneOf
|
||||
from fastapi.testclient import TestClient
|
||||
from inline_snapshot import snapshot
|
||||
|
||||
from ...utils import needs_py310
|
||||
|
||||
@@ -42,125 +42,115 @@ def test_post_user(client: TestClient):
|
||||
def test_openapi_schema(client: TestClient):
|
||||
response = client.get("/openapi.json")
|
||||
assert response.status_code == 200, response.text
|
||||
assert response.json() == {
|
||||
"openapi": "3.1.0",
|
||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||
"paths": {
|
||||
"/user/": {
|
||||
"post": {
|
||||
"summary": "Create User",
|
||||
"operationId": "create_user_user__post",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {"$ref": "#/components/schemas/UserIn"}
|
||||
assert response.json() == snapshot(
|
||||
{
|
||||
"openapi": "3.1.0",
|
||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||
"paths": {
|
||||
"/user/": {
|
||||
"post": {
|
||||
"summary": "Create User",
|
||||
"operationId": "create_user_user__post",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {"$ref": "#/components/schemas/UserIn"}
|
||||
}
|
||||
},
|
||||
"required": True,
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/BaseUser"
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"BaseUser": {
|
||||
"title": "BaseUser",
|
||||
"required": ["username", "email"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"username": {"title": "Username", "type": "string"},
|
||||
"email": {
|
||||
"title": "Email",
|
||||
"type": "string",
|
||||
"format": "email",
|
||||
},
|
||||
"full_name": {
|
||||
"title": "Full Name",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
},
|
||||
},
|
||||
},
|
||||
"HTTPValidationError": {
|
||||
"title": "HTTPValidationError",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"title": "Detail",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ValidationError"
|
||||
},
|
||||
}
|
||||
},
|
||||
"required": True,
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {"$ref": "#/components/schemas/BaseUser"}
|
||||
}
|
||||
"UserIn": {
|
||||
"title": "UserIn",
|
||||
"required": ["username", "email", "password"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"username": {"title": "Username", "type": "string"},
|
||||
"email": {
|
||||
"title": "Email",
|
||||
"type": "string",
|
||||
"format": "email",
|
||||
},
|
||||
"full_name": {
|
||||
"title": "Full Name",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
},
|
||||
"password": {"title": "Password", "type": "string"},
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ValidationError": {
|
||||
"title": "ValidationError",
|
||||
"required": ["loc", "msg", "type"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"loc": {
|
||||
"title": "Location",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [{"type": "string"}, {"type": "integer"}]
|
||||
},
|
||||
},
|
||||
"msg": {"title": "Message", "type": "string"},
|
||||
"type": {"title": "Error Type", "type": "string"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"BaseUser": {
|
||||
"title": "BaseUser",
|
||||
"required": IsOneOf(
|
||||
["username", "email", "full_name"],
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
["username", "email"],
|
||||
),
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"username": {"title": "Username", "type": "string"},
|
||||
"email": {
|
||||
"title": "Email",
|
||||
"type": "string",
|
||||
"format": "email",
|
||||
},
|
||||
"full_name": IsDict(
|
||||
{
|
||||
"title": "Full Name",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Full Name", "type": "string"}
|
||||
),
|
||||
},
|
||||
},
|
||||
"HTTPValidationError": {
|
||||
"title": "HTTPValidationError",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"title": "Detail",
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/components/schemas/ValidationError"},
|
||||
}
|
||||
},
|
||||
},
|
||||
"UserIn": {
|
||||
"title": "UserIn",
|
||||
"required": ["username", "email", "password"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"username": {"title": "Username", "type": "string"},
|
||||
"email": {
|
||||
"title": "Email",
|
||||
"type": "string",
|
||||
"format": "email",
|
||||
},
|
||||
"full_name": IsDict(
|
||||
{
|
||||
"title": "Full Name",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Full Name", "type": "string"}
|
||||
),
|
||||
"password": {"title": "Password", "type": "string"},
|
||||
},
|
||||
},
|
||||
"ValidationError": {
|
||||
"title": "ValidationError",
|
||||
"required": ["loc", "msg", "type"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"loc": {
|
||||
"title": "Location",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [{"type": "string"}, {"type": "integer"}]
|
||||
},
|
||||
},
|
||||
"msg": {"title": "Message", "type": "string"},
|
||||
"type": {"title": "Error Type", "type": "string"},
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict, IsOneOf
|
||||
from fastapi.testclient import TestClient
|
||||
from inline_snapshot import snapshot
|
||||
|
||||
from ...utils import needs_py310
|
||||
|
||||
@@ -50,104 +50,98 @@ def test_get(url, data, client: TestClient):
|
||||
def test_openapi_schema(client: TestClient):
|
||||
response = client.get("/openapi.json")
|
||||
assert response.status_code == 200, response.text
|
||||
assert response.json() == {
|
||||
"openapi": "3.1.0",
|
||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||
"paths": {
|
||||
"/items/{item_id}": {
|
||||
"get": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {"$ref": "#/components/schemas/Item"}
|
||||
}
|
||||
},
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
assert response.json() == snapshot(
|
||||
{
|
||||
"openapi": "3.1.0",
|
||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||
"paths": {
|
||||
"/items/{item_id}": {
|
||||
"get": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {"$ref": "#/components/schemas/Item"}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"summary": "Read Item",
|
||||
"operationId": "read_item_items__item_id__get",
|
||||
"parameters": [
|
||||
{
|
||||
"required": True,
|
||||
"schema": {"title": "Item Id", "type": "string"},
|
||||
"name": "item_id",
|
||||
"in": "path",
|
||||
}
|
||||
],
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"Item": {
|
||||
"title": "Item",
|
||||
"required": IsOneOf(
|
||||
["name", "description", "price", "tax", "tags"],
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
["name", "price"],
|
||||
),
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"title": "Name", "type": "string"},
|
||||
"price": {"title": "Price", "type": "number"},
|
||||
"description": IsDict(
|
||||
"summary": "Read Item",
|
||||
"operationId": "read_item_items__item_id__get",
|
||||
"parameters": [
|
||||
{
|
||||
"required": True,
|
||||
"schema": {"title": "Item Id", "type": "string"},
|
||||
"name": "item_id",
|
||||
"in": "path",
|
||||
}
|
||||
],
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"Item": {
|
||||
"title": "Item",
|
||||
"required": ["name", "price"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"title": "Name", "type": "string"},
|
||||
"price": {"title": "Price", "type": "number"},
|
||||
"description": {
|
||||
"title": "Description",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Description", "type": "string"}
|
||||
),
|
||||
"tax": {"title": "Tax", "type": "number", "default": 10.5},
|
||||
"tags": {
|
||||
"title": "Tags",
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
"default": [],
|
||||
},
|
||||
},
|
||||
},
|
||||
"ValidationError": {
|
||||
"title": "ValidationError",
|
||||
"required": ["loc", "msg", "type"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"loc": {
|
||||
"title": "Location",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [{"type": "string"}, {"type": "integer"}]
|
||||
},
|
||||
"tax": {"title": "Tax", "type": "number", "default": 10.5},
|
||||
"tags": {
|
||||
"title": "Tags",
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
"default": [],
|
||||
},
|
||||
},
|
||||
"msg": {"title": "Message", "type": "string"},
|
||||
"type": {"title": "Error Type", "type": "string"},
|
||||
},
|
||||
},
|
||||
"HTTPValidationError": {
|
||||
"title": "HTTPValidationError",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"title": "Detail",
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/components/schemas/ValidationError"},
|
||||
}
|
||||
"ValidationError": {
|
||||
"title": "ValidationError",
|
||||
"required": ["loc", "msg", "type"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"loc": {
|
||||
"title": "Location",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [{"type": "string"}, {"type": "integer"}]
|
||||
},
|
||||
},
|
||||
"msg": {"title": "Message", "type": "string"},
|
||||
"type": {"title": "Error Type", "type": "string"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
"HTTPValidationError": {
|
||||
"title": "HTTPValidationError",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"title": "Detail",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ValidationError"
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict, IsOneOf
|
||||
from fastapi.testclient import TestClient
|
||||
from inline_snapshot import snapshot
|
||||
|
||||
from ...utils import needs_py310
|
||||
|
||||
@@ -40,132 +40,126 @@ def test_read_item_public_data(client: TestClient):
|
||||
def test_openapi_schema(client: TestClient):
|
||||
response = client.get("/openapi.json")
|
||||
assert response.status_code == 200, response.text
|
||||
assert response.json() == {
|
||||
"openapi": "3.1.0",
|
||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||
"paths": {
|
||||
"/items/{item_id}/name": {
|
||||
"get": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {"$ref": "#/components/schemas/Item"}
|
||||
}
|
||||
},
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
assert response.json() == snapshot(
|
||||
{
|
||||
"openapi": "3.1.0",
|
||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||
"paths": {
|
||||
"/items/{item_id}/name": {
|
||||
"get": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {"$ref": "#/components/schemas/Item"}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"summary": "Read Item Name",
|
||||
"operationId": "read_item_name_items__item_id__name_get",
|
||||
"parameters": [
|
||||
{
|
||||
"required": True,
|
||||
"schema": {"title": "Item Id", "type": "string"},
|
||||
"name": "item_id",
|
||||
"in": "path",
|
||||
}
|
||||
],
|
||||
}
|
||||
},
|
||||
"/items/{item_id}/public": {
|
||||
"get": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {"$ref": "#/components/schemas/Item"}
|
||||
}
|
||||
},
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"summary": "Read Item Public Data",
|
||||
"operationId": "read_item_public_data_items__item_id__public_get",
|
||||
"parameters": [
|
||||
{
|
||||
"required": True,
|
||||
"schema": {"title": "Item Id", "type": "string"},
|
||||
"name": "item_id",
|
||||
"in": "path",
|
||||
}
|
||||
],
|
||||
}
|
||||
},
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"Item": {
|
||||
"title": "Item",
|
||||
"required": IsOneOf(
|
||||
["name", "description", "price", "tax"],
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
["name", "price"],
|
||||
),
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"title": "Name", "type": "string"},
|
||||
"price": {"title": "Price", "type": "number"},
|
||||
"description": IsDict(
|
||||
"summary": "Read Item Name",
|
||||
"operationId": "read_item_name_items__item_id__name_get",
|
||||
"parameters": [
|
||||
{
|
||||
"required": True,
|
||||
"schema": {"title": "Item Id", "type": "string"},
|
||||
"name": "item_id",
|
||||
"in": "path",
|
||||
}
|
||||
],
|
||||
}
|
||||
},
|
||||
"/items/{item_id}/public": {
|
||||
"get": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {"$ref": "#/components/schemas/Item"}
|
||||
}
|
||||
},
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
"summary": "Read Item Public Data",
|
||||
"operationId": "read_item_public_data_items__item_id__public_get",
|
||||
"parameters": [
|
||||
{
|
||||
"required": True,
|
||||
"schema": {"title": "Item Id", "type": "string"},
|
||||
"name": "item_id",
|
||||
"in": "path",
|
||||
}
|
||||
],
|
||||
}
|
||||
},
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"Item": {
|
||||
"title": "Item",
|
||||
"required": ["name", "price"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"title": "Name", "type": "string"},
|
||||
"price": {"title": "Price", "type": "number"},
|
||||
"description": {
|
||||
"title": "Description",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Description", "type": "string"}
|
||||
),
|
||||
"tax": {"title": "Tax", "type": "number", "default": 10.5},
|
||||
},
|
||||
},
|
||||
"ValidationError": {
|
||||
"title": "ValidationError",
|
||||
"required": ["loc", "msg", "type"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"loc": {
|
||||
"title": "Location",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [{"type": "string"}, {"type": "integer"}]
|
||||
},
|
||||
"tax": {"title": "Tax", "type": "number", "default": 10.5},
|
||||
},
|
||||
"msg": {"title": "Message", "type": "string"},
|
||||
"type": {"title": "Error Type", "type": "string"},
|
||||
},
|
||||
},
|
||||
"HTTPValidationError": {
|
||||
"title": "HTTPValidationError",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"title": "Detail",
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/components/schemas/ValidationError"},
|
||||
}
|
||||
"ValidationError": {
|
||||
"title": "ValidationError",
|
||||
"required": ["loc", "msg", "type"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"loc": {
|
||||
"title": "Location",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [{"type": "string"}, {"type": "integer"}]
|
||||
},
|
||||
},
|
||||
"msg": {"title": "Message", "type": "string"},
|
||||
"type": {"title": "Error Type", "type": "string"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
"HTTPValidationError": {
|
||||
"title": "HTTPValidationError",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"title": "Detail",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ValidationError"
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict, IsOneOf
|
||||
from fastapi.testclient import TestClient
|
||||
from inline_snapshot import snapshot
|
||||
|
||||
from ...utils import needs_py310
|
||||
|
||||
@@ -40,132 +40,126 @@ def test_read_item_public_data(client: TestClient):
|
||||
def test_openapi_schema(client: TestClient):
|
||||
response = client.get("/openapi.json")
|
||||
assert response.status_code == 200, response.text
|
||||
assert response.json() == {
|
||||
"openapi": "3.1.0",
|
||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||
"paths": {
|
||||
"/items/{item_id}/name": {
|
||||
"get": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {"$ref": "#/components/schemas/Item"}
|
||||
}
|
||||
},
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
assert response.json() == snapshot(
|
||||
{
|
||||
"openapi": "3.1.0",
|
||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||
"paths": {
|
||||
"/items/{item_id}/name": {
|
||||
"get": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {"$ref": "#/components/schemas/Item"}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"summary": "Read Item Name",
|
||||
"operationId": "read_item_name_items__item_id__name_get",
|
||||
"parameters": [
|
||||
{
|
||||
"required": True,
|
||||
"schema": {"title": "Item Id", "type": "string"},
|
||||
"name": "item_id",
|
||||
"in": "path",
|
||||
}
|
||||
],
|
||||
}
|
||||
},
|
||||
"/items/{item_id}/public": {
|
||||
"get": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {"$ref": "#/components/schemas/Item"}
|
||||
}
|
||||
},
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"summary": "Read Item Public Data",
|
||||
"operationId": "read_item_public_data_items__item_id__public_get",
|
||||
"parameters": [
|
||||
{
|
||||
"required": True,
|
||||
"schema": {"title": "Item Id", "type": "string"},
|
||||
"name": "item_id",
|
||||
"in": "path",
|
||||
}
|
||||
],
|
||||
}
|
||||
},
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"Item": {
|
||||
"title": "Item",
|
||||
"required": IsOneOf(
|
||||
["name", "description", "price", "tax"],
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
["name", "price"],
|
||||
),
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"title": "Name", "type": "string"},
|
||||
"price": {"title": "Price", "type": "number"},
|
||||
"description": IsDict(
|
||||
"summary": "Read Item Name",
|
||||
"operationId": "read_item_name_items__item_id__name_get",
|
||||
"parameters": [
|
||||
{
|
||||
"required": True,
|
||||
"schema": {"title": "Item Id", "type": "string"},
|
||||
"name": "item_id",
|
||||
"in": "path",
|
||||
}
|
||||
],
|
||||
}
|
||||
},
|
||||
"/items/{item_id}/public": {
|
||||
"get": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {"$ref": "#/components/schemas/Item"}
|
||||
}
|
||||
},
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
"summary": "Read Item Public Data",
|
||||
"operationId": "read_item_public_data_items__item_id__public_get",
|
||||
"parameters": [
|
||||
{
|
||||
"required": True,
|
||||
"schema": {"title": "Item Id", "type": "string"},
|
||||
"name": "item_id",
|
||||
"in": "path",
|
||||
}
|
||||
],
|
||||
}
|
||||
},
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"Item": {
|
||||
"title": "Item",
|
||||
"required": ["name", "price"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"title": "Name", "type": "string"},
|
||||
"price": {"title": "Price", "type": "number"},
|
||||
"description": {
|
||||
"title": "Description",
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{"title": "Description", "type": "string"}
|
||||
),
|
||||
"tax": {"title": "Tax", "type": "number", "default": 10.5},
|
||||
},
|
||||
},
|
||||
"ValidationError": {
|
||||
"title": "ValidationError",
|
||||
"required": ["loc", "msg", "type"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"loc": {
|
||||
"title": "Location",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [{"type": "string"}, {"type": "integer"}]
|
||||
},
|
||||
"tax": {"title": "Tax", "type": "number", "default": 10.5},
|
||||
},
|
||||
"msg": {"title": "Message", "type": "string"},
|
||||
"type": {"title": "Error Type", "type": "string"},
|
||||
},
|
||||
},
|
||||
"HTTPValidationError": {
|
||||
"title": "HTTPValidationError",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"title": "Detail",
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/components/schemas/ValidationError"},
|
||||
}
|
||||
"ValidationError": {
|
||||
"title": "ValidationError",
|
||||
"required": ["loc", "msg", "type"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"loc": {
|
||||
"title": "Location",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [{"type": "string"}, {"type": "integer"}]
|
||||
},
|
||||
},
|
||||
"msg": {"title": "Message", "type": "string"},
|
||||
"type": {"title": "Error Type", "type": "string"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
"HTTPValidationError": {
|
||||
"title": "HTTPValidationError",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"title": "Detail",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ValidationError"
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user