Coverage for tests/test_tutorial/test_header_param_models/test_tutorial001.py: 100%

31 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 needs_py39, needs_py310 1abcdef

9 

10 

11@pytest.fixture( 1abcdef

12 name="client", 

13 params=[ 

14 "tutorial001", 

15 pytest.param("tutorial001_py39", marks=needs_py39), 

16 pytest.param("tutorial001_py310", marks=needs_py310), 

17 "tutorial001_an", 

18 pytest.param("tutorial001_an_py39", marks=needs_py39), 

19 pytest.param("tutorial001_an_py310", marks=needs_py310), 

20 ], 

21) 

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

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

24 

25 client = TestClient(mod.app) 1abcdef

26 return client 1abcdef

27 

28 

29def test_header_param_model(client: TestClient): 1abcdef

30 response = client.get( 1ghijkl

31 "/items/", 

32 headers=[ 

33 ("save-data", "true"), 

34 ("if-modified-since", "yesterday"), 

35 ("traceparent", "123"), 

36 ("x-tag", "one"), 

37 ("x-tag", "two"), 

38 ], 

39 ) 

40 assert response.status_code == 200 1ghijkl

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

42 "host": "testserver", 

43 "save_data": True, 

44 "if_modified_since": "yesterday", 

45 "traceparent": "123", 

46 "x_tag": ["one", "two"], 

47 } 

48 

49 

50def test_header_param_model_defaults(client: TestClient): 1abcdef

51 response = client.get("/items/", headers=[("save-data", "true")]) 1mnopqr

52 assert response.status_code == 200 1mnopqr

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

54 "host": "testserver", 

55 "save_data": True, 

56 "if_modified_since": None, 

57 "traceparent": None, 

58 "x_tag": [], 

59 } 

60 

61 

62def test_header_param_model_invalid(client: TestClient): 1abcdef

63 response = client.get("/items/") 1stuvwx

64 assert response.status_code == 422 1stuvwx

65 assert response.json() == snapshot( 1stuvwx

66 { 

67 "detail": [ 

68 IsDict( 

69 { 

70 "type": "missing", 

71 "loc": ["header", "save_data"], 

72 "msg": "Field required", 

73 "input": { 

74 "x_tag": [], 

75 "host": "testserver", 

76 "accept": "*/*", 

77 "accept-encoding": "gzip, deflate", 

78 "connection": "keep-alive", 

79 "user-agent": "testclient", 

80 }, 

81 } 

82 ) 

83 | IsDict( 

84 # TODO: remove when deprecating Pydantic v1 

85 { 

86 "type": "value_error.missing", 

87 "loc": ["header", "save_data"], 

88 "msg": "field required", 

89 } 

90 ) 

91 ] 

92 } 

93 ) 

94 

95 

96def test_header_param_model_extra(client: TestClient): 1abcdef

97 response = client.get( 1yzABCD

98 "/items/", headers=[("save-data", "true"), ("tool", "plumbus")] 

99 ) 

100 assert response.status_code == 200, response.text 1yzABCD

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

102 { 

103 "host": "testserver", 

104 "save_data": True, 

105 "if_modified_since": None, 

106 "traceparent": None, 

107 "x_tag": [], 

108 } 

109 ) 

110 

111 

112def test_openapi_schema(client: TestClient): 1abcdef

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

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

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

116 { 

117 "openapi": "3.1.0", 

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

119 "paths": { 

120 "/items/": { 

121 "get": { 

122 "summary": "Read Items", 

123 "operationId": "read_items_items__get", 

124 "parameters": [ 

125 { 

126 "name": "host", 

127 "in": "header", 

128 "required": True, 

129 "schema": {"type": "string", "title": "Host"}, 

130 }, 

131 { 

132 "name": "save-data", 

133 "in": "header", 

134 "required": True, 

135 "schema": {"type": "boolean", "title": "Save Data"}, 

136 }, 

137 { 

138 "name": "if-modified-since", 

139 "in": "header", 

140 "required": False, 

141 "schema": IsDict( 

142 { 

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

144 "title": "If Modified Since", 

145 } 

146 ) 

147 | IsDict( 

148 # TODO: remove when deprecating Pydantic v1 

149 { 

150 "type": "string", 

151 "title": "If Modified Since", 

152 } 

153 ), 

154 }, 

155 { 

156 "name": "traceparent", 

157 "in": "header", 

158 "required": False, 

159 "schema": IsDict( 

160 { 

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

162 "title": "Traceparent", 

163 } 

164 ) 

165 | IsDict( 

166 # TODO: remove when deprecating Pydantic v1 

167 { 

168 "type": "string", 

169 "title": "Traceparent", 

170 } 

171 ), 

172 }, 

173 { 

174 "name": "x-tag", 

175 "in": "header", 

176 "required": False, 

177 "schema": { 

178 "type": "array", 

179 "items": {"type": "string"}, 

180 "default": [], 

181 "title": "X Tag", 

182 }, 

183 }, 

184 ], 

185 "responses": { 

186 "200": { 

187 "description": "Successful Response", 

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

189 }, 

190 "422": { 

191 "description": "Validation Error", 

192 "content": { 

193 "application/json": { 

194 "schema": { 

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

196 } 

197 } 

198 }, 

199 }, 

200 }, 

201 } 

202 } 

203 }, 

204 "components": { 

205 "schemas": { 

206 "HTTPValidationError": { 

207 "properties": { 

208 "detail": { 

209 "items": { 

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

211 }, 

212 "type": "array", 

213 "title": "Detail", 

214 } 

215 }, 

216 "type": "object", 

217 "title": "HTTPValidationError", 

218 }, 

219 "ValidationError": { 

220 "properties": { 

221 "loc": { 

222 "items": { 

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

224 }, 

225 "type": "array", 

226 "title": "Location", 

227 }, 

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

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

230 }, 

231 "type": "object", 

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

233 "title": "ValidationError", 

234 }, 

235 } 

236 }, 

237 } 

238 )