Coverage for tests / test_dependency_duplicates.py: 100%

43 statements  

« prev     ^ index     » next       coverage.py v7.13.3, created at 2026-02-12 18:15 +0000

1from fastapi import Depends, FastAPI 1abcd

2from fastapi.testclient import TestClient 1abcd

3from inline_snapshot import snapshot 1abcd

4from pydantic import BaseModel 1abcd

5 

6app = FastAPI() 1abcd

7 

8client = TestClient(app) 1abcd

9 

10 

11class Item(BaseModel): 1abcd

12 data: str 1abcd

13 

14 

15def duplicate_dependency(item: Item): 1abcd

16 return item 1heifjg

17 

18 

19def dependency(item2: Item): 1abcd

20 return item2 1klm

21 

22 

23def sub_duplicate_dependency( 1abcd

24 item: Item, sub_item: Item = Depends(duplicate_dependency) 

25): 

26 return [item, sub_item] 1efg

27 

28 

29@app.post("/with-duplicates") 1abcd

30async def with_duplicates(item: Item, item2: Item = Depends(duplicate_dependency)): 1abcd

31 return [item, item2] 1hij

32 

33 

34@app.post("/no-duplicates") 1abcd

35async def no_duplicates(item: Item, item2: Item = Depends(dependency)): 1abcd

36 return [item, item2] 1klm

37 

38 

39@app.post("/with-duplicates-sub") 1abcd

40async def no_duplicates_sub( 1abcd

41 item: Item, sub_items: list[Item] = Depends(sub_duplicate_dependency) 

42): 

43 return [item, sub_items] 1efg

44 

45 

46def test_no_duplicates_invalid(): 1abcd

47 response = client.post("/no-duplicates", json={"item": {"data": "myitem"}}) 1nop

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

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

50 "detail": [ 

51 { 

52 "type": "missing", 

53 "loc": ["body", "item2"], 

54 "msg": "Field required", 

55 "input": None, 

56 } 

57 ] 

58 } 

59 

60 

61def test_no_duplicates(): 1abcd

62 response = client.post( 1klm

63 "/no-duplicates", 

64 json={"item": {"data": "myitem"}, "item2": {"data": "myitem2"}}, 

65 ) 

66 assert response.status_code == 200, response.text 1klm

67 assert response.json() == [{"data": "myitem"}, {"data": "myitem2"}] 1klm

68 

69 

70def test_duplicates(): 1abcd

71 response = client.post("/with-duplicates", json={"data": "myitem"}) 1hij

72 assert response.status_code == 200, response.text 1hij

73 assert response.json() == [{"data": "myitem"}, {"data": "myitem"}] 1hij

74 

75 

76def test_sub_duplicates(): 1abcd

77 response = client.post("/with-duplicates-sub", json={"data": "myitem"}) 1efg

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

79 assert response.json() == [ 1efg

80 {"data": "myitem"}, 

81 [{"data": "myitem"}, {"data": "myitem"}], 

82 ] 

83 

84 

85def test_openapi_schema(): 1abcd

86 response = client.get("/openapi.json") 1qrs

87 assert response.status_code == 200, response.text 1qrs

88 assert response.json() == snapshot( 1qrs

89 { 

90 "openapi": "3.1.0", 

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

92 "paths": { 

93 "/with-duplicates": { 

94 "post": { 

95 "summary": "With Duplicates", 

96 "operationId": "with_duplicates_with_duplicates_post", 

97 "requestBody": { 

98 "content": { 

99 "application/json": { 

100 "schema": {"$ref": "#/components/schemas/Item"} 

101 } 

102 }, 

103 "required": True, 

104 }, 

105 "responses": { 

106 "200": { 

107 "description": "Successful Response", 

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

109 }, 

110 "422": { 

111 "description": "Validation Error", 

112 "content": { 

113 "application/json": { 

114 "schema": { 

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

116 } 

117 } 

118 }, 

119 }, 

120 }, 

121 } 

122 }, 

123 "/no-duplicates": { 

124 "post": { 

125 "summary": "No Duplicates", 

126 "operationId": "no_duplicates_no_duplicates_post", 

127 "requestBody": { 

128 "content": { 

129 "application/json": { 

130 "schema": { 

131 "$ref": "#/components/schemas/Body_no_duplicates_no_duplicates_post" 

132 } 

133 } 

134 }, 

135 "required": True, 

136 }, 

137 "responses": { 

138 "200": { 

139 "description": "Successful Response", 

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

141 }, 

142 "422": { 

143 "description": "Validation Error", 

144 "content": { 

145 "application/json": { 

146 "schema": { 

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

148 } 

149 } 

150 }, 

151 }, 

152 }, 

153 } 

154 }, 

155 "/with-duplicates-sub": { 

156 "post": { 

157 "summary": "No Duplicates Sub", 

158 "operationId": "no_duplicates_sub_with_duplicates_sub_post", 

159 "requestBody": { 

160 "content": { 

161 "application/json": { 

162 "schema": {"$ref": "#/components/schemas/Item"} 

163 } 

164 }, 

165 "required": True, 

166 }, 

167 "responses": { 

168 "200": { 

169 "description": "Successful Response", 

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

171 }, 

172 "422": { 

173 "description": "Validation Error", 

174 "content": { 

175 "application/json": { 

176 "schema": { 

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

178 } 

179 } 

180 }, 

181 }, 

182 }, 

183 } 

184 }, 

185 }, 

186 "components": { 

187 "schemas": { 

188 "Body_no_duplicates_no_duplicates_post": { 

189 "title": "Body_no_duplicates_no_duplicates_post", 

190 "required": ["item", "item2"], 

191 "type": "object", 

192 "properties": { 

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

194 "item2": {"$ref": "#/components/schemas/Item"}, 

195 }, 

196 }, 

197 "HTTPValidationError": { 

198 "title": "HTTPValidationError", 

199 "type": "object", 

200 "properties": { 

201 "detail": { 

202 "title": "Detail", 

203 "type": "array", 

204 "items": { 

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

206 }, 

207 } 

208 }, 

209 }, 

210 "Item": { 

211 "title": "Item", 

212 "required": ["data"], 

213 "type": "object", 

214 "properties": {"data": {"title": "Data", "type": "string"}}, 

215 }, 

216 "ValidationError": { 

217 "title": "ValidationError", 

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

219 "type": "object", 

220 "properties": { 

221 "loc": { 

222 "title": "Location", 

223 "type": "array", 

224 "items": { 

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

226 }, 

227 }, 

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

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

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

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

232 }, 

233 }, 

234 } 

235 }, 

236 } 

237 )