Coverage for tests / test_tutorial / test_request_files / test_tutorial002.py: 100%

50 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 fastapi import FastAPI 1abdc

5from fastapi.testclient import TestClient 1abdc

6from inline_snapshot import snapshot 1abdc

7 

8 

9@pytest.fixture( 1abdc

10 name="app", 

11 params=[ 

12 "tutorial002_py310", 

13 "tutorial002_an_py310", 

14 ], 

15) 

16def get_app(request: pytest.FixtureRequest): 1abdc

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

18 

19 return mod.app 1abc

20 

21 

22@pytest.fixture(name="client") 1abdc

23def get_client(app: FastAPI): 1abdc

24 client = TestClient(app) 1abc

25 return client 1abc

26 

27 

28def test_post_form_no_body(client: TestClient): 1abdc

29 response = client.post("/files/") 1nop

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

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

32 "detail": [ 

33 { 

34 "type": "missing", 

35 "loc": ["body", "files"], 

36 "msg": "Field required", 

37 "input": None, 

38 } 

39 ] 

40 } 

41 

42 

43def test_post_body_json(client: TestClient): 1abdc

44 response = client.post("/files/", json={"file": "Foo"}) 1qrs

45 assert response.status_code == 422, response.text 1qrs

46 assert response.json() == { 1qrs

47 "detail": [ 

48 { 

49 "type": "missing", 

50 "loc": ["body", "files"], 

51 "msg": "Field required", 

52 "input": None, 

53 } 

54 ] 

55 } 

56 

57 

58def test_post_files(tmp_path, app: FastAPI): 1abdc

59 path = tmp_path / "test.txt" 1efg

60 path.write_bytes(b"<file content>") 1efg

61 path2 = tmp_path / "test2.txt" 1efg

62 path2.write_bytes(b"<file content2>") 1efg

63 

64 client = TestClient(app) 1efg

65 with path.open("rb") as file, path2.open("rb") as file2: 1efg

66 response = client.post( 1efg

67 "/files/", 

68 files=( 

69 ("files", ("test.txt", file)), 

70 ("files", ("test2.txt", file2)), 

71 ), 

72 ) 

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

74 assert response.json() == {"file_sizes": [14, 15]} 1efg

75 

76 

77def test_post_upload_file(tmp_path, app: FastAPI): 1abdc

78 path = tmp_path / "test.txt" 1hij

79 path.write_bytes(b"<file content>") 1hij

80 path2 = tmp_path / "test2.txt" 1hij

81 path2.write_bytes(b"<file content2>") 1hij

82 

83 client = TestClient(app) 1hij

84 with path.open("rb") as file, path2.open("rb") as file2: 1hij

85 response = client.post( 1hij

86 "/uploadfiles/", 

87 files=( 

88 ("files", ("test.txt", file)), 

89 ("files", ("test2.txt", file2)), 

90 ), 

91 ) 

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

93 assert response.json() == {"filenames": ["test.txt", "test2.txt"]} 1hij

94 

95 

96def test_get_root(app: FastAPI): 1abdc

97 client = TestClient(app) 1klm

98 response = client.get("/") 1klm

99 assert response.status_code == 200, response.text 1klm

100 assert b"<form" in response.content 1klm

101 

102 

103def test_openapi_schema(client: TestClient): 1abdc

104 response = client.get("/openapi.json") 1tuv

105 assert response.status_code == 200, response.text 1tuv

106 assert response.json() == snapshot( 1tuv

107 { 

108 "openapi": "3.1.0", 

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

110 "paths": { 

111 "/files/": { 

112 "post": { 

113 "responses": { 

114 "200": { 

115 "description": "Successful Response", 

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

117 }, 

118 "422": { 

119 "description": "Validation Error", 

120 "content": { 

121 "application/json": { 

122 "schema": { 

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

124 } 

125 } 

126 }, 

127 }, 

128 }, 

129 "summary": "Create Files", 

130 "operationId": "create_files_files__post", 

131 "requestBody": { 

132 "content": { 

133 "multipart/form-data": { 

134 "schema": { 

135 "$ref": "#/components/schemas/Body_create_files_files__post" 

136 } 

137 } 

138 }, 

139 "required": True, 

140 }, 

141 } 

142 }, 

143 "/uploadfiles/": { 

144 "post": { 

145 "responses": { 

146 "200": { 

147 "description": "Successful Response", 

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

149 }, 

150 "422": { 

151 "description": "Validation Error", 

152 "content": { 

153 "application/json": { 

154 "schema": { 

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

156 } 

157 } 

158 }, 

159 }, 

160 }, 

161 "summary": "Create Upload Files", 

162 "operationId": "create_upload_files_uploadfiles__post", 

163 "requestBody": { 

164 "content": { 

165 "multipart/form-data": { 

166 "schema": { 

167 "$ref": "#/components/schemas/Body_create_upload_files_uploadfiles__post" 

168 } 

169 } 

170 }, 

171 "required": True, 

172 }, 

173 } 

174 }, 

175 "/": { 

176 "get": { 

177 "responses": { 

178 "200": { 

179 "description": "Successful Response", 

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

181 } 

182 }, 

183 "summary": "Main", 

184 "operationId": "main__get", 

185 } 

186 }, 

187 }, 

188 "components": { 

189 "schemas": { 

190 "Body_create_upload_files_uploadfiles__post": { 

191 "title": "Body_create_upload_files_uploadfiles__post", 

192 "required": ["files"], 

193 "type": "object", 

194 "properties": { 

195 "files": { 

196 "title": "Files", 

197 "type": "array", 

198 "items": {"type": "string", "format": "binary"}, 

199 } 

200 }, 

201 }, 

202 "Body_create_files_files__post": { 

203 "title": "Body_create_files_files__post", 

204 "required": ["files"], 

205 "type": "object", 

206 "properties": { 

207 "files": { 

208 "title": "Files", 

209 "type": "array", 

210 "items": {"type": "string", "format": "binary"}, 

211 } 

212 }, 

213 }, 

214 "ValidationError": { 

215 "title": "ValidationError", 

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

217 "type": "object", 

218 "properties": { 

219 "loc": { 

220 "title": "Location", 

221 "type": "array", 

222 "items": { 

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

224 }, 

225 }, 

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

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

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

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

230 }, 

231 }, 

232 "HTTPValidationError": { 

233 "title": "HTTPValidationError", 

234 "type": "object", 

235 "properties": { 

236 "detail": { 

237 "title": "Detail", 

238 "type": "array", 

239 "items": { 

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

241 }, 

242 } 

243 }, 

244 }, 

245 } 

246 }, 

247 } 

248 )