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

172 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-01-05 22:07 +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 with self.client.session_transaction() as sess: 

64 sess["publisher"] = { 

65 "nickname": "test_username", 

66 "fullname": "Test User", 

67 "email": "test@example.com", 

68 } 

69 

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

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

72 dates = [ 

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

74 ] 

75 

76 mock_get_publisher_metrics.return_value = { 

77 "metrics": [ 

78 { 

79 "buckets": dates, 

80 "metric_name": "weekly_installed_base_by_version", 

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

82 "snap_id": "test-id", 

83 "status": "OK", 

84 } 

85 ] 

86 } 

87 

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

89 self.assertEqual(response.status_code, 200) 

90 response_json = response.json 

91 

92 self.assertIn("active_devices", response_json) 

93 self.assertIn("latest_active_devices", response_json) 

94 self.assertEqual( 

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

96 ) 

97 

98 active_devices = response_json["active_devices"] 

99 self.assertEqual( 

100 active_devices["name"], "weekly_installed_base_by_version" 

101 ) 

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

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

104 

105 @responses.activate 

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

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

108 @patch( 

109 "canonicalwebteam.store_api.dashboard.Dashboard.get_publisher_metrics" 

110 ) 

111 def test_get_active_devices_weekly_installed_by_channel( 

112 self, 

113 mock_get_publisher_metrics, 

114 mock_get_item_details, 

115 mock_is_authenticated, 

116 ): 

117 mock_is_authenticated.return_value = True 

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

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

120 dates = [ 

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

122 ] 

123 mock_get_publisher_metrics.return_value = { 

124 "metrics": [ 

125 { 

126 "buckets": dates, 

127 "metric_name": "weekly_installed_base_by_channel", 

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

129 "snap_id": "test-id", 

130 "status": "OK", 

131 } 

132 ] 

133 } 

134 

135 with self.client.session_transaction() as sess: 

136 sess["publisher"] = { 

137 "nickname": "test_username", 

138 "fullname": "Test User", 

139 "email": "test@example.com", 

140 } 

141 

142 response = self.client.get( 

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

144 ) 

145 self.assertEqual(response.status_code, 200) 

146 response_json = response.json 

147 self.assertIn("active_devices", response_json) 

148 self.assertIn("latest_active_devices", response_json) 

149 self.assertEqual( 

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

151 ) 

152 

153 active_devices = response_json["active_devices"] 

154 self.assertEqual( 

155 active_devices["name"], "weekly_installed_base_by_channel" 

156 ) 

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

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

159 

160 @responses.activate 

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

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

163 @patch( 

164 "canonicalwebteam.store_api.dashboard.Dashboard.get_publisher_metrics" 

165 ) 

166 def test_get_active_devices_weekly_installed_by_os( 

167 self, 

168 mock_get_publisher_metrics, 

169 mock_get_item_details, 

170 mock_is_authenticated, 

171 ): 

172 mock_is_authenticated.return_value = True 

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

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

175 dates = [ 

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

177 ] 

178 mock_get_publisher_metrics.return_value = { 

179 "metrics": [ 

180 { 

181 "buckets": dates, 

182 "metric_name": "weekly_installed_base_by_operating_system", 

183 "series": [ 

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

185 ], 

186 "snap_id": "test-id", 

187 "status": "OK", 

188 } 

189 ] 

190 } 

191 

192 with self.client.session_transaction() as sess: 

193 sess["publisher"] = { 

194 "nickname": "test_username", 

195 "fullname": "Test User", 

196 "email": "test@example.com", 

197 } 

198 

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

200 self.assertEqual(response.status_code, 200) 

201 response_json = response.json 

202 self.assertIn("active_devices", response_json) 

203 self.assertIn("latest_active_devices", response_json) 

204 

205 active_devices = response_json["active_devices"] 

206 self.assertEqual( 

207 active_devices["name"], "weekly_installed_base_by_operating_system" 

208 ) 

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

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

211 

212 @responses.activate 

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

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

215 @patch( 

216 "canonicalwebteam.store_api.dashboard.Dashboard.get_publisher_metrics" 

217 ) 

218 def test_get_active_devices_in_3_months_period( 

219 self, 

220 mock_get_publisher_metrics, 

221 mock_get_item_details, 

222 mock_is_authenticated, 

223 ): 

224 mock_is_authenticated.return_value = True 

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

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

227 dates = [ 

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

229 ] 

230 mock_get_publisher_metrics.return_value = { 

231 "metrics": [ 

232 { 

233 "buckets": dates, 

234 "metric_name": "weekly_installed_base_by_architecture", 

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

236 "snap_id": "test-id", 

237 "status": "OK", 

238 } 

239 ] 

240 } 

241 

242 with self.client.session_transaction() as sess: 

243 sess["publisher"] = { 

244 "nickname": "test_username", 

245 "fullname": "Test User", 

246 "email": "test@example.com", 

247 } 

248 

249 response = self.client.get( 

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

251 ) 

252 self.assertEqual(response.status_code, 200) 

253 response_json = response.json 

254 

255 self.assertIn("active_devices", response_json) 

256 self.assertIn("latest_active_devices", response_json) 

257 

258 active_devices = response_json["active_devices"] 

259 self.assertEqual( 

260 active_devices["name"], "weekly_installed_base_by_architecture" 

261 ) 

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

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

264 

265 

266class GetMetricAnnotation(TestCase): 

267 render_templates = False 

268 

269 snap_name = "test-snap" 

270 snap_payload = { 

271 "snap_name": snap_name, 

272 "snap_id": "snap_id", 

273 "categories": { 

274 "locked": False, 

275 "items": [ 

276 { 

277 "featured": False, 

278 "name": "development", 

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

280 }, 

281 { 

282 "featured": True, 

283 "name": "featured", 

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

285 }, 

286 { 

287 "featured": True, 

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

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

290 }, 

291 ], 

292 }, 

293 } 

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

295 

296 def create_app(self): 

297 app = create_app(testing=True) 

298 app.secret_key = "secret_key" 

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

300 return app 

301 

302 @responses.activate 

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

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

305 def test_get_active_devices_weekly_installed_by_version( 

306 self, mock_get_snap_info, mock_is_authenticated 

307 ): 

308 mock_is_authenticated.return_value = True 

309 

310 mock_get_snap_info.return_value = self.snap_payload 

311 

312 with self.client.session_transaction() as sess: 

313 sess["publisher"] = { 

314 "nickname": "test_username", 

315 "fullname": "Test User", 

316 "email": "test@example.com", 

317 } 

318 

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

320 self.assertEqual(response.status_code, 200) 

321 response_json = response.json 

322 

323 self.assertEqual( 

324 response_json["buckets"], 

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

326 ) 

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

328 self.assertEqual( 

329 response_json["series"], 

330 [ 

331 { 

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

333 "display_date": "January 2019", 

334 "display_name": "Server and cloud", 

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

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

337 }, 

338 { 

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

340 "display_date": "February 2019", 

341 "display_name": "Development", 

342 "name": "development", 

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

344 }, 

345 { 

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

347 "display_date": "July 2024", 

348 "display_name": "Featured", 

349 "name": "featured", 

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

351 }, 

352 ], 

353 ) 

354 

355 

356class GetCountryMetric(TestCase): 

357 render_templates = False 

358 

359 snap_name = "test-snap" 

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

361 

362 def create_app(self): 

363 app = create_app(testing=True) 

364 app.secret_key = "secret_key" 

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

366 return app 

367 

368 @responses.activate 

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

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

371 @patch( 

372 "canonicalwebteam.store_api.dashboard.Dashboard.get_publisher_metrics" 

373 ) 

374 def test_get_active_devices_weekly_installed_by_version( 

375 self, 

376 mock_get_publisher_metrics, 

377 mock_get_item_details, 

378 mock_is_authenticated, 

379 ): 

380 mock_is_authenticated.return_value = True 

381 

382 countries = [ 

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

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

385 ] 

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

387 mock_get_publisher_metrics.return_value = { 

388 "metrics": [ 

389 { 

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

391 "metric_name": "weekly_installed_base_by_country", 

392 "series": countries, 

393 "snap_id": "id", 

394 "status": "OK", 

395 } 

396 ] 

397 } 

398 

399 with self.client.session_transaction() as sess: 

400 sess["publisher"] = { 

401 "nickname": "test_username", 

402 "fullname": "Test User", 

403 "email": "test@example.com", 

404 } 

405 

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

407 self.assertEqual(response.status_code, 200) 

408 response_json = response.json 

409 active_devices = response_json["active_devices"] 

410 

411 for info in active_devices: 

412 country_info = active_devices[info] 

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

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

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

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

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

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

419 else: 

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

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