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

34 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_form_models.{request.param}") 1abcdef

20 

21 client = TestClient(mod.app) 1abcdef

22 return client 1abcdef

23 

24 

25def test_post_body_form(client: TestClient): 1abcdef

26 response = client.post("/login/", data={"username": "Foo", "password": "secret"}) 1ghijkl

27 assert response.status_code == 200 1ghijkl

28 assert response.json() == {"username": "Foo", "password": "secret"} 1ghijkl

29 

30 

31def test_post_body_form_no_password(client: TestClient): 1abcdef

32 response = client.post("/login/", data={"username": "Foo"}) 1mnopqr

33 assert response.status_code == 422 1mnopqr

34 assert response.json() == IsDict( 1mnopqr

35 { 

36 "detail": [ 

37 { 

38 "type": "missing", 

39 "loc": ["body", "password"], 

40 "msg": "Field required", 

41 "input": {"username": "Foo"}, 

42 } 

43 ] 

44 } 

45 ) | IsDict( 

46 # TODO: remove when deprecating Pydantic v1 

47 { 

48 "detail": [ 

49 { 

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

51 "msg": "field required", 

52 "type": "value_error.missing", 

53 } 

54 ] 

55 } 

56 ) 

57 

58 

59def test_post_body_form_no_username(client: TestClient): 1abcdef

60 response = client.post("/login/", data={"password": "secret"}) 1stuvwx

61 assert response.status_code == 422 1stuvwx

62 assert response.json() == IsDict( 1stuvwx

63 { 

64 "detail": [ 

65 { 

66 "type": "missing", 

67 "loc": ["body", "username"], 

68 "msg": "Field required", 

69 "input": {"password": "secret"}, 

70 } 

71 ] 

72 } 

73 ) | IsDict( 

74 # TODO: remove when deprecating Pydantic v1 

75 { 

76 "detail": [ 

77 { 

78 "loc": ["body", "username"], 

79 "msg": "field required", 

80 "type": "value_error.missing", 

81 } 

82 ] 

83 } 

84 ) 

85 

86 

87def test_post_body_form_no_data(client: TestClient): 1abcdef

88 response = client.post("/login/") 1yzABCD

89 assert response.status_code == 422 1yzABCD

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

91 { 

92 "detail": [ 

93 { 

94 "type": "missing", 

95 "loc": ["body", "username"], 

96 "msg": "Field required", 

97 "input": {}, 

98 }, 

99 { 

100 "type": "missing", 

101 "loc": ["body", "password"], 

102 "msg": "Field required", 

103 "input": {}, 

104 }, 

105 ] 

106 } 

107 ) | IsDict( 

108 # TODO: remove when deprecating Pydantic v1 

109 { 

110 "detail": [ 

111 { 

112 "loc": ["body", "username"], 

113 "msg": "field required", 

114 "type": "value_error.missing", 

115 }, 

116 { 

117 "loc": ["body", "password"], 

118 "msg": "field required", 

119 "type": "value_error.missing", 

120 }, 

121 ] 

122 } 

123 ) 

124 

125 

126def test_post_body_json(client: TestClient): 1abcdef

127 response = client.post("/login/", json={"username": "Foo", "password": "secret"}) 1EFGHIJ

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

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

130 { 

131 "detail": [ 

132 { 

133 "type": "missing", 

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

135 "msg": "Field required", 

136 "input": {}, 

137 }, 

138 { 

139 "type": "missing", 

140 "loc": ["body", "password"], 

141 "msg": "Field required", 

142 "input": {}, 

143 }, 

144 ] 

145 } 

146 ) | IsDict( 

147 # TODO: remove when deprecating Pydantic v1 

148 { 

149 "detail": [ 

150 { 

151 "loc": ["body", "username"], 

152 "msg": "field required", 

153 "type": "value_error.missing", 

154 }, 

155 { 

156 "loc": ["body", "password"], 

157 "msg": "field required", 

158 "type": "value_error.missing", 

159 }, 

160 ] 

161 } 

162 ) 

163 

164 

165def test_openapi_schema(client: TestClient): 1abcdef

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

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

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

169 "openapi": "3.1.0", 

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

171 "paths": { 

172 "/login/": { 

173 "post": { 

174 "responses": { 

175 "200": { 

176 "description": "Successful Response", 

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

178 }, 

179 "422": { 

180 "description": "Validation Error", 

181 "content": { 

182 "application/json": { 

183 "schema": { 

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

185 } 

186 } 

187 }, 

188 }, 

189 }, 

190 "summary": "Login", 

191 "operationId": "login_login__post", 

192 "requestBody": { 

193 "content": { 

194 "application/x-www-form-urlencoded": { 

195 "schema": {"$ref": "#/components/schemas/FormData"} 

196 } 

197 }, 

198 "required": True, 

199 }, 

200 } 

201 } 

202 }, 

203 "components": { 

204 "schemas": { 

205 "FormData": { 

206 "properties": { 

207 "username": {"type": "string", "title": "Username"}, 

208 "password": {"type": "string", "title": "Password"}, 

209 }, 

210 "type": "object", 

211 "required": ["username", "password"], 

212 "title": "FormData", 

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 }, 

229 }, 

230 "HTTPValidationError": { 

231 "title": "HTTPValidationError", 

232 "type": "object", 

233 "properties": { 

234 "detail": { 

235 "title": "Detail", 

236 "type": "array", 

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

238 } 

239 }, 

240 }, 

241 } 

242 }, 

243 }