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

40 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

6from inline_snapshot import snapshot 1abcdef

7 

8from tests.utils import ( 1abcdef

9 needs_py39, 

10 needs_py310, 

11 needs_pydanticv1, 

12 needs_pydanticv2, 

13 pydantic_snapshot, 

14) 

15 

16 

17@pytest.fixture( 1abcdef

18 name="client", 

19 params=[ 

20 pytest.param("tutorial002", marks=needs_pydanticv2), 

21 pytest.param("tutorial002_py310", marks=[needs_py310, needs_pydanticv2]), 

22 pytest.param("tutorial002_an", marks=needs_pydanticv2), 

23 pytest.param("tutorial002_an_py39", marks=[needs_py39, needs_pydanticv2]), 

24 pytest.param("tutorial002_an_py310", marks=[needs_py310, needs_pydanticv2]), 

25 pytest.param("tutorial002_pv1", marks=[needs_pydanticv1, needs_pydanticv1]), 

26 pytest.param("tutorial002_pv1_py310", marks=[needs_py310, needs_pydanticv1]), 

27 pytest.param("tutorial002_pv1_an", marks=[needs_pydanticv1]), 

28 pytest.param("tutorial002_pv1_an_py39", marks=[needs_py39, needs_pydanticv1]), 

29 pytest.param("tutorial002_pv1_an_py310", marks=[needs_py310, needs_pydanticv1]), 

30 ], 

31) 

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

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

34 

35 client = TestClient(mod.app) 1abcdef

36 return client 1abcdef

37 

38 

39def test_cookie_param_model(client: TestClient): 1abcdef

40 with client as c: 1ghijkl

41 c.cookies.set("session_id", "123") 1ghijkl

42 c.cookies.set("fatebook_tracker", "456") 1ghijkl

43 c.cookies.set("googall_tracker", "789") 1ghijkl

44 response = c.get("/items/") 1ghijkl

45 assert response.status_code == 200 1ghijkl

46 assert response.json() == { 1ghijkl

47 "session_id": "123", 

48 "fatebook_tracker": "456", 

49 "googall_tracker": "789", 

50 } 

51 

52 

53def test_cookie_param_model_defaults(client: TestClient): 1abcdef

54 with client as c: 1stuvwx

55 c.cookies.set("session_id", "123") 1stuvwx

56 response = c.get("/items/") 1stuvwx

57 assert response.status_code == 200 1stuvwx

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

59 "session_id": "123", 

60 "fatebook_tracker": None, 

61 "googall_tracker": None, 

62 } 

63 

64 

65def test_cookie_param_model_invalid(client: TestClient): 1abcdef

66 response = client.get("/items/") 1yzABCD

67 assert response.status_code == 422 1yzABCD

68 assert response.json() == pydantic_snapshot( 1yzABCD

69 v2=snapshot( 

70 { 

71 "detail": [ 

72 { 

73 "type": "missing", 

74 "loc": ["cookie", "session_id"], 

75 "msg": "Field required", 

76 "input": {}, 

77 } 

78 ] 

79 } 

80 ), 

81 v1=snapshot( 

82 { 

83 "detail": [ 

84 { 

85 "type": "value_error.missing", 

86 "loc": ["cookie", "session_id"], 

87 "msg": "field required", 

88 } 

89 ] 

90 } 

91 ), 

92 ) 

93 

94 

95def test_cookie_param_model_extra(client: TestClient): 1abcdef

96 with client as c: 1mnopqr

97 c.cookies.set("session_id", "123") 1mnopqr

98 c.cookies.set("extra", "track-me-here-too") 1mnopqr

99 response = c.get("/items/") 1mnopqr

100 assert response.status_code == 422 1mnopqr

101 assert response.json() == snapshot( 1mnopqr

102 IsDict( 

103 { 

104 "detail": [ 

105 { 

106 "type": "extra_forbidden", 

107 "loc": ["cookie", "extra"], 

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

109 "input": "track-me-here-too", 

110 } 

111 ] 

112 } 

113 ) 

114 | IsDict( 

115 # TODO: remove when deprecating Pydantic v1 

116 { 

117 "detail": [ 

118 { 

119 "type": "value_error.extra", 

120 "loc": ["cookie", "extra"], 

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

122 } 

123 ] 

124 } 

125 ) 

126 ) 

127 

128 

129def test_openapi_schema(client: TestClient): 1abcdef

130 response = client.get("/openapi.json") 1EFGHIJ

131 assert response.status_code == 200, response.text 1EFGHIJ

132 assert response.json() == snapshot( 1EFGHIJ

133 { 

134 "openapi": "3.1.0", 

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

136 "paths": { 

137 "/items/": { 

138 "get": { 

139 "summary": "Read Items", 

140 "operationId": "read_items_items__get", 

141 "parameters": [ 

142 { 

143 "name": "session_id", 

144 "in": "cookie", 

145 "required": True, 

146 "schema": {"type": "string", "title": "Session Id"}, 

147 }, 

148 { 

149 "name": "fatebook_tracker", 

150 "in": "cookie", 

151 "required": False, 

152 "schema": pydantic_snapshot( 

153 v2=snapshot( 

154 { 

155 "anyOf": [ 

156 {"type": "string"}, 

157 {"type": "null"}, 

158 ], 

159 "title": "Fatebook Tracker", 

160 } 

161 ), 

162 v1=snapshot( 

163 # TODO: remove when deprecating Pydantic v1 

164 { 

165 "type": "string", 

166 "title": "Fatebook Tracker", 

167 } 

168 ), 

169 ), 

170 }, 

171 { 

172 "name": "googall_tracker", 

173 "in": "cookie", 

174 "required": False, 

175 "schema": IsDict( 

176 { 

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

178 "title": "Googall Tracker", 

179 } 

180 ) 

181 | IsDict( 

182 # TODO: remove when deprecating Pydantic v1 

183 { 

184 "type": "string", 

185 "title": "Googall Tracker", 

186 } 

187 ), 

188 }, 

189 ], 

190 "responses": { 

191 "200": { 

192 "description": "Successful Response", 

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

194 }, 

195 "422": { 

196 "description": "Validation Error", 

197 "content": { 

198 "application/json": { 

199 "schema": { 

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

201 } 

202 } 

203 }, 

204 }, 

205 }, 

206 } 

207 } 

208 }, 

209 "components": { 

210 "schemas": { 

211 "HTTPValidationError": { 

212 "properties": { 

213 "detail": { 

214 "items": { 

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

216 }, 

217 "type": "array", 

218 "title": "Detail", 

219 } 

220 }, 

221 "type": "object", 

222 "title": "HTTPValidationError", 

223 }, 

224 "ValidationError": { 

225 "properties": { 

226 "loc": { 

227 "items": { 

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

229 }, 

230 "type": "array", 

231 "title": "Location", 

232 }, 

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

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

235 }, 

236 "type": "object", 

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

238 "title": "ValidationError", 

239 }, 

240 } 

241 }, 

242 } 

243 )