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
« 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
7import responses
8from tests.publisher.endpoint_testing import BaseTestCases
11class MetricsPageNotAuth(BaseTestCases.EndpointLoggedOut):
12 def setUp(self):
13 snap_name = "test-snap"
14 endpoint_url = "/{}/metrics".format(snap_name)
16 super().setUp(snap_name=snap_name, endpoint_url=endpoint_url)
19class GetActiveDeviceAnnotationGetInfo(
20 BaseTestCases.EndpointLoggedInErrorHandling
21):
22 def setUp(self):
23 snap_name = "test-snap"
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 )
37class GetActiveDeviceMetrics(TestCase):
38 render_templates = False
40 snap_name = "test-snap"
41 endpoint_url = "/test-snap/metrics/active-devices"
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
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
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 }
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 ]
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 }
88 response = self.client.get(self.endpoint_url)
89 self.assertEqual(response.status_code, 200)
90 response_json = response.json
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 )
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)
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 }
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 }
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 )
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)
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 }
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 }
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)
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)
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 }
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 }
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
255 self.assertIn("active_devices", response_json)
256 self.assertIn("latest_active_devices", response_json)
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)
266class GetMetricAnnotation(TestCase):
267 render_templates = False
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"
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
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
310 mock_get_snap_info.return_value = self.snap_payload
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 }
319 response = self.client.get(self.endpoint_url)
320 self.assertEqual(response.status_code, 200)
321 response_json = response.json
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 )
356class GetCountryMetric(TestCase):
357 render_templates = False
359 snap_name = "test-snap"
360 endpoint_url = "/test-snap/metrics/country-metric"
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
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
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 }
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 }
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"]
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])