Coverage for tests/test_tutorial/test_request_forms/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_forms.{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"} 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": None, 

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": None, 

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": None, 

98 }, 

99 { 

100 "type": "missing", 

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

102 "msg": "Field required", 

103 "input": None, 

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": None, 

137 }, 

138 { 

139 "type": "missing", 

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

141 "msg": "Field required", 

142 "input": None, 

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": { 

196 "$ref": "#/components/schemas/Body_login_login__post" 

197 } 

198 } 

199 }, 

200 "required": True, 

201 }, 

202 } 

203 } 

204 }, 

205 "components": { 

206 "schemas": { 

207 "Body_login_login__post": { 

208 "title": "Body_login_login__post", 

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

210 "type": "object", 

211 "properties": { 

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

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

214 }, 

215 }, 

216 "ValidationError": { 

217 "title": "ValidationError", 

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

219 "type": "object", 

220 "properties": { 

221 "loc": { 

222 "title": "Location", 

223 "type": "array", 

224 "items": { 

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

226 }, 

227 }, 

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

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

230 }, 

231 }, 

232 "HTTPValidationError": { 

233 "title": "HTTPValidationError", 

234 "type": "object", 

235 "properties": { 

236 "detail": { 

237 "title": "Detail", 

238 "type": "array", 

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

240 } 

241 }, 

242 }, 

243 } 

244 }, 

245 }