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

31 statements  

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

1import importlib 1abcde

2 

3import pytest 1abcde

4from dirty_equals import IsDict 1abcde

5from fastapi.testclient import TestClient 1abcde

6from inline_snapshot import snapshot 1abcde

7 

8from tests.utils import needs_py39, needs_py310 1abcde

9 

10 

11@pytest.fixture( 1abcde

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): 1abcde

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

24 

25 client = TestClient(mod.app) 1abcde

26 return client 1abcde

27 

28 

29def test_query_param_model(client: TestClient): 1abcde

30 response = client.get( 1fghij

31 "/items/", 

32 params={ 

33 "limit": 10, 

34 "offset": 5, 

35 "order_by": "updated_at", 

36 "tags": ["tag1", "tag2"], 

37 }, 

38 ) 

39 assert response.status_code == 200 1fghij

40 assert response.json() == { 1fghij

41 "limit": 10, 

42 "offset": 5, 

43 "order_by": "updated_at", 

44 "tags": ["tag1", "tag2"], 

45 } 

46 

47 

48def test_query_param_model_defaults(client: TestClient): 1abcde

49 response = client.get("/items/") 1klmno

50 assert response.status_code == 200 1klmno

51 assert response.json() == { 1klmno

52 "limit": 100, 

53 "offset": 0, 

54 "order_by": "created_at", 

55 "tags": [], 

56 } 

57 

58 

59def test_query_param_model_invalid(client: TestClient): 1abcde

60 response = client.get( 1pqrst

61 "/items/", 

62 params={ 

63 "limit": 150, 

64 "offset": -1, 

65 "order_by": "invalid", 

66 }, 

67 ) 

68 assert response.status_code == 422 1pqrst

69 assert response.json() == snapshot( 1pqrst

70 IsDict( 

71 { 

72 "detail": [ 

73 { 

74 "type": "less_than_equal", 

75 "loc": ["query", "limit"], 

76 "msg": "Input should be less than or equal to 100", 

77 "input": "150", 

78 "ctx": {"le": 100}, 

79 }, 

80 { 

81 "type": "greater_than_equal", 

82 "loc": ["query", "offset"], 

83 "msg": "Input should be greater than or equal to 0", 

84 "input": "-1", 

85 "ctx": {"ge": 0}, 

86 }, 

87 { 

88 "type": "literal_error", 

89 "loc": ["query", "order_by"], 

90 "msg": "Input should be 'created_at' or 'updated_at'", 

91 "input": "invalid", 

92 "ctx": {"expected": "'created_at' or 'updated_at'"}, 

93 }, 

94 ] 

95 } 

96 ) 

97 | IsDict( 

98 # TODO: remove when deprecating Pydantic v1 

99 { 

100 "detail": [ 

101 { 

102 "type": "value_error.number.not_le", 

103 "loc": ["query", "limit"], 

104 "msg": "ensure this value is less than or equal to 100", 

105 "ctx": {"limit_value": 100}, 

106 }, 

107 { 

108 "type": "value_error.number.not_ge", 

109 "loc": ["query", "offset"], 

110 "msg": "ensure this value is greater than or equal to 0", 

111 "ctx": {"limit_value": 0}, 

112 }, 

113 { 

114 "type": "value_error.const", 

115 "loc": ["query", "order_by"], 

116 "msg": "unexpected value; permitted: 'created_at', 'updated_at'", 

117 "ctx": { 

118 "given": "invalid", 

119 "permitted": ["created_at", "updated_at"], 

120 }, 

121 }, 

122 ] 

123 } 

124 ) 

125 ) 

126 

127 

128def test_query_param_model_extra(client: TestClient): 1abcde

129 response = client.get( 1uvwxy

130 "/items/", 

131 params={ 

132 "limit": 10, 

133 "offset": 5, 

134 "order_by": "updated_at", 

135 "tags": ["tag1", "tag2"], 

136 "tool": "plumbus", 

137 }, 

138 ) 

139 assert response.status_code == 200 1uvwxy

140 assert response.json() == { 1uvwxy

141 "limit": 10, 

142 "offset": 5, 

143 "order_by": "updated_at", 

144 "tags": ["tag1", "tag2"], 

145 } 

146 

147 

148def test_openapi_schema(client: TestClient): 1abcde

149 response = client.get("/openapi.json") 1zABCD

150 assert response.status_code == 200, response.text 1zABCD

151 assert response.json() == snapshot( 1zABCD

152 { 

153 "openapi": "3.1.0", 

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

155 "paths": { 

156 "/items/": { 

157 "get": { 

158 "summary": "Read Items", 

159 "operationId": "read_items_items__get", 

160 "parameters": [ 

161 { 

162 "name": "limit", 

163 "in": "query", 

164 "required": False, 

165 "schema": { 

166 "type": "integer", 

167 "maximum": 100, 

168 "exclusiveMinimum": 0, 

169 "default": 100, 

170 "title": "Limit", 

171 }, 

172 }, 

173 { 

174 "name": "offset", 

175 "in": "query", 

176 "required": False, 

177 "schema": { 

178 "type": "integer", 

179 "minimum": 0, 

180 "default": 0, 

181 "title": "Offset", 

182 }, 

183 }, 

184 { 

185 "name": "order_by", 

186 "in": "query", 

187 "required": False, 

188 "schema": { 

189 "enum": ["created_at", "updated_at"], 

190 "type": "string", 

191 "default": "created_at", 

192 "title": "Order By", 

193 }, 

194 }, 

195 { 

196 "name": "tags", 

197 "in": "query", 

198 "required": False, 

199 "schema": { 

200 "type": "array", 

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

202 "default": [], 

203 "title": "Tags", 

204 }, 

205 }, 

206 ], 

207 "responses": { 

208 "200": { 

209 "description": "Successful Response", 

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

211 }, 

212 "422": { 

213 "description": "Validation Error", 

214 "content": { 

215 "application/json": { 

216 "schema": { 

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

218 } 

219 } 

220 }, 

221 }, 

222 }, 

223 } 

224 } 

225 }, 

226 "components": { 

227 "schemas": { 

228 "HTTPValidationError": { 

229 "properties": { 

230 "detail": { 

231 "items": { 

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

233 }, 

234 "type": "array", 

235 "title": "Detail", 

236 } 

237 }, 

238 "type": "object", 

239 "title": "HTTPValidationError", 

240 }, 

241 "ValidationError": { 

242 "properties": { 

243 "loc": { 

244 "items": { 

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

246 }, 

247 "type": "array", 

248 "title": "Location", 

249 }, 

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

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

252 }, 

253 "type": "object", 

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

255 "title": "ValidationError", 

256 }, 

257 } 

258 }, 

259 } 

260 )