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

44 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2025-05-05 00:03 +0000

1import importlib 1abcdef

2 

3import pytest 1abcdef

4from dirty_equals import IsDict 1abcdef

5from fastapi.testclient import TestClient 1abcdef

6 

7from ...utils import needs_py39 1abcdef

8 

9 

10@pytest.fixture( 1abcdef

11 name="client", 

12 params=[ 

13 "tutorial001", 

14 "tutorial001_an", 

15 pytest.param("tutorial001_an_py39", marks=needs_py39), 

16 ], 

17) 

18def get_client(request: pytest.FixtureRequest): 1abcdef

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

20 

21 client = TestClient(mod.app) 1abcdef

22 return client 1abcdef

23 

24 

25def test_post_form_no_body(client: TestClient): 1abcdef

26 response = client.post("/files/") 1yzABCD

27 assert response.status_code == 422, response.text 1yzABCD

28 assert response.json() == IsDict( 1yzABCD

29 { 

30 "detail": [ 

31 { 

32 "type": "missing", 

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

34 "msg": "Field required", 

35 "input": None, 

36 } 

37 ] 

38 } 

39 ) | IsDict( 

40 # TODO: remove when deprecating Pydantic v1 

41 { 

42 "detail": [ 

43 { 

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

45 "msg": "field required", 

46 "type": "value_error.missing", 

47 } 

48 ] 

49 } 

50 ) 

51 

52 

53def test_post_body_json(client: TestClient): 1abcdef

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

55 assert response.status_code == 422, response.text 1EFGHIJ

56 assert response.json() == IsDict( 1EFGHIJ

57 { 

58 "detail": [ 

59 { 

60 "type": "missing", 

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

62 "msg": "Field required", 

63 "input": None, 

64 } 

65 ] 

66 } 

67 ) | IsDict( 

68 # TODO: remove when deprecating Pydantic v1 

69 { 

70 "detail": [ 

71 { 

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

73 "msg": "field required", 

74 "type": "value_error.missing", 

75 } 

76 ] 

77 } 

78 ) 

79 

80 

81def test_post_file(tmp_path, client: TestClient): 1abcdef

82 path = tmp_path / "test.txt" 1mnopqr

83 path.write_bytes(b"<file content>") 1mnopqr

84 

85 with path.open("rb") as file: 1mnopqr

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

87 assert response.status_code == 200, response.text 1mnopqr

88 assert response.json() == {"file_size": 14} 1mnopqr

89 

90 

91def test_post_large_file(tmp_path, client: TestClient): 1abcdef

92 default_pydantic_max_size = 2**16 1ghijkl

93 path = tmp_path / "test.txt" 1ghijkl

94 path.write_bytes(b"x" * (default_pydantic_max_size + 1)) 1ghijkl

95 

96 with path.open("rb") as file: 1ghijkl

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

98 assert response.status_code == 200, response.text 1ghijkl

99 assert response.json() == {"file_size": default_pydantic_max_size + 1} 1ghijkl

100 

101 

102def test_post_upload_file(tmp_path, client: TestClient): 1abcdef

103 path = tmp_path / "test.txt" 1stuvwx

104 path.write_bytes(b"<file content>") 1stuvwx

105 

106 with path.open("rb") as file: 1stuvwx

107 response = client.post("/uploadfile/", files={"file": file}) 1stuvwx

108 assert response.status_code == 200, response.text 1stuvwx

109 assert response.json() == {"filename": "test.txt"} 1stuvwx

110 

111 

112def test_openapi_schema(client: TestClient): 1abcdef

113 response = client.get("/openapi.json") 1KLMNOP

114 assert response.status_code == 200, response.text 1KLMNOP

115 assert response.json() == { 1KLMNOP

116 "openapi": "3.1.0", 

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

118 "paths": { 

119 "/files/": { 

120 "post": { 

121 "responses": { 

122 "200": { 

123 "description": "Successful Response", 

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

125 }, 

126 "422": { 

127 "description": "Validation Error", 

128 "content": { 

129 "application/json": { 

130 "schema": { 

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

132 } 

133 } 

134 }, 

135 }, 

136 }, 

137 "summary": "Create File", 

138 "operationId": "create_file_files__post", 

139 "requestBody": { 

140 "content": { 

141 "multipart/form-data": { 

142 "schema": { 

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

144 } 

145 } 

146 }, 

147 "required": True, 

148 }, 

149 } 

150 }, 

151 "/uploadfile/": { 

152 "post": { 

153 "responses": { 

154 "200": { 

155 "description": "Successful Response", 

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

157 }, 

158 "422": { 

159 "description": "Validation Error", 

160 "content": { 

161 "application/json": { 

162 "schema": { 

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

164 } 

165 } 

166 }, 

167 }, 

168 }, 

169 "summary": "Create Upload File", 

170 "operationId": "create_upload_file_uploadfile__post", 

171 "requestBody": { 

172 "content": { 

173 "multipart/form-data": { 

174 "schema": { 

175 "$ref": "#/components/schemas/Body_create_upload_file_uploadfile__post" 

176 } 

177 } 

178 }, 

179 "required": True, 

180 }, 

181 } 

182 }, 

183 }, 

184 "components": { 

185 "schemas": { 

186 "Body_create_upload_file_uploadfile__post": { 

187 "title": "Body_create_upload_file_uploadfile__post", 

188 "required": ["file"], 

189 "type": "object", 

190 "properties": { 

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

192 }, 

193 }, 

194 "Body_create_file_files__post": { 

195 "title": "Body_create_file_files__post", 

196 "required": ["file"], 

197 "type": "object", 

198 "properties": { 

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

200 }, 

201 }, 

202 "ValidationError": { 

203 "title": "ValidationError", 

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

205 "type": "object", 

206 "properties": { 

207 "loc": { 

208 "title": "Location", 

209 "type": "array", 

210 "items": { 

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

212 }, 

213 }, 

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

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

216 }, 

217 }, 

218 "HTTPValidationError": { 

219 "title": "HTTPValidationError", 

220 "type": "object", 

221 "properties": { 

222 "detail": { 

223 "title": "Detail", 

224 "type": "array", 

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

226 } 

227 }, 

228 }, 

229 } 

230 }, 

231 }