Coverage for tests / test_tutorial / test_path_params_numeric_validations / test_tutorial006.py: 100%

33 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 pytest.param("tutorial006_py310"), 

12 pytest.param("tutorial006_an_py310"), 

13 ], 

14) 

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

16 mod = importlib.import_module( 1abc

17 f"docs_src.path_params_numeric_validations.{request.param}" 

18 ) 

19 return TestClient(mod.app) 1abc

20 

21 

22@pytest.mark.parametrize( 1abdc

23 "path,expected_response", 

24 [ 

25 ( 

26 "/items/0?q=&size=0.1", 

27 {"item_id": 0, "size": 0.1}, 

28 ), 

29 ( 

30 "/items/1000?q=somequery&size=10.4", 

31 {"item_id": 1000, "q": "somequery", "size": 10.4}, 

32 ), 

33 ], 

34) 

35def test_read_items(client: TestClient, path, expected_response): 1abdc

36 response = client.get(path) 1efg

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

38 assert response.json() == expected_response 1efg

39 

40 

41def test_read_items_item_id_less_than_zero(client: TestClient): 1abdc

42 response = client.get("/items/-1?q=somequery&size=5") 1hij

43 assert response.status_code == 422, response.text 1hij

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

45 "detail": [ 

46 { 

47 "loc": ["path", "item_id"], 

48 "input": "-1", 

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

50 "type": "greater_than_equal", 

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

52 } 

53 ] 

54 } 

55 

56 

57def test_read_items_item_id_greater_than_one_thousand(client: TestClient): 1abdc

58 response = client.get("/items/1001?q=somequery&size=5") 1klm

59 assert response.status_code == 422, response.text 1klm

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

61 "detail": [ 

62 { 

63 "loc": ["path", "item_id"], 

64 "input": "1001", 

65 "msg": "Input should be less than or equal to 1000", 

66 "type": "less_than_equal", 

67 "ctx": {"le": 1000}, 

68 } 

69 ] 

70 } 

71 

72 

73def test_read_items_size_too_small(client: TestClient): 1abdc

74 response = client.get("/items/1?q=somequery&size=0.0") 1nop

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

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

77 "detail": [ 

78 { 

79 "loc": ["query", "size"], 

80 "input": "0.0", 

81 "msg": "Input should be greater than 0", 

82 "type": "greater_than", 

83 "ctx": {"gt": 0.0}, 

84 } 

85 ] 

86 } 

87 

88 

89def test_read_items_size_too_large(client: TestClient): 1abdc

90 response = client.get("/items/1?q=somequery&size=10.5") 1qrs

91 assert response.status_code == 422, response.text 1qrs

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

93 "detail": [ 

94 { 

95 "loc": ["query", "size"], 

96 "input": "10.5", 

97 "msg": "Input should be less than 10.5", 

98 "type": "less_than", 

99 "ctx": {"lt": 10.5}, 

100 } 

101 ] 

102 } 

103 

104 

105def test_openapi_schema(client: TestClient): 1abdc

106 response = client.get("/openapi.json") 1tuv

107 assert response.status_code == 200, response.text 1tuv

108 assert response.json() == snapshot( 1tuv

109 { 

110 "openapi": "3.1.0", 

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

112 "paths": { 

113 "/items/{item_id}": { 

114 "get": { 

115 "summary": "Read Items", 

116 "operationId": "read_items_items__item_id__get", 

117 "parameters": [ 

118 { 

119 "required": True, 

120 "schema": { 

121 "title": "The ID of the item to get", 

122 "type": "integer", 

123 "minimum": 0, 

124 "maximum": 1000, 

125 }, 

126 "name": "item_id", 

127 "in": "path", 

128 }, 

129 { 

130 "required": True, 

131 "schema": { 

132 "type": "string", 

133 "title": "Q", 

134 }, 

135 "name": "q", 

136 "in": "query", 

137 }, 

138 { 

139 "in": "query", 

140 "name": "size", 

141 "required": True, 

142 "schema": { 

143 "exclusiveMaximum": 10.5, 

144 "exclusiveMinimum": 0, 

145 "title": "Size", 

146 "type": "number", 

147 }, 

148 }, 

149 ], 

150 "responses": { 

151 "200": { 

152 "description": "Successful Response", 

153 "content": { 

154 "application/json": { 

155 "schema": {}, 

156 } 

157 }, 

158 }, 

159 "422": { 

160 "content": { 

161 "application/json": { 

162 "schema": { 

163 "$ref": "#/components/schemas/HTTPValidationError", 

164 }, 

165 }, 

166 }, 

167 "description": "Validation Error", 

168 }, 

169 }, 

170 } 

171 } 

172 }, 

173 "components": { 

174 "schemas": { 

175 "HTTPValidationError": { 

176 "properties": { 

177 "detail": { 

178 "items": { 

179 "$ref": "#/components/schemas/ValidationError", 

180 }, 

181 "title": "Detail", 

182 "type": "array", 

183 }, 

184 }, 

185 "title": "HTTPValidationError", 

186 "type": "object", 

187 }, 

188 "ValidationError": { 

189 "properties": { 

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

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

192 "loc": { 

193 "items": { 

194 "anyOf": [ 

195 { 

196 "type": "string", 

197 }, 

198 { 

199 "type": "integer", 

200 }, 

201 ], 

202 }, 

203 "title": "Location", 

204 "type": "array", 

205 }, 

206 "msg": { 

207 "title": "Message", 

208 "type": "string", 

209 }, 

210 "type": { 

211 "title": "Error Type", 

212 "type": "string", 

213 }, 

214 }, 

215 "required": [ 

216 "loc", 

217 "msg", 

218 "type", 

219 ], 

220 "title": "ValidationError", 

221 "type": "object", 

222 }, 

223 }, 

224 }, 

225 } 

226 )