Browse Source

Merge "Handler for counting notifications statuses added"

Jenkins 2 years ago
parent
commit
542b8558f2

+ 30
- 0
nailgun/nailgun/api/v1/handlers/notifications.py View File

@@ -59,3 +59,33 @@ class NotificationCollectionHandler(CollectionHandler):
59 59
             self.collection.single.update(notif, nd)
60 60
             notifications_updated.append(notif)
61 61
         return self.collection.to_list(notifications_updated)
62
+
63
+
64
+class 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)

+ 4
- 0
nailgun/nailgun/api/v1/urls.py View File

@@ -86,6 +86,8 @@ from nailgun.api.v1.handlers.plugin_link import PluginLinkCollectionHandler
86 86
 from nailgun.api.v1.handlers.plugin_link import PluginLinkHandler
87 87
 
88 88
 from nailgun.api.v1.handlers.notifications import NotificationCollectionHandler
89
+from nailgun.api.v1.handlers.notifications import \
90
+    NotificationCollectionStatsHandler
89 91
 from nailgun.api.v1.handlers.notifications import NotificationHandler
90 92
 
91 93
 from nailgun.api.v1.handlers.orchestrator import DefaultDeploymentInfo
@@ -336,6 +338,8 @@ urls = (
336 338
     NotificationCollectionHandler,
337 339
     r'/notifications/(?P<obj_id>\d+)/?$',
338 340
     NotificationHandler,
341
+    r'/notifications/stats/?$',
342
+    NotificationCollectionStatsHandler,
339 343
 
340 344
     r'/dump/(?P<snapshot_name>[A-Za-z0-9-_.]+)$',
341 345
     SnapshotDownloadHandler,

+ 23
- 5
nailgun/nailgun/objects/notification.py View File

@@ -16,17 +16,17 @@
16 16
 
17 17
 from datetime import datetime
18 18
 
19
-from nailgun.db.sqlalchemy import models
19
+from sqlalchemy import func
20 20
 
21
+from nailgun import consts
22
+from nailgun.db import db
23
+from nailgun.db.sqlalchemy import models
21 24
 from nailgun import errors
22 25
 from nailgun.logger import logger
23
-
24 26
 from nailgun.objects import NailgunCollection
25 27
 from nailgun.objects import NailgunObject
26
-
27
-from nailgun.objects import Task
28
-
29 28
 from nailgun.objects.serializers.notification import NotificationSerializer
29
+from nailgun.objects import Task
30 30
 
31 31
 
32 32
 class Notification(NailgunObject):
@@ -87,6 +87,24 @@ class Notification(NailgunObject):
87 87
         notif_dict['date'] = instance.datetime.strftime('%d-%m-%Y')
88 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
 
91 109
 class NotificationCollection(NailgunCollection):
92 110
 

+ 39
- 0
nailgun/nailgun/test/unit/test_notification_handler.py View File

@@ -101,3 +101,42 @@ class TestHandlers(BaseIntegrationTest):
101 101
             expect_errors=True
102 102
         )
103 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)

Loading…
Cancel
Save