Coverage for tests/test_tutorial/test_request_forms_and_files/test_tutorial001_an_py39.py: 100%

53 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2024-08-08 03:53 +0000

1import pytest 1eabcd

2from dirty_equals import IsDict 1eabcd

3from fastapi import FastAPI 1eabcd

4from fastapi.testclient import TestClient 1eabcd

5 

6from ...utils import needs_py39 1eabcd

7 

8 

9@pytest.fixture(name="app") 1eabcd

10def get_app(): 1eabcd

11 from docs_src.request_forms_and_files.tutorial001_an_py39 import app 1abcd

12 

13 return app 1abcd

14 

15 

16@pytest.fixture(name="client") 1eabcd

17def get_client(app: FastAPI): 1eabcd

18 client = TestClient(app) 1abcd

19 return client 1abcd

20 

21 

22@needs_py39 1eabcd

23def test_post_form_no_body(client: TestClient): 1eabcd

24 response = client.post("/files/") 1abcd

25 assert response.status_code == 422, response.text 1abcd

26 assert response.json() == IsDict( 1abcd

27 { 

28 "detail": [ 

29 { 

30 "type": "missing", 

31 "loc": ["body", "file"], 

32 "msg": "Field required", 

33 "input": None, 

34 }, 

35 { 

36 "type": "missing", 

37 "loc": ["body", "fileb"], 

38 "msg": "Field required", 

39 "input": None, 

40 }, 

41 { 

42 "type": "missing", 

43 "loc": ["body", "token"], 

44 "msg": "Field required", 

45 "input": None, 

46 }, 

47 ] 

48 } 

49 ) | IsDict( 

50 # TODO: remove when deprecating Pydantic v1 

51 { 

52 "detail": [ 

53 { 

54 "loc": ["body", "file"], 

55 "msg": "field required", 

56 "type": "value_error.missing", 

57 }, 

58 { 

59 "loc": ["body", "fileb"], 

60 "msg": "field required", 

61 "type": "value_error.missing", 

62 }, 

63 { 

64 "loc": ["body", "token"], 

65 "msg": "field required", 

66 "type": "value_error.missing", 

67 }, 

68 ] 

69 } 

70 ) 

71 

72 

73@needs_py39 1eabcd

74def test_post_form_no_file(client: TestClient): 1eabcd

75 response = client.post("/files/", data={"token": "foo"}) 1abcd

76 assert response.status_code == 422, response.text 1abcd

77 assert response.json() == IsDict( 1abcd

78 { 

79 "detail": [ 

80 { 

81 "type": "missing", 

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

83 "msg": "Field required", 

84 "input": None, 

85 }, 

86 { 

87 "type": "missing", 

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

89 "msg": "Field required", 

90 "input": None, 

91 }, 

92 ] 

93 } 

94 ) | IsDict( 

95 # TODO: remove when deprecating Pydantic v1 

96 { 

97 "detail": [ 

98 { 

99 "loc": ["body", "file"], 

100 "msg": "field required", 

101 "type": "value_error.missing", 

102 }, 

103 { 

104 "loc": ["body", "fileb"], 

105 "msg": "field required", 

106 "type": "value_error.missing", 

107 }, 

108 ] 

109 } 

110 ) 

111 

112 

113@needs_py39 1eabcd

114def test_post_body_json(client: TestClient): 1eabcd

115 response = client.post("/files/", json={"file": "Foo", "token": "Bar"}) 1abcd

116 assert response.status_code == 422, response.text 1abcd

117 assert response.json() == IsDict( 1abcd

118 { 

119 "detail": [ 

120 { 

121 "type": "missing", 

122 "loc": ["body", "file"], 

123 "msg": "Field required", 

124 "input": None, 

125 }, 

126 { 

127 "type": "missing", 

128 "loc": ["body", "fileb"], 

129 "msg": "Field required", 

130 "input": None, 

131 }, 

132 { 

133 "type": "missing", 

134 "loc": ["body", "token"], 

135 "msg": "Field required", 

136 "input": None, 

137 }, 

138 ] 

139 } 

140 ) | IsDict( 

141 # TODO: remove when deprecating Pydantic v1 

142 { 

143 "detail": [ 

144 { 

145 "loc": ["body", "file"], 

146 "msg": "field required", 

147 "type": "value_error.missing", 

148 }, 

149 { 

150 "loc": ["body", "fileb"], 

151 "msg": "field required", 

152 "type": "value_error.missing", 

153 }, 

154 { 

155 "loc": ["body", "token"], 

156 "msg": "field required", 

157 "type": "value_error.missing", 

158 }, 

159 ] 

160 } 

161 ) 

162 

163 

164@needs_py39 1eabcd

165def test_post_file_no_token(tmp_path, app: FastAPI): 1eabcd

166 path = tmp_path / "test.txt" 1abcd

167 path.write_bytes(b"<file content>") 1abcd

168 

169 client = TestClient(app) 1abcd

170 with path.open("rb") as file: 1abcd

171 response = client.post("/files/", files={"file": file}) 1abcd

172 assert response.status_code == 422, response.text 1abcd

173 assert response.json() == IsDict( 1abcd

174 { 

175 "detail": [ 

176 { 

177 "type": "missing", 

178 "loc": ["body", "fileb"], 

179 "msg": "Field required", 

180 "input": None, 

181 }, 

182 { 

183 "type": "missing", 

184 "loc": ["body", "token"], 

185 "msg": "Field required", 

186 "input": None, 

187 }, 

188 ] 

189 } 

190 ) | IsDict( 

191 # TODO: remove when deprecating Pydantic v1 

192 { 

193 "detail": [ 

194 { 

195 "loc": ["body", "fileb"], 

196 "msg": "field required", 

197 "type": "value_error.missing", 

198 }, 

199 { 

200 "loc": ["body", "token"], 

201 "msg": "field required", 

202 "type": "value_error.missing", 

203 }, 

204 ] 

205 } 

206 ) 

207 

208 

209@needs_py39 1eabcd

210def test_post_files_and_token(tmp_path, app: FastAPI): 1eabcd

211 patha = tmp_path / "test.txt" 1abcd

212 pathb = tmp_path / "testb.txt" 1abcd

213 patha.write_text("<file content>") 1abcd

214 pathb.write_text("<file b content>") 1abcd

215 

216 client = TestClient(app) 1abcd

217 with patha.open("rb") as filea, pathb.open("rb") as fileb: 1abcd

218 response = client.post( 1abcd

219 "/files/", 

220 data={"token": "foo"}, 

221 files={"file": filea, "fileb": ("testb.txt", fileb, "text/plain")}, 

222 ) 

223 assert response.status_code == 200, response.text 1abcd

224 assert response.json() == { 1abcd

225 "file_size": 14, 

226 "token": "foo", 

227 "fileb_content_type": "text/plain", 

228 } 

229 

230 

231@needs_py39 1eabcd

232def test_openapi_schema(client: TestClient): 1eabcd

233 response = client.get("/openapi.json") 1abcd

234 assert response.status_code == 200, response.text 1abcd

235 assert response.json() == { 1abcd

236 "openapi": "3.1.0", 

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

238 "paths": { 

239 "/files/": { 

240 "post": { 

241 "responses": { 

242 "200": { 

243 "description": "Successful Response", 

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

245 }, 

246 "422": { 

247 "description": "Validation Error", 

248 "content": { 

249 "application/json": { 

250 "schema": { 

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

252 } 

253 } 

254 }, 

255 }, 

256 }, 

257 "summary": "Create File", 

258 "operationId": "create_file_files__post", 

259 "requestBody": { 

260 "content": { 

261 "multipart/form-data": { 

262 "schema": { 

263 "$ref": "#/components/schemas/Body_create_file_files__post" 

264 } 

265 } 

266 }, 

267 "required": True, 

268 }, 

269 } 

270 } 

271 }, 

272 "components": { 

273 "schemas": { 

274 "Body_create_file_files__post": { 

275 "title": "Body_create_file_files__post", 

276 "required": ["file", "fileb", "token"], 

277 "type": "object", 

278 "properties": { 

279 "file": {"title": "File", "type": "string", "format": "binary"}, 

280 "fileb": { 

281 "title": "Fileb", 

282 "type": "string", 

283 "format": "binary", 

284 }, 

285 "token": {"title": "Token", "type": "string"}, 

286 }, 

287 }, 

288 "ValidationError": { 

289 "title": "ValidationError", 

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

291 "type": "object", 

292 "properties": { 

293 "loc": { 

294 "title": "Location", 

295 "type": "array", 

296 "items": { 

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

298 }, 

299 }, 

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

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

302 }, 

303 }, 

304 "HTTPValidationError": { 

305 "title": "HTTPValidationError", 

306 "type": "object", 

307 "properties": { 

308 "detail": { 

309 "title": "Detail", 

310 "type": "array", 

311 "items": {"$ref": "#/components/schemas/ValidationError"}, 

312 } 

313 }, 

314 }, 

315 } 

316 }, 

317 }