Coverage for tests/publisher/snaps/tests_get_metrics.py: 100%

160 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-04-28 22:05 +0000

1import random 

2from datetime import datetime 

3from flask_testing import TestCase 

4from webapp.app import create_app 

5from unittest.mock import patch 

6 

7import responses 

8from tests.publisher.endpoint_testing import BaseTestCases 

9 

10 

11class MetricsPageNotAuth(BaseTestCases.EndpointLoggedOut): 

12 def setUp(self): 

13 snap_name = "test-snap" 

14 endpoint_url = "/{}/metrics".format(snap_name) 

15 

16 super().setUp(snap_name=snap_name, endpoint_url=endpoint_url) 

17 

18 

19class GetActiveDeviceAnnotationGetInfo( 

20 BaseTestCases.EndpointLoggedInErrorHandling 

21): 

22 def setUp(self): 

23 snap_name = "test-snap" 

24 

25 api_url = "https://dashboard.snapcraft.io/dev/api/snaps/info/{}" 

26 api_url = api_url.format(snap_name) 

27 endpoint_url = "/{}/metrics/active-device-annotation".format(snap_name) 

28 super().setUp( 

29 snap_name=snap_name, 

30 endpoint_url=endpoint_url, 

31 method_endpoint="GET", 

32 api_url=api_url, 

33 method_api="GET", 

34 ) 

35 

36 

37class GetActiveDeviceMetrics(TestCase): 

38 render_templates = False 

39 

40 snap_name = "test-snap" 

41 endpoint_url = "/test-snap/metrics/active-devices" 

42 

43 def create_app(self): 

44 app = create_app(testing=True) 

45 app.secret_key = "secret_key" 

46 app.config["WTF_CSRF_METHODS"] = [] 

47 return app 

48 

49 @responses.activate 

50 @patch("webapp.publisher.snaps.views.authentication.is_authenticated") 

51 @patch("canonicalwebteam.store_api.dashboard.Dashboard.get_snap_info") 

52 @patch( 

53 "canonicalwebteam.store_api.dashboard.Dashboard.get_publisher_metrics" 

54 ) 

55 def test_get_active_devices_weekly_installed_by_version( 

56 self, 

57 mock_get_publisher_metrics, 

58 mock_get_item_details, 

59 mock_is_authenticated, 

60 ): 

61 mock_is_authenticated.return_value = True 

62 

63 mock_get_item_details.return_value = {"snap_id": "id"} 

64 random_values = random.sample(range(1, 30), 29) 

65 dates = [ 

66 datetime(2018, 3, day).strftime("%Y-%m-%d") for day in range(1, 30) 

67 ] 

68 

69 mock_get_publisher_metrics.return_value = { 

70 "metrics": [ 

71 { 

72 "buckets": dates, 

73 "metric_name": "weekly_installed_base_by_version", 

74 "series": [{"name": "1.0", "values": random_values}], 

75 "snap_id": "test-id", 

76 "status": "OK", 

77 } 

78 ] 

79 } 

80 

81 response = self.client.get(self.endpoint_url) 

82 self.assertEqual(response.status_code, 200) 

83 response_json = response.json 

84 

85 self.assertIn("active_devices", response_json) 

86 self.assertIn("latest_active_devices", response_json) 

87 self.assertEqual( 

88 response_json["latest_active_devices"], random_values[28] 

89 ) 

90 

91 active_devices = response_json["active_devices"] 

92 self.assertEqual( 

93 active_devices["name"], "weekly_installed_base_by_version" 

94 ) 

95 self.assertEqual(active_devices["series"][0]["name"], "1.0") 

96 self.assertEqual(active_devices["series"][0]["values"], random_values) 

97 

98 @responses.activate 

99 @patch("webapp.publisher.snaps.views.authentication.is_authenticated") 

100 @patch("canonicalwebteam.store_api.dashboard.Dashboard.get_snap_info") 

101 @patch( 

102 "canonicalwebteam.store_api.dashboard.Dashboard.get_publisher_metrics" 

103 ) 

104 def test_get_active_devices_weekly_installed_by_channel( 

105 self, 

106 mock_get_publisher_metrics, 

107 mock_get_item_details, 

108 mock_is_authenticated, 

109 ): 

110 mock_is_authenticated.return_value = True 

111 mock_get_item_details.return_value = {"snap_id": "id"} 

112 random_values = random.sample(range(1, 30), 29) 

113 dates = [ 

114 datetime(2018, 3, day).strftime("%Y-%m-%d") for day in range(1, 30) 

115 ] 

116 mock_get_publisher_metrics.return_value = { 

117 "metrics": [ 

118 { 

119 "buckets": dates, 

120 "metric_name": "weekly_installed_base_by_channel", 

121 "series": [{"name": "1.0", "values": random_values}], 

122 "snap_id": "test-id", 

123 "status": "OK", 

124 } 

125 ] 

126 } 

127 

128 response = self.client.get( 

129 self.endpoint_url + "?active-devices=channel" 

130 ) 

131 self.assertEqual(response.status_code, 200) 

132 response_json = response.json 

133 self.assertIn("active_devices", response_json) 

134 self.assertIn("latest_active_devices", response_json) 

135 self.assertEqual( 

136 response_json["latest_active_devices"], random_values[28] 

137 ) 

138 

139 active_devices = response_json["active_devices"] 

140 self.assertEqual( 

141 active_devices["name"], "weekly_installed_base_by_channel" 

142 ) 

143 self.assertEqual(active_devices["series"][0]["name"], "latest/1.0") 

144 self.assertEqual(active_devices["series"][0]["values"], random_values) 

145 

146 @responses.activate 

147 @patch("webapp.publisher.snaps.views.authentication.is_authenticated") 

148 @patch("canonicalwebteam.store_api.dashboard.Dashboard.get_snap_info") 

149 @patch( 

150 "canonicalwebteam.store_api.dashboard.Dashboard.get_publisher_metrics" 

151 ) 

152 def test_get_active_devices_weekly_installed_by_os( 

153 self, 

154 mock_get_publisher_metrics, 

155 mock_get_item_details, 

156 mock_is_authenticated, 

157 ): 

158 mock_is_authenticated.return_value = True 

159 mock_get_item_details.return_value = {"snap_id": "id"} 

160 random_values = random.sample(range(1, 30), 29) 

161 dates = [ 

162 datetime(2018, 3, day).strftime("%Y-%m-%d") for day in range(1, 30) 

163 ] 

164 mock_get_publisher_metrics.return_value = { 

165 "metrics": [ 

166 { 

167 "buckets": dates, 

168 "metric_name": "weekly_installed_base_by_operating_system", 

169 "series": [ 

170 {"values": random_values, "name": "ubuntu/0.1"} 

171 ], 

172 "snap_id": "test-id", 

173 "status": "OK", 

174 } 

175 ] 

176 } 

177 

178 response = self.client.get(self.endpoint_url + "?active-devices=os") 

179 self.assertEqual(response.status_code, 200) 

180 response_json = response.json 

181 self.assertIn("active_devices", response_json) 

182 self.assertIn("latest_active_devices", response_json) 

183 

184 active_devices = response_json["active_devices"] 

185 self.assertEqual( 

186 active_devices["name"], "weekly_installed_base_by_operating_system" 

187 ) 

188 self.assertEqual(active_devices["series"][0]["name"], "Ubuntu 0.1") 

189 self.assertEqual(active_devices["series"][0]["values"], random_values) 

190 

191 @responses.activate 

192 @patch("webapp.publisher.snaps.views.authentication.is_authenticated") 

193 @patch("canonicalwebteam.store_api.dashboard.Dashboard.get_snap_info") 

194 @patch( 

195 "canonicalwebteam.store_api.dashboard.Dashboard.get_publisher_metrics" 

196 ) 

197 def test_get_active_devices_in_3_months_period( 

198 self, 

199 mock_get_publisher_metrics, 

200 mock_get_item_details, 

201 mock_is_authenticated, 

202 ): 

203 mock_is_authenticated.return_value = True 

204 mock_get_item_details.return_value = {"snap_id": "id"} 

205 random_values = random.sample(range(1, 30), 29) 

206 dates = [ 

207 datetime(2018, 3, day).strftime("%Y-%m-%d") for day in range(1, 30) 

208 ] 

209 mock_get_publisher_metrics.return_value = { 

210 "metrics": [ 

211 { 

212 "buckets": dates, 

213 "metric_name": "weekly_installed_base_by_architecture", 

214 "series": [{"values": random_values, "name": "0.1"}], 

215 "snap_id": "test-id", 

216 "status": "OK", 

217 } 

218 ] 

219 } 

220 

221 response = self.client.get( 

222 self.endpoint_url + "?active-devices=architecture&period=3m" 

223 ) 

224 self.assertEqual(response.status_code, 200) 

225 response_json = response.json 

226 

227 self.assertIn("active_devices", response_json) 

228 self.assertIn("latest_active_devices", response_json) 

229 

230 active_devices = response_json["active_devices"] 

231 self.assertEqual( 

232 active_devices["name"], "weekly_installed_base_by_architecture" 

233 ) 

234 self.assertEqual(active_devices["series"][0]["name"], "0.1") 

235 self.assertEqual(active_devices["series"][0]["values"], random_values) 

236 

237 

238class GetMetricAnnotation(TestCase): 

239 render_templates = False 

240 

241 snap_name = "test-snap" 

242 snap_payload = { 

243 "snap_name": snap_name, 

244 "snap_id": "snap_id", 

245 "categories": { 

246 "locked": False, 

247 "items": [ 

248 { 

249 "featured": False, 

250 "name": "development", 

251 "since": "2019-02-08T17:02:33.318798", 

252 }, 

253 { 

254 "featured": True, 

255 "name": "featured", 

256 "since": "2024-07-01T19:45:19.386538", 

257 }, 

258 { 

259 "featured": True, 

260 "name": "server-and-cloud", 

261 "since": "2019-01-24T10:26:40.642290", 

262 }, 

263 ], 

264 }, 

265 } 

266 endpoint_url = "/test-snap/metrics/active-device-annotation" 

267 

268 def create_app(self): 

269 app = create_app(testing=True) 

270 app.secret_key = "secret_key" 

271 app.config["WTF_CSRF_METHODS"] = [] 

272 return app 

273 

274 @responses.activate 

275 @patch("webapp.publisher.snaps.views.authentication.is_authenticated") 

276 @patch("canonicalwebteam.store_api.dashboard.Dashboard.get_snap_info") 

277 def test_get_active_devices_weekly_installed_by_version( 

278 self, mock_get_snap_info, mock_is_authenticated 

279 ): 

280 mock_is_authenticated.return_value = True 

281 

282 mock_get_snap_info.return_value = self.snap_payload 

283 

284 response = self.client.get(self.endpoint_url) 

285 self.assertEqual(response.status_code, 200) 

286 response_json = response.json 

287 

288 self.assertEqual( 

289 response_json["buckets"], 

290 ["2019-02-08", "2024-07-01", "2019-01-24"], 

291 ) 

292 self.assertEqual(response_json["name"], "annotations") 

293 self.assertEqual( 

294 response_json["series"], 

295 [ 

296 { 

297 "date": "2019-01-24", 

298 "display_date": "January 2019", 

299 "display_name": "Server and cloud", 

300 "name": "server-and-cloud", 

301 "values": [0, 0, 1], 

302 }, 

303 { 

304 "date": "2019-02-08", 

305 "display_date": "February 2019", 

306 "display_name": "Development", 

307 "name": "development", 

308 "values": [1, 0, 0], 

309 }, 

310 { 

311 "date": "2024-07-01", 

312 "display_date": "July 2024", 

313 "display_name": "Featured", 

314 "name": "featured", 

315 "values": [0, 1, 0], 

316 }, 

317 ], 

318 ) 

319 

320 

321class GetCountryMetric(TestCase): 

322 render_templates = False 

323 

324 snap_name = "test-snap" 

325 endpoint_url = "/test-snap/metrics/country-metric" 

326 

327 def create_app(self): 

328 app = create_app(testing=True) 

329 app.secret_key = "secret_key" 

330 app.config["WTF_CSRF_METHODS"] = [] 

331 return app 

332 

333 @responses.activate 

334 @patch("webapp.publisher.snaps.views.authentication.is_authenticated") 

335 @patch("canonicalwebteam.store_api.dashboard.Dashboard.get_snap_info") 

336 @patch( 

337 "canonicalwebteam.store_api.dashboard.Dashboard.get_publisher_metrics" 

338 ) 

339 def test_get_active_devices_weekly_installed_by_version( 

340 self, 

341 mock_get_publisher_metrics, 

342 mock_get_item_details, 

343 mock_is_authenticated, 

344 ): 

345 mock_is_authenticated.return_value = True 

346 

347 countries = [ 

348 {"values": [2], "name": "FR"}, 

349 {"values": [3], "name": "GB"}, 

350 ] 

351 mock_get_item_details.return_value = {"snap_id": "id"} 

352 mock_get_publisher_metrics.return_value = { 

353 "metrics": [ 

354 { 

355 "buckets": ["2024-09-17"], 

356 "metric_name": "weekly_installed_base_by_country", 

357 "series": countries, 

358 "snap_id": "id", 

359 "status": "OK", 

360 } 

361 ] 

362 } 

363 

364 response = self.client.get(self.endpoint_url) 

365 self.assertEqual(response.status_code, 200) 

366 response_json = response.json 

367 active_devices = response_json["active_devices"] 

368 

369 for info in active_devices: 

370 country_info = active_devices[info] 

371 if country_info["code"] == "FR": 

372 self.assertEqual(country_info["number_of_users"], 2) 

373 self.assertEqual(country_info["color_rgb"], [66, 146, 198]) 

374 elif country_info["code"] == "GB": 

375 self.assertEqual(country_info["number_of_users"], 3) 

376 self.assertEqual(country_info["color_rgb"], [8, 48, 107]) 

377 else: 

378 self.assertEqual(country_info["number_of_users"], 0) 

379 self.assertEqual(country_info["color_rgb"], [218, 218, 218])