Coverage for tests / test_tutorial / test_path_params_numeric_validations / test_tutorial005.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("tutorial005_py310"), 

12 pytest.param("tutorial005_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 ("/items/1?q=", {"item_id": 1}), 

26 ("/items/1000?q=somequery", {"item_id": 1000, "q": "somequery"}), 

27 ], 

28) 

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

30 response = client.get(path) 1efg

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

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

33 

34 

35def test_read_items_non_int_item_id(client: TestClient): 1abdc

36 response = client.get("/items/invalid_id?q=somequery") 1hij

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

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

39 "detail": [ 

40 { 

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

42 "input": "invalid_id", 

43 "msg": "Input should be a valid integer, unable to parse string as an integer", 

44 "type": "int_parsing", 

45 } 

46 ] 

47 } 

48 

49 

50def test_read_items_item_id_less_than_one(client: TestClient): 1abdc

51 response = client.get("/items/0?q=somequery") 1klm

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

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

54 "detail": [ 

55 { 

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

57 "input": "0", 

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

59 "type": "greater_than", 

60 "ctx": {"gt": 0}, 

61 } 

62 ] 

63 } 

64 

65 

66def test_read_items_item_id_greater_than_one_thousand(client: TestClient): 1abdc

67 response = client.get("/items/1001?q=somequery") 1nop

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

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

70 "detail": [ 

71 { 

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

73 "input": "1001", 

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

75 "type": "less_than_equal", 

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

77 } 

78 ] 

79 } 

80 

81 

82def test_read_items_missing_q(client: TestClient): 1abdc

83 response = client.get("/items/42") 1qrs

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

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

86 "detail": [ 

87 { 

88 "loc": ["query", "q"], 

89 "input": None, 

90 "msg": "Field required", 

91 "type": "missing", 

92 } 

93 ] 

94 } 

95 

96 

97def test_openapi_schema(client: TestClient): 1abdc

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

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

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

101 { 

102 "openapi": "3.1.0", 

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

104 "paths": { 

105 "/items/{item_id}": { 

106 "get": { 

107 "summary": "Read Items", 

108 "operationId": "read_items_items__item_id__get", 

109 "parameters": [ 

110 { 

111 "required": True, 

112 "schema": { 

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

114 "type": "integer", 

115 "exclusiveMinimum": 0, 

116 "maximum": 1000, 

117 }, 

118 "name": "item_id", 

119 "in": "path", 

120 }, 

121 { 

122 "required": True, 

123 "schema": { 

124 "type": "string", 

125 "title": "Q", 

126 }, 

127 "name": "q", 

128 "in": "query", 

129 }, 

130 ], 

131 "responses": { 

132 "200": { 

133 "description": "Successful Response", 

134 "content": { 

135 "application/json": { 

136 "schema": {}, 

137 } 

138 }, 

139 }, 

140 "422": { 

141 "content": { 

142 "application/json": { 

143 "schema": { 

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

145 }, 

146 }, 

147 }, 

148 "description": "Validation Error", 

149 }, 

150 }, 

151 } 

152 } 

153 }, 

154 "components": { 

155 "schemas": { 

156 "HTTPValidationError": { 

157 "properties": { 

158 "detail": { 

159 "items": { 

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

161 }, 

162 "title": "Detail", 

163 "type": "array", 

164 }, 

165 }, 

166 "title": "HTTPValidationError", 

167 "type": "object", 

168 }, 

169 "ValidationError": { 

170 "properties": { 

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

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

173 "loc": { 

174 "items": { 

175 "anyOf": [ 

176 { 

177 "type": "string", 

178 }, 

179 { 

180 "type": "integer", 

181 }, 

182 ], 

183 }, 

184 "title": "Location", 

185 "type": "array", 

186 }, 

187 "msg": { 

188 "title": "Message", 

189 "type": "string", 

190 }, 

191 "type": { 

192 "title": "Error Type", 

193 "type": "string", 

194 }, 

195 }, 

196 "required": [ 

197 "loc", 

198 "msg", 

199 "type", 

200 ], 

201 "title": "ValidationError", 

202 "type": "object", 

203 }, 

204 }, 

205 }, 

206 } 

207 )