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

31 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 

7from tests.utils import needs_py310 1abdc

8 

9 

10@pytest.fixture( 1abdc

11 name="client", 

12 params=[ 

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

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

15 ], 

16) 

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

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

19 

20 client = TestClient(mod.app) 1abc

21 client.headers.clear() 1abc

22 return client 1abc

23 

24 

25def test_header_param_model(client: TestClient): 1abdc

26 response = client.get( 1efg

27 "/items/", 

28 headers=[ 

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

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

31 ("traceparent", "123"), 

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

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

34 ], 

35 ) 

36 assert response.status_code == 200, response.text 1efg

37 assert response.json() == { 1efg

38 "host": "testserver", 

39 "save_data": True, 

40 "if_modified_since": "yesterday", 

41 "traceparent": "123", 

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

43 } 

44 

45 

46def test_header_param_model_defaults(client: TestClient): 1abdc

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

48 assert response.status_code == 200 1hij

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

50 "host": "testserver", 

51 "save_data": True, 

52 "if_modified_since": None, 

53 "traceparent": None, 

54 "x_tag": [], 

55 } 

56 

57 

58def test_header_param_model_invalid(client: TestClient): 1abdc

59 response = client.get("/items/") 1klm

60 assert response.status_code == 422 1klm

61 assert response.json() == snapshot( 1klm

62 { 

63 "detail": [ 

64 { 

65 "type": "missing", 

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

67 "msg": "Field required", 

68 "input": {"x_tag": [], "host": "testserver"}, 

69 } 

70 ] 

71 } 

72 ) 

73 

74 

75def test_header_param_model_extra(client: TestClient): 1abdc

76 response = client.get( 1nop

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

78 ) 

79 assert response.status_code == 422, response.text 1nop

80 assert response.json() == snapshot( 1nop

81 { 

82 "detail": [ 

83 { 

84 "type": "extra_forbidden", 

85 "loc": ["header", "tool"], 

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

87 "input": "plumbus", 

88 } 

89 ] 

90 } 

91 ) 

92 

93 

94def test_openapi_schema(client: TestClient): 1abdc

95 response = client.get("/openapi.json") 1qrs

96 assert response.status_code == 200, response.text 1qrs

97 assert response.json() == snapshot( 1qrs

98 { 

99 "openapi": "3.1.0", 

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

101 "paths": { 

102 "/items/": { 

103 "get": { 

104 "summary": "Read Items", 

105 "operationId": "read_items_items__get", 

106 "parameters": [ 

107 { 

108 "name": "host", 

109 "in": "header", 

110 "required": True, 

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

112 }, 

113 { 

114 "name": "save-data", 

115 "in": "header", 

116 "required": True, 

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

118 }, 

119 { 

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

121 "in": "header", 

122 "required": False, 

123 "schema": { 

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

125 "title": "If Modified Since", 

126 }, 

127 }, 

128 { 

129 "name": "traceparent", 

130 "in": "header", 

131 "required": False, 

132 "schema": { 

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

134 "title": "Traceparent", 

135 }, 

136 }, 

137 { 

138 "name": "x-tag", 

139 "in": "header", 

140 "required": False, 

141 "schema": { 

142 "type": "array", 

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

144 "default": [], 

145 "title": "X Tag", 

146 }, 

147 }, 

148 ], 

149 "responses": { 

150 "200": { 

151 "description": "Successful Response", 

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

153 }, 

154 "422": { 

155 "description": "Validation Error", 

156 "content": { 

157 "application/json": { 

158 "schema": { 

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

160 } 

161 } 

162 }, 

163 }, 

164 }, 

165 } 

166 } 

167 }, 

168 "components": { 

169 "schemas": { 

170 "HTTPValidationError": { 

171 "properties": { 

172 "detail": { 

173 "items": { 

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

175 }, 

176 "type": "array", 

177 "title": "Detail", 

178 } 

179 }, 

180 "type": "object", 

181 "title": "HTTPValidationError", 

182 }, 

183 "ValidationError": { 

184 "properties": { 

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

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

187 "loc": { 

188 "items": { 

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

190 }, 

191 "type": "array", 

192 "title": "Location", 

193 }, 

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

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

196 }, 

197 "type": "object", 

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

199 "title": "ValidationError", 

200 }, 

201 } 

202 }, 

203 } 

204 )