Coverage for tests / test_tutorial / test_body_nested_models / test_tutorial006.py: 100%

31 statements  

« prev     ^ index     » next       coverage.py v7.13.3, created at 2026-02-12 18:15 +0000

1import importlib 1abdc

2 

3import pytest 1abdc

4from dirty_equals import IsList 1abdc

5from fastapi.testclient import TestClient 1abdc

6from inline_snapshot import snapshot 1abdc

7 

8from ...utils import needs_py310 1abdc

9 

10 

11@pytest.fixture( 1abdc

12 name="client", 

13 params=[ 

14 pytest.param("tutorial006_py310", marks=needs_py310), 

15 ], 

16) 

17def get_client(request: pytest.FixtureRequest): 1abdc

18 mod = importlib.import_module(f"docs_src.body_nested_models.{request.param}") 1abc

19 

20 client = TestClient(mod.app) 1abc

21 return client 1abc

22 

23 

24def test_put_all(client: TestClient): 1abdc

25 response = client.put( 1efg

26 "/items/123", 

27 json={ 

28 "name": "Foo", 

29 "description": "A very nice Item", 

30 "price": 35.4, 

31 "tax": 3.2, 

32 "tags": ["foo", "bar", "foo"], 

33 "images": [ 

34 {"url": "http://example.com/image.png", "name": "example image"} 

35 ], 

36 }, 

37 ) 

38 assert response.status_code == 200, response.text 1efg

39 assert response.json() == { 1efg

40 "item_id": 123, 

41 "item": { 

42 "name": "Foo", 

43 "description": "A very nice Item", 

44 "price": 35.4, 

45 "tax": 3.2, 

46 "tags": IsList("foo", "bar", check_order=False), 

47 "images": [ 

48 {"url": "http://example.com/image.png", "name": "example image"} 

49 ], 

50 }, 

51 } 

52 

53 

54def test_put_only_required(client: TestClient): 1abdc

55 response = client.put( 1hij

56 "/items/5", 

57 json={"name": "Foo", "price": 35.4}, 

58 ) 

59 assert response.status_code == 200, response.text 1hij

60 assert response.json() == { 1hij

61 "item_id": 5, 

62 "item": { 

63 "name": "Foo", 

64 "description": None, 

65 "price": 35.4, 

66 "tax": None, 

67 "tags": [], 

68 "images": None, 

69 }, 

70 } 

71 

72 

73def test_put_empty_body(client: TestClient): 1abdc

74 response = client.put( 1klm

75 "/items/5", 

76 json={}, 

77 ) 

78 assert response.status_code == 422, response.text 1klm

79 assert response.json() == { 1klm

80 "detail": [ 

81 { 

82 "loc": ["body", "name"], 

83 "input": {}, 

84 "msg": "Field required", 

85 "type": "missing", 

86 }, 

87 { 

88 "loc": ["body", "price"], 

89 "input": {}, 

90 "msg": "Field required", 

91 "type": "missing", 

92 }, 

93 ] 

94 } 

95 

96 

97def test_put_images_not_list(client: TestClient): 1abdc

98 response = client.put( 1nop

99 "/items/5", 

100 json={ 

101 "name": "Foo", 

102 "price": 35.4, 

103 "images": {"url": "http://example.com/image.png", "name": "example image"}, 

104 }, 

105 ) 

106 assert response.status_code == 422, response.text 1nop

107 assert response.json() == { 1nop

108 "detail": [ 

109 { 

110 "loc": ["body", "images"], 

111 "input": { 

112 "url": "http://example.com/image.png", 

113 "name": "example image", 

114 }, 

115 "msg": "Input should be a valid list", 

116 "type": "list_type", 

117 }, 

118 ] 

119 } 

120 

121 

122def test_openapi_schema(client: TestClient): 1abdc

123 response = client.get("/openapi.json") 1qrs

124 assert response.status_code == 200, response.text 1qrs

125 assert response.json() == snapshot( 1qrs

126 { 

127 "openapi": "3.1.0", 

128 "info": {"title": "FastAPI", "version": "0.1.0"}, 

129 "paths": { 

130 "/items/{item_id}": { 

131 "put": { 

132 "parameters": [ 

133 { 

134 "in": "path", 

135 "name": "item_id", 

136 "required": True, 

137 "schema": { 

138 "title": "Item Id", 

139 "type": "integer", 

140 }, 

141 }, 

142 ], 

143 "responses": { 

144 "200": { 

145 "description": "Successful Response", 

146 "content": {"application/json": {"schema": {}}}, 

147 }, 

148 "422": { 

149 "description": "Validation Error", 

150 "content": { 

151 "application/json": { 

152 "schema": { 

153 "$ref": "#/components/schemas/HTTPValidationError" 

154 } 

155 } 

156 }, 

157 }, 

158 }, 

159 "summary": "Update Item", 

160 "operationId": "update_item_items__item_id__put", 

161 "requestBody": { 

162 "content": { 

163 "application/json": { 

164 "schema": { 

165 "$ref": "#/components/schemas/Item", 

166 } 

167 } 

168 }, 

169 "required": True, 

170 }, 

171 } 

172 } 

173 }, 

174 "components": { 

175 "schemas": { 

176 "Image": { 

177 "properties": { 

178 "url": { 

179 "title": "Url", 

180 "type": "string", 

181 "format": "uri", 

182 "maxLength": 2083, 

183 "minLength": 1, 

184 }, 

185 "name": { 

186 "title": "Name", 

187 "type": "string", 

188 }, 

189 }, 

190 "required": ["url", "name"], 

191 "title": "Image", 

192 "type": "object", 

193 }, 

194 "Item": { 

195 "properties": { 

196 "name": { 

197 "title": "Name", 

198 "type": "string", 

199 }, 

200 "description": { 

201 "title": "Description", 

202 "anyOf": [{"type": "string"}, {"type": "null"}], 

203 }, 

204 "price": { 

205 "title": "Price", 

206 "type": "number", 

207 }, 

208 "tax": { 

209 "title": "Tax", 

210 "anyOf": [{"type": "number"}, {"type": "null"}], 

211 }, 

212 "tags": { 

213 "title": "Tags", 

214 "default": [], 

215 "type": "array", 

216 "items": {"type": "string"}, 

217 "uniqueItems": True, 

218 }, 

219 "images": { 

220 "anyOf": [ 

221 { 

222 "items": { 

223 "$ref": "#/components/schemas/Image", 

224 }, 

225 "type": "array", 

226 }, 

227 { 

228 "type": "null", 

229 }, 

230 ], 

231 "title": "Images", 

232 }, 

233 }, 

234 "required": [ 

235 "name", 

236 "price", 

237 ], 

238 "title": "Item", 

239 "type": "object", 

240 }, 

241 "ValidationError": { 

242 "title": "ValidationError", 

243 "required": ["loc", "msg", "type"], 

244 "type": "object", 

245 "properties": { 

246 "loc": { 

247 "title": "Location", 

248 "type": "array", 

249 "items": { 

250 "anyOf": [{"type": "string"}, {"type": "integer"}] 

251 }, 

252 }, 

253 "msg": {"title": "Message", "type": "string"}, 

254 "type": {"title": "Error Type", "type": "string"}, 

255 "input": {"title": "Input"}, 

256 "ctx": {"title": "Context", "type": "object"}, 

257 }, 

258 }, 

259 "HTTPValidationError": { 

260 "title": "HTTPValidationError", 

261 "type": "object", 

262 "properties": { 

263 "detail": { 

264 "title": "Detail", 

265 "type": "array", 

266 "items": { 

267 "$ref": "#/components/schemas/ValidationError" 

268 }, 

269 } 

270 }, 

271 }, 

272 } 

273 }, 

274 } 

275 )