Coverage for tests / test_tutorial / test_body_multiple_params / test_tutorial003.py: 100%

26 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 ...utils import needs_py310 1abdc

8 

9 

10@pytest.fixture( 1abdc

11 name="client", 

12 params=[ 

13 pytest.param("tutorial003_py310", marks=needs_py310), 

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

15 ], 

16) 

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

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

19 

20 client = TestClient(mod.app) 1abc

21 return client 1abc

22 

23 

24def test_post_body_valid(client: TestClient): 1abdc

25 response = client.put( 1efg

26 "/items/5", 

27 json={ 

28 "importance": 2, 

29 "item": {"name": "Foo", "price": 50.5}, 

30 "user": {"username": "Dave"}, 

31 }, 

32 ) 

33 assert response.status_code == 200 1efg

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

35 "item_id": 5, 

36 "importance": 2, 

37 "item": { 

38 "name": "Foo", 

39 "price": 50.5, 

40 "description": None, 

41 "tax": None, 

42 }, 

43 "user": {"username": "Dave", "full_name": None}, 

44 } 

45 

46 

47def test_post_body_no_data(client: TestClient): 1abdc

48 response = client.put("/items/5", json=None) 1hij

49 assert response.status_code == 422 1hij

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

51 "detail": [ 

52 { 

53 "type": "missing", 

54 "loc": ["body", "item"], 

55 "msg": "Field required", 

56 "input": None, 

57 }, 

58 { 

59 "type": "missing", 

60 "loc": ["body", "user"], 

61 "msg": "Field required", 

62 "input": None, 

63 }, 

64 { 

65 "type": "missing", 

66 "loc": ["body", "importance"], 

67 "msg": "Field required", 

68 "input": None, 

69 }, 

70 ] 

71 } 

72 

73 

74def test_post_body_empty_list(client: TestClient): 1abdc

75 response = client.put("/items/5", json=[]) 1klm

76 assert response.status_code == 422 1klm

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

78 "detail": [ 

79 { 

80 "type": "missing", 

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

82 "msg": "Field required", 

83 "input": None, 

84 }, 

85 { 

86 "type": "missing", 

87 "loc": ["body", "user"], 

88 "msg": "Field required", 

89 "input": None, 

90 }, 

91 { 

92 "type": "missing", 

93 "loc": ["body", "importance"], 

94 "msg": "Field required", 

95 "input": None, 

96 }, 

97 ] 

98 } 

99 

100 

101def test_openapi_schema(client: TestClient): 1abdc

102 response = client.get("/openapi.json") 1nop

103 assert response.status_code == 200, response.text 1nop

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

105 { 

106 "openapi": "3.1.0", 

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

108 "paths": { 

109 "/items/{item_id}": { 

110 "put": { 

111 "responses": { 

112 "200": { 

113 "description": "Successful Response", 

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

115 }, 

116 "422": { 

117 "description": "Validation Error", 

118 "content": { 

119 "application/json": { 

120 "schema": { 

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

122 } 

123 } 

124 }, 

125 }, 

126 }, 

127 "summary": "Update Item", 

128 "operationId": "update_item_items__item_id__put", 

129 "parameters": [ 

130 { 

131 "required": True, 

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

133 "name": "item_id", 

134 "in": "path", 

135 } 

136 ], 

137 "requestBody": { 

138 "content": { 

139 "application/json": { 

140 "schema": { 

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

142 } 

143 } 

144 }, 

145 "required": True, 

146 }, 

147 } 

148 } 

149 }, 

150 "components": { 

151 "schemas": { 

152 "Item": { 

153 "title": "Item", 

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

155 "type": "object", 

156 "properties": { 

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

158 "description": { 

159 "title": "Description", 

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

161 }, 

162 "price": {"title": "Price", "type": "number"}, 

163 "tax": { 

164 "title": "Tax", 

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

166 }, 

167 }, 

168 }, 

169 "User": { 

170 "title": "User", 

171 "required": ["username"], 

172 "type": "object", 

173 "properties": { 

174 "username": {"title": "Username", "type": "string"}, 

175 "full_name": { 

176 "title": "Full Name", 

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

178 }, 

179 }, 

180 }, 

181 "Body_update_item_items__item_id__put": { 

182 "title": "Body_update_item_items__item_id__put", 

183 "required": ["item", "user", "importance"], 

184 "type": "object", 

185 "properties": { 

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

187 "user": {"$ref": "#/components/schemas/User"}, 

188 "importance": {"title": "Importance", "type": "integer"}, 

189 }, 

190 }, 

191 "ValidationError": { 

192 "title": "ValidationError", 

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

194 "type": "object", 

195 "properties": { 

196 "loc": { 

197 "title": "Location", 

198 "type": "array", 

199 "items": { 

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

201 }, 

202 }, 

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

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

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

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

207 }, 

208 }, 

209 "HTTPValidationError": { 

210 "title": "HTTPValidationError", 

211 "type": "object", 

212 "properties": { 

213 "detail": { 

214 "title": "Detail", 

215 "type": "array", 

216 "items": { 

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

218 }, 

219 } 

220 }, 

221 }, 

222 } 

223 }, 

224 } 

225 )