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

50 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2025-01-13 13:38 +0000

1import pytest 1eabcd

2from fastapi.testclient import TestClient 1eabcd

3 

4from tests.utils import needs_py39, needs_pydanticv2 1eabcd

5 

6 

7@pytest.fixture(name="client") 1eabcd

8def get_client(): 1eabcd

9 from docs_src.request_form_models.tutorial002_an_py39 import app 1abcd

10 

11 client = TestClient(app) 1abcd

12 return client 1abcd

13 

14 

15@needs_pydanticv2 1eabcd

16@needs_py39 1eabcd

17def test_post_body_form(client: TestClient): 1eabcd

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

19 assert response.status_code == 200 1fghi

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

21 

22 

23@needs_pydanticv2 1eabcd

24@needs_py39 1eabcd

25def test_post_body_extra_form(client: TestClient): 1eabcd

26 response = client.post( 1jklm

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

28 ) 

29 assert response.status_code == 422 1jklm

30 assert response.json() == { 1jklm

31 "detail": [ 

32 { 

33 "type": "extra_forbidden", 

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

35 "msg": "Extra inputs are not permitted", 

36 "input": "extra", 

37 } 

38 ] 

39 } 

40 

41 

42@needs_pydanticv2 1eabcd

43@needs_py39 1eabcd

44def test_post_body_form_no_password(client: TestClient): 1eabcd

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

46 assert response.status_code == 422 1nopq

47 assert response.json() == { 1nopq

48 "detail": [ 

49 { 

50 "type": "missing", 

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

52 "msg": "Field required", 

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

54 } 

55 ] 

56 } 

57 

58 

59@needs_pydanticv2 1eabcd

60@needs_py39 1eabcd

61def test_post_body_form_no_username(client: TestClient): 1eabcd

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

63 assert response.status_code == 422 1rstu

64 assert response.json() == { 1rstu

65 "detail": [ 

66 { 

67 "type": "missing", 

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

69 "msg": "Field required", 

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

71 } 

72 ] 

73 } 

74 

75 

76@needs_pydanticv2 1eabcd

77@needs_py39 1eabcd

78def test_post_body_form_no_data(client: TestClient): 1eabcd

79 response = client.post("/login/") 1vwxy

80 assert response.status_code == 422 1vwxy

81 assert response.json() == { 1vwxy

82 "detail": [ 

83 { 

84 "type": "missing", 

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

86 "msg": "Field required", 

87 "input": {}, 

88 }, 

89 { 

90 "type": "missing", 

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

92 "msg": "Field required", 

93 "input": {}, 

94 }, 

95 ] 

96 } 

97 

98 

99@needs_pydanticv2 1eabcd

100@needs_py39 1eabcd

101def test_post_body_json(client: TestClient): 1eabcd

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

103 assert response.status_code == 422, response.text 1zABC

104 assert response.json() == { 1zABC

105 "detail": [ 

106 { 

107 "type": "missing", 

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

109 "msg": "Field required", 

110 "input": {}, 

111 }, 

112 { 

113 "type": "missing", 

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

115 "msg": "Field required", 

116 "input": {}, 

117 }, 

118 ] 

119 } 

120 

121 

122@needs_pydanticv2 1eabcd

123@needs_py39 1eabcd

124def test_openapi_schema(client: TestClient): 1eabcd

125 response = client.get("/openapi.json") 1DEFG

126 assert response.status_code == 200, response.text 1DEFG

127 assert response.json() == { 1DEFG

128 "openapi": "3.1.0", 

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

130 "paths": { 

131 "/login/": { 

132 "post": { 

133 "responses": { 

134 "200": { 

135 "description": "Successful Response", 

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

137 }, 

138 "422": { 

139 "description": "Validation Error", 

140 "content": { 

141 "application/json": { 

142 "schema": { 

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

144 } 

145 } 

146 }, 

147 }, 

148 }, 

149 "summary": "Login", 

150 "operationId": "login_login__post", 

151 "requestBody": { 

152 "content": { 

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

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

155 } 

156 }, 

157 "required": True, 

158 }, 

159 } 

160 } 

161 }, 

162 "components": { 

163 "schemas": { 

164 "FormData": { 

165 "properties": { 

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

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

168 }, 

169 "additionalProperties": False, 

170 "type": "object", 

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

172 "title": "FormData", 

173 }, 

174 "ValidationError": { 

175 "title": "ValidationError", 

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

177 "type": "object", 

178 "properties": { 

179 "loc": { 

180 "title": "Location", 

181 "type": "array", 

182 "items": { 

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

184 }, 

185 }, 

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

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

188 }, 

189 }, 

190 "HTTPValidationError": { 

191 "title": "HTTPValidationError", 

192 "type": "object", 

193 "properties": { 

194 "detail": { 

195 "title": "Detail", 

196 "type": "array", 

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

198 } 

199 }, 

200 }, 

201 } 

202 }, 

203 }