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

26 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

6 

7from ...utils import needs_py39, needs_py310 1abcde

8 

9 

10@pytest.fixture( 1abcde

11 name="client", 

12 params=[ 

13 "tutorial001", 

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

15 "tutorial001_an", 

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

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

18 ], 

19) 

20def get_client(request: pytest.FixtureRequest): 1abcde

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

22 

23 client = TestClient(mod.app) 1abcde

24 return client 1abcde

25 

26 

27def test_items_5(client: TestClient): 1abcde

28 response = client.put("/items/5", json={"item": {"name": "Foo", "price": 3.0}}) 1fghij

29 assert response.status_code == 200 1fghij

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

31 "item_id": 5, 

32 "item": {"name": "Foo", "price": 3.0, "description": None, "tax": None}, 

33 } 

34 

35 

36def test_items_6(client: TestClient): 1abcde

37 response = client.put( 1klmno

38 "/items/6", 

39 json={ 

40 "item": { 

41 "name": "Bar", 

42 "price": 0.2, 

43 "description": "Some bar", 

44 "tax": "5.4", 

45 } 

46 }, 

47 ) 

48 assert response.status_code == 200 1klmno

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

50 "item_id": 6, 

51 "item": { 

52 "name": "Bar", 

53 "price": 0.2, 

54 "description": "Some bar", 

55 "tax": 5.4, 

56 }, 

57 } 

58 

59 

60def test_invalid_price(client: TestClient): 1abcde

61 response = client.put("/items/5", json={"item": {"name": "Foo", "price": -3.0}}) 1pqrst

62 assert response.status_code == 422 1pqrst

63 assert response.json() == IsDict( 1pqrst

64 { 

65 "detail": [ 

66 { 

67 "type": "greater_than", 

68 "loc": ["body", "item", "price"], 

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

70 "input": -3.0, 

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

72 } 

73 ] 

74 } 

75 ) | IsDict( 

76 # TODO: remove when deprecating Pydantic v1 

77 { 

78 "detail": [ 

79 { 

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

81 "loc": ["body", "item", "price"], 

82 "msg": "ensure this value is greater than 0", 

83 "type": "value_error.number.not_gt", 

84 } 

85 ] 

86 } 

87 ) 

88 

89 

90def test_openapi_schema(client: TestClient): 1abcde

91 response = client.get("/openapi.json") 1uvwxy

92 assert response.status_code == 200, response.text 1uvwxy

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

94 "openapi": "3.1.0", 

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

96 "paths": { 

97 "/items/{item_id}": { 

98 "put": { 

99 "responses": { 

100 "200": { 

101 "description": "Successful Response", 

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

103 }, 

104 "422": { 

105 "description": "Validation Error", 

106 "content": { 

107 "application/json": { 

108 "schema": { 

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

110 } 

111 } 

112 }, 

113 }, 

114 }, 

115 "summary": "Update Item", 

116 "operationId": "update_item_items__item_id__put", 

117 "parameters": [ 

118 { 

119 "required": True, 

120 "schema": {"title": "Item Id", "type": "integer"}, 

121 "name": "item_id", 

122 "in": "path", 

123 } 

124 ], 

125 "requestBody": { 

126 "content": { 

127 "application/json": { 

128 "schema": { 

129 "$ref": "#/components/schemas/Body_update_item_items__item_id__put" 

130 } 

131 } 

132 }, 

133 "required": True, 

134 }, 

135 } 

136 } 

137 }, 

138 "components": { 

139 "schemas": { 

140 "Item": { 

141 "title": "Item", 

142 "required": ["name", "price"], 

143 "type": "object", 

144 "properties": { 

145 "name": {"title": "Name", "type": "string"}, 

146 "description": IsDict( 

147 { 

148 "title": "The description of the item", 

149 "anyOf": [ 

150 {"maxLength": 300, "type": "string"}, 

151 {"type": "null"}, 

152 ], 

153 } 

154 ) 

155 | IsDict( 

156 # TODO: remove when deprecating Pydantic v1 

157 { 

158 "title": "The description of the item", 

159 "maxLength": 300, 

160 "type": "string", 

161 } 

162 ), 

163 "price": { 

164 "title": "Price", 

165 "exclusiveMinimum": 0.0, 

166 "type": "number", 

167 "description": "The price must be greater than zero", 

168 }, 

169 "tax": IsDict( 

170 { 

171 "title": "Tax", 

172 "anyOf": [{"type": "number"}, {"type": "null"}], 

173 } 

174 ) 

175 | IsDict( 

176 # TODO: remove when deprecating Pydantic v1 

177 {"title": "Tax", "type": "number"} 

178 ), 

179 }, 

180 }, 

181 "Body_update_item_items__item_id__put": { 

182 "title": "Body_update_item_items__item_id__put", 

183 "required": ["item"], 

184 "type": "object", 

185 "properties": {"item": {"$ref": "#/components/schemas/Item"}}, 

186 }, 

187 "ValidationError": { 

188 "title": "ValidationError", 

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

190 "type": "object", 

191 "properties": { 

192 "loc": { 

193 "title": "Location", 

194 "type": "array", 

195 "items": { 

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

197 }, 

198 }, 

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

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

201 }, 

202 }, 

203 "HTTPValidationError": { 

204 "title": "HTTPValidationError", 

205 "type": "object", 

206 "properties": { 

207 "detail": { 

208 "title": "Detail", 

209 "type": "array", 

210 "items": {"$ref": "#/components/schemas/ValidationError"}, 

211 } 

212 }, 

213 }, 

214 } 

215 }, 

216 }