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

37 statements  

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

1import importlib 1abcdef

2from pathlib import Path 1abcdef

3 

4import pytest 1abcdef

5from dirty_equals import IsDict 1abcdef

6from fastapi.testclient import TestClient 1abcdef

7 

8from ...utils import needs_py39, needs_py310 1abcdef

9 

10 

11@pytest.fixture( 1abcdef

12 name="client", 

13 params=[ 

14 "tutorial001_02", 

15 pytest.param("tutorial001_02_py310", marks=needs_py310), 

16 "tutorial001_02_an", 

17 pytest.param("tutorial001_02_an_py39", marks=needs_py39), 

18 pytest.param("tutorial001_02_an_py310", marks=needs_py310), 

19 ], 

20) 

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

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

23 

24 client = TestClient(mod.app) 1abcdef

25 return client 1abcdef

26 

27 

28def test_post_form_no_body(client: TestClient): 1abcdef

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

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

31 assert response.json() == {"message": "No file sent"} 1stuvwx

32 

33 

34def test_post_uploadfile_no_body(client: TestClient): 1abcdef

35 response = client.post("/uploadfile/") 1yzABCD

36 assert response.status_code == 200, response.text 1yzABCD

37 assert response.json() == {"message": "No upload file sent"} 1yzABCD

38 

39 

40def test_post_file(tmp_path: Path, client: TestClient): 1abcdef

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

42 path.write_bytes(b"<file content>") 1ghijkl

43 

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

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

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

47 assert response.json() == {"file_size": 14} 1ghijkl

48 

49 

50def test_post_upload_file(tmp_path: Path, client: TestClient): 1abcdef

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

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

53 

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

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

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

57 assert response.json() == {"filename": "test.txt"} 1mnopqr

58 

59 

60def test_openapi_schema(client: TestClient): 1abcdef

61 response = client.get("/openapi.json") 1EFGHIJ

62 assert response.status_code == 200, response.text 1EFGHIJ

63 assert response.json() == { 1EFGHIJ

64 "openapi": "3.1.0", 

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

66 "paths": { 

67 "/files/": { 

68 "post": { 

69 "summary": "Create File", 

70 "operationId": "create_file_files__post", 

71 "requestBody": { 

72 "content": { 

73 "multipart/form-data": { 

74 "schema": IsDict( 

75 { 

76 "allOf": [ 

77 { 

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

79 } 

80 ], 

81 "title": "Body", 

82 } 

83 ) 

84 | IsDict( 

85 # TODO: remove when deprecating Pydantic v1 

86 { 

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

88 } 

89 ) 

90 } 

91 } 

92 }, 

93 "responses": { 

94 "200": { 

95 "description": "Successful Response", 

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

97 }, 

98 "422": { 

99 "description": "Validation Error", 

100 "content": { 

101 "application/json": { 

102 "schema": { 

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

104 } 

105 } 

106 }, 

107 }, 

108 }, 

109 } 

110 }, 

111 "/uploadfile/": { 

112 "post": { 

113 "summary": "Create Upload File", 

114 "operationId": "create_upload_file_uploadfile__post", 

115 "requestBody": { 

116 "content": { 

117 "multipart/form-data": { 

118 "schema": IsDict( 

119 { 

120 "allOf": [ 

121 { 

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

123 } 

124 ], 

125 "title": "Body", 

126 } 

127 ) 

128 | IsDict( 

129 # TODO: remove when deprecating Pydantic v1 

130 { 

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

132 } 

133 ) 

134 } 

135 } 

136 }, 

137 "responses": { 

138 "200": { 

139 "description": "Successful Response", 

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

141 }, 

142 "422": { 

143 "description": "Validation Error", 

144 "content": { 

145 "application/json": { 

146 "schema": { 

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

148 } 

149 } 

150 }, 

151 }, 

152 }, 

153 } 

154 }, 

155 }, 

156 "components": { 

157 "schemas": { 

158 "Body_create_file_files__post": { 

159 "title": "Body_create_file_files__post", 

160 "type": "object", 

161 "properties": { 

162 "file": IsDict( 

163 { 

164 "title": "File", 

165 "anyOf": [ 

166 {"type": "string", "format": "binary"}, 

167 {"type": "null"}, 

168 ], 

169 } 

170 ) 

171 | IsDict( 

172 # TODO: remove when deprecating Pydantic v1 

173 {"title": "File", "type": "string", "format": "binary"} 

174 ) 

175 }, 

176 }, 

177 "Body_create_upload_file_uploadfile__post": { 

178 "title": "Body_create_upload_file_uploadfile__post", 

179 "type": "object", 

180 "properties": { 

181 "file": IsDict( 

182 { 

183 "title": "File", 

184 "anyOf": [ 

185 {"type": "string", "format": "binary"}, 

186 {"type": "null"}, 

187 ], 

188 } 

189 ) 

190 | IsDict( 

191 # TODO: remove when deprecating Pydantic v1 

192 {"title": "File", "type": "string", "format": "binary"} 

193 ) 

194 }, 

195 }, 

196 "HTTPValidationError": { 

197 "title": "HTTPValidationError", 

198 "type": "object", 

199 "properties": { 

200 "detail": { 

201 "title": "Detail", 

202 "type": "array", 

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

204 } 

205 }, 

206 }, 

207 "ValidationError": { 

208 "title": "ValidationError", 

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

210 "type": "object", 

211 "properties": { 

212 "loc": { 

213 "title": "Location", 

214 "type": "array", 

215 "items": { 

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

217 }, 

218 }, 

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

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

221 }, 

222 }, 

223 } 

224 }, 

225 }