Coverage for tests/store/test_get_packages.py: 98%

50 statements  

« prev     ^ index     » next       coverage.py v7.16.1, created at 2026-09-18 22:11 +0000

1from unittest import TestCase 

2from unittest.mock import patch 

3from webapp.app import app 

4 

5 

6FIND_RESULTS = [ 

7 { 

8 "default-release": { 

9 "channel": { 

10 "base": { 

11 "architecture": "amd64", 

12 "channel": "22.04", 

13 "name": "ubuntu", 

14 }, 

15 "name": "3/stable", 

16 "released-at": "2025-05-28T00:34:33.427207+00:00", 

17 "risk": "stable", 

18 "track": "3", 

19 }, 

20 "revision": {"revision": 205}, 

21 }, 

22 "id": "3uPxmv77o1PrixpQFIf8o7SkOLsnMWmZ", 

23 "name": "kafka", 

24 "result": { 

25 "categories": [ 

26 { 

27 "featured": False, 

28 "name": "databases", 

29 }, 

30 ], 

31 "deployable-on": [], 

32 "media": [ 

33 { 

34 "height": None, 

35 "type": "icon", 

36 "url": ( 

37 "https://api.charmhub.io/api/v1/media/download/" 

38 "charm_3uPxmv77o1PrixpQFIf8o7SkOLsnMWmZ_icon_ad" 

39 "1a94cf9bb9f68614cb6c17e54e2fbd9dcc7fecc514dc60" 

40 "12b7f58fb5b87f8f.png" 

41 ), 

42 "width": None, 

43 }, 

44 ], 

45 "publisher": { 

46 "display-name": "Canonical", 

47 "id": "gVVkuxw4C56POG1eszt4RPR3L5Eak8XE", 

48 "username": "data-platform", 

49 "validation": "unproven", 

50 }, 

51 "summary": "Charmed Apache Kafka Operator", 

52 "title": "Apache Kafka", 

53 }, 

54 "type": "charm", 

55 }, 

56 { 

57 "default-release": { 

58 "channel": { 

59 "base": { 

60 "architecture": "amd64", 

61 "channel": "22.04", 

62 "name": "ubuntu", 

63 }, 

64 "name": "3/stable", 

65 "released-at": "2025-06-02T18:45:45.026540+00:00", 

66 "risk": "stable", 

67 "track": "3", 

68 }, 

69 "revision": {"revision": 82}, 

70 }, 

71 "id": "zGwm8mNdJ0Tb45JNDYNgiRBRlzaw66oA", 

72 "name": "kafka-k8s", 

73 "result": { 

74 "categories": [{"featured": False, "name": "databases"}], 

75 "deployable-on": ["kubernetes"], 

76 "media": [ 

77 { 

78 "height": None, 

79 "type": "icon", 

80 "url": ( 

81 "https://api.charmhub.io/api/v1/media/download/charm_" 

82 "zGwm8mNdJ0Tb45JNDYNgiRBRlzaw66oA_icon_ad1a94cf9bb9f6" 

83 "8614cb6c17e54e2fbd9dcc7fecc514dc6012b7f58fb5b87f8f" 

84 ".png" 

85 ), 

86 "width": None, 

87 }, 

88 ], 

89 "publisher": { 

90 "display-name": "Canonical", 

91 "id": "gVVkuxw4C56POG1eszt4RPR3L5Eak8XE", 

92 "username": "data-platform", 

93 "validation": "unproven", 

94 }, 

95 "summary": "Charmed Apache Kafka K8s Operator", 

96 "title": "Apache Kafka - K8s", 

97 }, 

98 "type": "charm", 

99 }, 

100 { 

101 "default-release": { 

102 "channel": { 

103 "base": { 

104 "architecture": "amd64", 

105 "channel": "22.04", 

106 "name": "ubuntu", 

107 }, 

108 "name": "6/stable", 

109 "released-at": "2025-08-20T21:22:15.968934+00:00", 

110 "risk": "stable", 

111 "track": "6", 

112 }, 

113 "revision": {"revision": 229}, 

114 }, 

115 "id": "Jfd56ZWJ9IaNHuPjXVLP9d9Xa2XMTSKp", 

116 "name": "mongodb", 

117 "result": { 

118 "categories": [{"featured": False, "name": "databases"}], 

119 "deployable-on": [], 

120 "media": [ 

121 { 

122 "height": None, 

123 "type": "icon", 

124 "url": ( 

125 "https://api.charmhub.io/api/v1/media/download/" 

126 "charm_Jfd56ZWJ9IaNHuPjXVLP9d9Xa2XMTSKp_icon_ad" 

127 "1a94cf9bb9f68614cb6c17e54e2fbd9dcc7fecc514dc60" 

128 "12b7f58fb5b87f8f.png" 

129 ), 

130 "width": None, 

131 }, 

132 ], 

133 "publisher": { 

134 "display-name": "Canonical", 

135 "id": "gVVkuxw4C56POG1eszt4RPR3L5Eak8XE", 

136 "username": "data-platform", 

137 "validation": "unproven", 

138 }, 

139 "summary": "A MongoDB operator charm", 

140 "title": "MongoDB", 

141 }, 

142 "type": "charm", 

143 }, 

144] 

145 

146 

147class TestGetPackages(TestCase): 

148 def setUp(self): 

149 app.testing = True 

150 self.client = app.test_client() 

151 

152 @patch("webapp.store_api.publisher_gateway.find") 

153 def test_get_packages(self, mock_find): 

154 mock_find.return_value = {"results": FIND_RESULTS} 

155 response = self.client.get("/packages.json") 

156 self.assertEqual(response.status_code, 200) 

157 self.assertIn("packages", response.json) 

158 self.assertEqual(len(response.json["packages"]), 3) 

159 

160 @patch("webapp.store_api.publisher_gateway.find") 

161 def test_get_packages_with_query(self, mock_find): 

162 mock_find.return_value = {"results": [FIND_RESULTS[0]]} 

163 response = self.client.get("/packages.json?q=kafka") 

164 self.assertEqual(response.status_code, 200) 

165 self.assertIn("q", response.json) 

166 self.assertEqual("kafka", response.json["q"]) 

167 self.assertIn("packages", response.json) 

168 self.assertEqual(len(response.json["packages"]), 1) 

169 

170 @patch("webapp.store_api.publisher_gateway.find") 

171 def test_get_packages_with_provides_and_requires(self, mock_find): 

172 mock_find.return_value = {"results": [FIND_RESULTS[0]]} 

173 response = self.client.get( 

174 "/packages.json?provides=kafka-client&requires=certificates" 

175 ) 

176 self.assertEqual(response.status_code, 200) 

177 self.assertIn("provides", response.json) 

178 self.assertEqual(["kafka-client"], response.json["provides"]) 

179 self.assertIn("requires", response.json) 

180 self.assertEqual(["certificates"], response.json["requires"]) 

181 self.assertIn("packages", response.json) 

182 self.assertEqual(len(response.json["packages"]), 1) 

183 

184 @patch("webapp.store_api.publisher_gateway.find") 

185 def test_get_packages_error_handling(self, mock_find): 

186 mock_find.side_effect = Exception("Mocked Error") 

187 with self.client as client: 

188 with self.assertRaises(Exception) as context: 

189 response = client.get("/packages.json") 

190 self.assertEqual(str(context.exception), "Mocked Error") 

191 

192 self.assertEqual(response.status_code, 500) 

193 

194 @patch("webapp.store_api.publisher_gateway.find") 

195 def test_get_packages_empty_response(self, mock_find): 

196 mock_find.return_value = {"results": []} 

197 with self.client as client: 

198 response = client.get( 

199 "/packages.json?q=some-random-non-existent-package-name" 

200 ) 

201 self.assertEqual(response.status_code, 200) 

202 self.assertEqual(0, len(response.json["packages"]))