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

37 statements  

« prev     ^ index     » next       coverage.py v7.13.3, created at 2026-02-12 18:15 +0000

1import importlib 1abdc

2 

3import pytest 1abdc

4from fastapi.testclient import TestClient 1abdc

5from inline_snapshot import snapshot 1abdc

6 

7 

8@pytest.fixture( 1abdc

9 name="client", 

10 params=[ 

11 "tutorial002_py310", 

12 "tutorial002_an_py310", 

13 ], 

14) 

15def get_client(request: pytest.FixtureRequest): 1abdc

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

17 

18 client = TestClient(mod.app) 1abc

19 return client 1abc

20 

21 

22def test_post_body_form(client: TestClient): 1abdc

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

24 assert response.status_code == 200 1efg

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

26 

27 

28def test_post_body_extra_form(client: TestClient): 1abdc

29 response = client.post( 1hij

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

31 ) 

32 assert response.status_code == 422 1hij

33 assert response.json() == { 1hij

34 "detail": [ 

35 { 

36 "type": "extra_forbidden", 

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

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

39 "input": "extra", 

40 } 

41 ] 

42 } 

43 

44 

45def test_post_body_form_no_password(client: TestClient): 1abdc

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

47 assert response.status_code == 422 1klm

48 assert response.json() == { 1klm

49 "detail": [ 

50 { 

51 "type": "missing", 

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

53 "msg": "Field required", 

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

55 } 

56 ] 

57 } 

58 

59 

60def test_post_body_form_no_username(client: TestClient): 1abdc

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

62 assert response.status_code == 422 1nop

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

64 "detail": [ 

65 { 

66 "type": "missing", 

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

68 "msg": "Field required", 

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

70 } 

71 ] 

72 } 

73 

74 

75def test_post_body_form_no_data(client: TestClient): 1abdc

76 response = client.post("/login/") 1qrs

77 assert response.status_code == 422 1qrs

78 assert response.json() == { 1qrs

79 "detail": [ 

80 { 

81 "type": "missing", 

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

83 "msg": "Field required", 

84 "input": {}, 

85 }, 

86 { 

87 "type": "missing", 

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

89 "msg": "Field required", 

90 "input": {}, 

91 }, 

92 ] 

93 } 

94 

95 

96def test_post_body_json(client: TestClient): 1abdc

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

98 assert response.status_code == 422, response.text 1tuv

99 assert response.json() == { 1tuv

100 "detail": [ 

101 { 

102 "type": "missing", 

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

104 "msg": "Field required", 

105 "input": {}, 

106 }, 

107 { 

108 "type": "missing", 

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

110 "msg": "Field required", 

111 "input": {}, 

112 }, 

113 ] 

114 } 

115 

116 

117def test_openapi_schema(client: TestClient): 1abdc

118 response = client.get("/openapi.json") 1wxy

119 assert response.status_code == 200, response.text 1wxy

120 assert response.json() == snapshot( 1wxy

121 { 

122 "openapi": "3.1.0", 

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

124 "paths": { 

125 "/login/": { 

126 "post": { 

127 "responses": { 

128 "200": { 

129 "description": "Successful Response", 

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

131 }, 

132 "422": { 

133 "description": "Validation Error", 

134 "content": { 

135 "application/json": { 

136 "schema": { 

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

138 } 

139 } 

140 }, 

141 }, 

142 }, 

143 "summary": "Login", 

144 "operationId": "login_login__post", 

145 "requestBody": { 

146 "content": { 

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

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

149 } 

150 }, 

151 "required": True, 

152 }, 

153 } 

154 } 

155 }, 

156 "components": { 

157 "schemas": { 

158 "FormData": { 

159 "properties": { 

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

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

162 }, 

163 "additionalProperties": False, 

164 "type": "object", 

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

166 "title": "FormData", 

167 }, 

168 "ValidationError": { 

169 "title": "ValidationError", 

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

171 "type": "object", 

172 "properties": { 

173 "loc": { 

174 "title": "Location", 

175 "type": "array", 

176 "items": { 

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

178 }, 

179 }, 

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

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

182 "input": {"title": "Input"}, 

183 "ctx": {"title": "Context", "type": "object"}, 

184 }, 

185 }, 

186 "HTTPValidationError": { 

187 "title": "HTTPValidationError", 

188 "type": "object", 

189 "properties": { 

190 "detail": { 

191 "title": "Detail", 

192 "type": "array", 

193 "items": { 

194 "$ref": "#/components/schemas/ValidationError" 

195 }, 

196 } 

197 }, 

198 }, 

199 } 

200 }, 

201 } 

202 )