Coverage for tests/test_forms_single_model.py: 100%
51 statements
« prev ^ index » next coverage.py v7.6.1, created at 2025-12-04 08:29 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2025-12-04 08:29 +0000
1from typing import List, Optional 1abcdefg
3from dirty_equals import IsDict 1abcdefg
4from fastapi import FastAPI, Form 1abcdefg
5from fastapi._compat import PYDANTIC_V2 1abcdefg
6from fastapi.testclient import TestClient 1abcdefg
7from pydantic import BaseModel, Field 1abcdefg
8from typing_extensions import Annotated 1abcdefg
10app = FastAPI() 1abcdefg
13class FormModel(BaseModel): 1abcdefg
14 username: str 1abcdefg
15 lastname: str 1abcdefg
16 age: Optional[int] = None 1abcdefg
17 tags: List[str] = ["foo", "bar"] 1abcdefg
18 alias_with: str = Field(alias="with", default="nothing") 1abcdefg
21class FormModelExtraAllow(BaseModel): 1abcdefg
22 param: str 1abcdefg
24 if PYDANTIC_V2: 1abcdefg
25 model_config = {"extra": "allow"} 1abcdefg
26 else:
28 class Config: 1abcdef
29 extra = "allow" 1abcdef
32@app.post("/form/") 1abcdefg
33def post_form(user: Annotated[FormModel, Form()]): 1abcdefg
34 return user 1hijklmnopqrstu
37@app.post("/form-extra-allow/") 1abcdefg
38def post_form_extra_allow(params: Annotated[FormModelExtraAllow, Form()]): 1abcdefg
39 return params 1vwxyzABCDEFGHI
42client = TestClient(app) 1abcdefg
45def test_send_all_data(): 1abcdefg
46 response = client.post( 1ikmoqsu
47 "/form/",
48 data={
49 "username": "Rick",
50 "lastname": "Sanchez",
51 "age": "70",
52 "tags": ["plumbus", "citadel"],
53 "with": "something",
54 },
55 )
56 assert response.status_code == 200, response.text 1ikmoqsu
57 assert response.json() == { 1ikmoqsu
58 "username": "Rick",
59 "lastname": "Sanchez",
60 "age": 70,
61 "tags": ["plumbus", "citadel"],
62 "with": "something",
63 }
66def test_defaults(): 1abcdefg
67 response = client.post("/form/", data={"username": "Rick", "lastname": "Sanchez"}) 1hjlnprt
68 assert response.status_code == 200, response.text 1hjlnprt
69 assert response.json() == { 1hjlnprt
70 "username": "Rick",
71 "lastname": "Sanchez",
72 "age": None,
73 "tags": ["foo", "bar"],
74 "with": "nothing",
75 }
78def test_invalid_data(): 1abcdefg
79 response = client.post( 1JKLMNOP
80 "/form/",
81 data={
82 "username": "Rick",
83 "lastname": "Sanchez",
84 "age": "seventy",
85 "tags": ["plumbus", "citadel"],
86 },
87 )
88 assert response.status_code == 422, response.text 1JKLMNOP
89 assert response.json() == IsDict( 1JKLMNOP
90 {
91 "detail": [
92 {
93 "type": "int_parsing",
94 "loc": ["body", "age"],
95 "msg": "Input should be a valid integer, unable to parse string as an integer",
96 "input": "seventy",
97 }
98 ]
99 }
100 ) | IsDict(
101 # TODO: remove when deprecating Pydantic v1
102 {
103 "detail": [
104 {
105 "loc": ["body", "age"],
106 "msg": "value is not a valid integer",
107 "type": "type_error.integer",
108 }
109 ]
110 }
111 )
114def test_no_data(): 1abcdefg
115 response = client.post("/form/") 1QRSTUVW
116 assert response.status_code == 422, response.text 1QRSTUVW
117 assert response.json() == IsDict( 1QRSTUVW
118 {
119 "detail": [
120 {
121 "type": "missing",
122 "loc": ["body", "username"],
123 "msg": "Field required",
124 "input": {"tags": ["foo", "bar"], "with": "nothing"},
125 },
126 {
127 "type": "missing",
128 "loc": ["body", "lastname"],
129 "msg": "Field required",
130 "input": {"tags": ["foo", "bar"], "with": "nothing"},
131 },
132 ]
133 }
134 ) | IsDict(
135 # TODO: remove when deprecating Pydantic v1
136 {
137 "detail": [
138 {
139 "loc": ["body", "username"],
140 "msg": "field required",
141 "type": "value_error.missing",
142 },
143 {
144 "loc": ["body", "lastname"],
145 "msg": "field required",
146 "type": "value_error.missing",
147 },
148 ]
149 }
150 )
153def test_extra_param_single(): 1abcdefg
154 response = client.post( 1wyACEGI
155 "/form-extra-allow/",
156 data={
157 "param": "123",
158 "extra_param": "456",
159 },
160 )
161 assert response.status_code == 200, response.text 1wyACEGI
162 assert response.json() == { 1wyACEGI
163 "param": "123",
164 "extra_param": "456",
165 }
168def test_extra_param_list(): 1abcdefg
169 response = client.post( 1vxzBDFH
170 "/form-extra-allow/",
171 data={
172 "param": "123",
173 "extra_params": ["456", "789"],
174 },
175 )
176 assert response.status_code == 200, response.text 1vxzBDFH
177 assert response.json() == { 1vxzBDFH
178 "param": "123",
179 "extra_params": ["456", "789"],
180 }