Coverage for tests/test_tutorial/test_request_form_models/test_tutorial002_pv1.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 fastapi.testclient import TestClient 1abcdef

5 

6from ...utils import needs_py39, needs_pydanticv1 1abcdef

7 

8 

9@pytest.fixture( 1abcdef

10 name="client", 

11 params=[ 

12 "tutorial002_pv1", 

13 "tutorial002_pv1_an", 

14 pytest.param("tutorial002_pv1_an_py39", marks=needs_py39), 

15 ], 

16) 

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

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

19 

20 client = TestClient(mod.app) 1abcdef

21 return client 1abcdef

22 

23 

24# TODO: remove when deprecating Pydantic v1 

25@needs_pydanticv1 1abcdef

26def test_post_body_form(client: TestClient): 1abcdef

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

28 assert response.status_code == 200 1ghijkl

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

30 

31 

32# TODO: remove when deprecating Pydantic v1 

33@needs_pydanticv1 1abcdef

34def test_post_body_extra_form(client: TestClient): 1abcdef

35 response = client.post( 1mnopqr

36 "/login/", data={"username": "Foo", "password": "secret", "extra": "extra"} 

37 ) 

38 assert response.status_code == 422 1mnopqr

39 assert response.json() == { 1mnopqr

40 "detail": [ 

41 { 

42 "type": "value_error.extra", 

43 "loc": ["body", "extra"], 

44 "msg": "extra fields not permitted", 

45 } 

46 ] 

47 } 

48 

49 

50# TODO: remove when deprecating Pydantic v1 

51@needs_pydanticv1 1abcdef

52def test_post_body_form_no_password(client: TestClient): 1abcdef

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

54 assert response.status_code == 422 1stuvwx

55 assert response.json() == { 1stuvwx

56 "detail": [ 

57 { 

58 "type": "value_error.missing", 

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

60 "msg": "field required", 

61 } 

62 ] 

63 } 

64 

65 

66# TODO: remove when deprecating Pydantic v1 

67@needs_pydanticv1 1abcdef

68def test_post_body_form_no_username(client: TestClient): 1abcdef

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

70 assert response.status_code == 422 1yzABCD

71 assert response.json() == { 1yzABCD

72 "detail": [ 

73 { 

74 "type": "value_error.missing", 

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

76 "msg": "field required", 

77 } 

78 ] 

79 } 

80 

81 

82# TODO: remove when deprecating Pydantic v1 

83@needs_pydanticv1 1abcdef

84def test_post_body_form_no_data(client: TestClient): 1abcdef

85 response = client.post("/login/") 1EFGHIJ

86 assert response.status_code == 422 1EFGHIJ

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

88 "detail": [ 

89 { 

90 "type": "value_error.missing", 

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

92 "msg": "field required", 

93 }, 

94 { 

95 "type": "value_error.missing", 

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

97 "msg": "field required", 

98 }, 

99 ] 

100 } 

101 

102 

103# TODO: remove when deprecating Pydantic v1 

104@needs_pydanticv1 1abcdef

105def test_post_body_json(client: TestClient): 1abcdef

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

107 assert response.status_code == 422, response.text 1KLMNOP

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

109 "detail": [ 

110 { 

111 "type": "value_error.missing", 

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

113 "msg": "field required", 

114 }, 

115 { 

116 "type": "value_error.missing", 

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

118 "msg": "field required", 

119 }, 

120 ] 

121 } 

122 

123 

124# TODO: remove when deprecating Pydantic v1 

125@needs_pydanticv1 1abcdef

126def test_openapi_schema(client: TestClient): 1abcdef

127 response = client.get("/openapi.json") 1QRSTUV

128 assert response.status_code == 200, response.text 1QRSTUV

129 assert response.json() == { 1QRSTUV

130 "openapi": "3.1.0", 

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

132 "paths": { 

133 "/login/": { 

134 "post": { 

135 "responses": { 

136 "200": { 

137 "description": "Successful Response", 

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

139 }, 

140 "422": { 

141 "description": "Validation Error", 

142 "content": { 

143 "application/json": { 

144 "schema": { 

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

146 } 

147 } 

148 }, 

149 }, 

150 }, 

151 "summary": "Login", 

152 "operationId": "login_login__post", 

153 "requestBody": { 

154 "content": { 

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

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

157 } 

158 }, 

159 "required": True, 

160 }, 

161 } 

162 } 

163 }, 

164 "components": { 

165 "schemas": { 

166 "FormData": { 

167 "properties": { 

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

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

170 }, 

171 "additionalProperties": False, 

172 "type": "object", 

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

174 "title": "FormData", 

175 }, 

176 "ValidationError": { 

177 "title": "ValidationError", 

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

179 "type": "object", 

180 "properties": { 

181 "loc": { 

182 "title": "Location", 

183 "type": "array", 

184 "items": { 

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

186 }, 

187 }, 

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

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

190 }, 

191 }, 

192 "HTTPValidationError": { 

193 "title": "HTTPValidationError", 

194 "type": "object", 

195 "properties": { 

196 "detail": { 

197 "title": "Detail", 

198 "type": "array", 

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

200 } 

201 }, 

202 }, 

203 } 

204 }, 

205 }