summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2017-01-31 11:36:38 +0000
committerGerrit Code Review <review@openstack.org>2017-01-31 11:36:39 +0000
commit542b8558f2129fd159a6fb661adad65c922676fa (patch)
treef7a64254e08d3c1f8c96e271e05e0cf6491df5b3
parente46b57befc0032448e12581dc64458170280d465 (diff)
parentd4bf85957e13abecc519c84f43122e55df510eec (diff)
Merge "Handler for counting notifications statuses added"
-rw-r--r--nailgun/nailgun/api/v1/handlers/notifications.py30
-rw-r--r--nailgun/nailgun/api/v1/urls.py4
-rw-r--r--nailgun/nailgun/objects/notification.py28
-rw-r--r--nailgun/nailgun/test/unit/test_notification_handler.py39
4 files changed, 96 insertions, 5 deletions
diff --git a/nailgun/nailgun/api/v1/handlers/notifications.py b/nailgun/nailgun/api/v1/handlers/notifications.py
index 6113c8f..c516b4e 100644
--- a/nailgun/nailgun/api/v1/handlers/notifications.py
+++ b/nailgun/nailgun/api/v1/handlers/notifications.py
@@ -59,3 +59,33 @@ class NotificationCollectionHandler(CollectionHandler):
59 self.collection.single.update(notif, nd) 59 self.collection.single.update(notif, nd)
60 notifications_updated.append(notif) 60 notifications_updated.append(notif)
61 return self.collection.to_list(notifications_updated) 61 return self.collection.to_list(notifications_updated)
62
63
64class NotificationCollectionStatsHandler(CollectionHandler):
65
66 collection = objects.NotificationCollection
67 validator = NotificationValidator
68
69 @handle_errors
70 @validate
71 @serialize
72 def GET(self):
73 """Calculates notifications statuses
74
75 Counts all presented notifications in the DB and returns dict
76 with structure {'total': count, 'unread': count, ...}
77
78 :returns: dict with notifications statuses count
79
80 :http: * 200 (OK)
81 """
82 return self.collection.single.get_statuses_with_count()
83
84 @handle_errors
85 @validate
86 def POST(self):
87 """Update notification statuses is not allowed
88
89 :http: * 405 (Method not allowed)
90 """
91 raise self.http(405)
diff --git a/nailgun/nailgun/api/v1/urls.py b/nailgun/nailgun/api/v1/urls.py
index d4249db..78dbeba 100644
--- a/nailgun/nailgun/api/v1/urls.py
+++ b/nailgun/nailgun/api/v1/urls.py
@@ -86,6 +86,8 @@ from nailgun.api.v1.handlers.plugin_link import PluginLinkCollectionHandler
86from nailgun.api.v1.handlers.plugin_link import PluginLinkHandler 86from nailgun.api.v1.handlers.plugin_link import PluginLinkHandler
87 87
88from nailgun.api.v1.handlers.notifications import NotificationCollectionHandler 88from nailgun.api.v1.handlers.notifications import NotificationCollectionHandler
89from nailgun.api.v1.handlers.notifications import \
90 NotificationCollectionStatsHandler
89from nailgun.api.v1.handlers.notifications import NotificationHandler 91from nailgun.api.v1.handlers.notifications import NotificationHandler
90 92
91from nailgun.api.v1.handlers.orchestrator import DefaultDeploymentInfo 93from nailgun.api.v1.handlers.orchestrator import DefaultDeploymentInfo
@@ -336,6 +338,8 @@ urls = (
336 NotificationCollectionHandler, 338 NotificationCollectionHandler,
337 r'/notifications/(?P<obj_id>\d+)/?$', 339 r'/notifications/(?P<obj_id>\d+)/?$',
338 NotificationHandler, 340 NotificationHandler,
341 r'/notifications/stats/?$',
342 NotificationCollectionStatsHandler,
339 343
340 r'/dump/(?P<snapshot_name>[A-Za-z0-9-_.]+)$', 344 r'/dump/(?P<snapshot_name>[A-Za-z0-9-_.]+)$',
341 SnapshotDownloadHandler, 345 SnapshotDownloadHandler,
diff --git a/nailgun/nailgun/objects/notification.py b/nailgun/nailgun/objects/notification.py
index 94d711f..e7d2bb8 100644
--- a/nailgun/nailgun/objects/notification.py
+++ b/nailgun/nailgun/objects/notification.py
@@ -16,17 +16,17 @@
16 16
17from datetime import datetime 17from datetime import datetime
18 18
19from nailgun.db.sqlalchemy import models 19from sqlalchemy import func
20 20
21from nailgun import consts
22from nailgun.db import db
23from nailgun.db.sqlalchemy import models
21from nailgun import errors 24from nailgun import errors
22from nailgun.logger import logger 25from nailgun.logger import logger
23
24from nailgun.objects import NailgunCollection 26from nailgun.objects import NailgunCollection
25from nailgun.objects import NailgunObject 27from nailgun.objects import NailgunObject
26
27from nailgun.objects import Task
28
29from nailgun.objects.serializers.notification import NotificationSerializer 28from nailgun.objects.serializers.notification import NotificationSerializer
29from nailgun.objects import Task
30 30
31 31
32class Notification(NailgunObject): 32class Notification(NailgunObject):
@@ -87,6 +87,24 @@ class Notification(NailgunObject):
87 notif_dict['date'] = instance.datetime.strftime('%d-%m-%Y') 87 notif_dict['date'] = instance.datetime.strftime('%d-%m-%Y')
88 return notif_dict 88 return notif_dict
89 89
90 @classmethod
91 def get_statuses_with_count(cls):
92 """Counts notifications statuses in DB
93
94 Calculates number of notifications and adds total count to the
95 result. All notifications statuses described in the
96 consts.NOTIFICATION_STATUSES will be present in the result.
97
98 :return: dict with structure {'total': count, 'unread': count, ...}
99 """
100 result = dict.fromkeys(consts.NOTIFICATION_STATUSES, 0)
101 query = db().query(cls.model.status, func.count(cls.model.status)).\
102 group_by(cls.model.status)
103 for status, num in query.all():
104 result[status] = num
105 result['total'] = sum(result.values())
106 return result
107
90 108
91class NotificationCollection(NailgunCollection): 109class NotificationCollection(NailgunCollection):
92 110
diff --git a/nailgun/nailgun/test/unit/test_notification_handler.py b/nailgun/nailgun/test/unit/test_notification_handler.py
index c82100d..69fd57e 100644
--- a/nailgun/nailgun/test/unit/test_notification_handler.py
+++ b/nailgun/nailgun/test/unit/test_notification_handler.py
@@ -101,3 +101,42 @@ class TestHandlers(BaseIntegrationTest):
101 expect_errors=True 101 expect_errors=True
102 ) 102 )
103 self.assertEqual(404, resp.status_code) 103 self.assertEqual(404, resp.status_code)
104
105 def test_get_notification_status(self):
106 resp = self.app.get(
107 reverse(
108 'NotificationCollectionStatsHandler',
109 ),
110 headers=self.default_headers
111 )
112 self.assertEqual({'total': 0, 'read': 0, 'unread': 0}, resp.json_body)
113 self.assertEqual(200, resp.status_code)
114
115 self.env.create_notification()
116 resp = self.app.get(
117 reverse(
118 'NotificationCollectionStatsHandler',
119 ),
120 headers=self.default_headers
121 )
122 self.assertEqual({'total': 1, 'read': 0, 'unread': 1}, resp.json_body)
123
124 self.env.create_notification(status='read')
125 self.env.create_notification(status='read')
126 resp = self.app.get(
127 reverse(
128 'NotificationCollectionStatsHandler',
129 ),
130 headers=self.default_headers
131 )
132 self.assertEqual({'total': 3, 'read': 2, 'unread': 1}, resp.json_body)
133
134 def test_notification_statuses_post_not_allowed(self):
135 resp = self.app.post(
136 reverse(
137 'NotificationCollectionStatsHandler',
138 ),
139 headers=self.default_headers,
140 expect_errors=True
141 )
142 self.assertEqual(405, resp.status_code)