Browse Source

Handler for changing notifications statuses added

As workaround for decreasing loading in the UI on unread
notifications fetching we can mark all notifications as read.
For such purposes we add NotificationsMarkAllHandler

Change-Id: I2e6a0daaf8712ab3064df728a8fb463ef805aa06
Partial-Bug: #1657348
Alexander Kislitsky 2 years ago
parent
commit
71fb921dbe

+ 22
- 4
nailgun/nailgun/api/v1/handlers/notifications.py View File

@@ -19,15 +19,14 @@ Handlers dealing with notifications
19 19
 """
20 20
 import web
21 21
 
22
+from nailgun.api.v1.handlers.base import BaseHandler
22 23
 from nailgun.api.v1.handlers.base import CollectionHandler
23
-from nailgun.api.v1.handlers.base import SingleHandler
24
-
25
-from nailgun import objects
26
-
27 24
 from nailgun.api.v1.handlers.base import handle_errors
28 25
 from nailgun.api.v1.handlers.base import serialize
26
+from nailgun.api.v1.handlers.base import SingleHandler
29 27
 from nailgun.api.v1.handlers.base import validate
30 28
 from nailgun.api.v1.validators.notification import NotificationValidator
29
+from nailgun import objects
31 30
 
32 31
 
33 32
 class NotificationHandler(SingleHandler):
@@ -89,3 +88,22 @@ class NotificationCollectionStatsHandler(CollectionHandler):
89 88
         :http: * 405 (Method not allowed)
90 89
         """
91 90
         raise self.http(405)
91
+
92
+
93
+class NotificationStatusHandler(BaseHandler):
94
+
95
+    validator = NotificationValidator
96
+
97
+    @handle_errors
98
+    @validate
99
+    @serialize
100
+    def PUT(self):
101
+        """Updates status of all notifications
102
+
103
+        :http: * 200 (OK)
104
+               * 400 (Invalid data)
105
+        """
106
+        web_data = web.data()
107
+        data = self.validator.validate_change_status(web_data)
108
+        status = data['status']
109
+        objects.NotificationCollection.update_statuses(status)

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

@@ -88,6 +88,9 @@ from nailgun.api.v1.handlers.plugin_link import PluginLinkHandler
88 88
 from nailgun.api.v1.handlers.notifications import NotificationCollectionHandler
89 89
 from nailgun.api.v1.handlers.notifications import \
90 90
     NotificationCollectionStatsHandler
91
+from nailgun.api.v1.handlers.notifications import \
92
+    NotificationStatusHandler
93
+
91 94
 from nailgun.api.v1.handlers.notifications import NotificationHandler
92 95
 
93 96
 from nailgun.api.v1.handlers.orchestrator import DefaultDeploymentInfo
@@ -336,6 +339,8 @@ urls = (
336 339
 
337 340
     r'/notifications/?$',
338 341
     NotificationCollectionHandler,
342
+    r'/notifications/change_status/?$',
343
+    NotificationStatusHandler,
339 344
     r'/notifications/(?P<obj_id>\d+)/?$',
340 345
     NotificationHandler,
341 346
     r'/notifications/stats/?$',

+ 29
- 0
nailgun/nailgun/api/v1/validators/json_schema/notification.py View File

@@ -0,0 +1,29 @@
1
+#    Copyright 2017 Mirantis, Inc.
2
+#
3
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+#    not use this file except in compliance with the License. You may obtain
5
+#    a copy of the License at
6
+#
7
+#         http://www.apache.org/licenses/LICENSE-2.0
8
+#
9
+#    Unless required by applicable law or agreed to in writing, software
10
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+#    License for the specific language governing permissions and limitations
13
+#    under the License.
14
+
15
+from nailgun import consts
16
+
17
+
18
+NOTIFICATIONS_CHANGE_STATUS = {
19
+    "$schema": "http://json-schema.org/draft-04/schema#",
20
+    "type": "object",
21
+    "required": ["status"],
22
+    "properties": {
23
+        "status": {
24
+            "type": "string",
25
+            "enum": list(consts.NOTIFICATION_STATUSES)
26
+        },
27
+
28
+    }
29
+}

+ 9
- 3
nailgun/nailgun/api/v1/validators/notification.py View File

@@ -13,11 +13,11 @@
13 13
 #    License for the specific language governing permissions and limitations
14 14
 #    under the License.
15 15
 
16
-from nailgun import consts
17
-from nailgun import objects
18
-
19 16
 from nailgun.api.v1.validators.base import BasicValidator
17
+from nailgun.api.v1.validators.json_schema import notification
18
+from nailgun import consts
20 19
 from nailgun import errors
20
+from nailgun import objects
21 21
 
22 22
 
23 23
 class NotificationValidator(BasicValidator):
@@ -90,3 +90,9 @@ class NotificationValidator(BasicValidator):
90 90
         without any validations.
91 91
         """
92 92
         pass
93
+
94
+    @classmethod
95
+    def validate_change_status(cls, data):
96
+        parsed = super(NotificationValidator, cls).validate(data)
97
+        cls.validate_schema(parsed, notification.NOTIFICATIONS_CHANGE_STATUS)
98
+        return parsed

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

@@ -109,3 +109,8 @@ class Notification(NailgunObject):
109 109
 class NotificationCollection(NailgunCollection):
110 110
 
111 111
     single = Notification
112
+
113
+    @classmethod
114
+    def update_statuses(cls, status):
115
+        db().query(cls.single.model).update(
116
+            {cls.single.model.status: status}, synchronize_session=False)

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

@@ -16,6 +16,7 @@
16 16
 
17 17
 from oslo_serialization import jsonutils
18 18
 
19
+from nailgun import consts
19 20
 from nailgun.test.base import BaseIntegrationTest
20 21
 from nailgun.utils import reverse
21 22
 
@@ -140,3 +141,39 @@ class TestHandlers(BaseIntegrationTest):
140 141
             expect_errors=True
141 142
         )
142 143
         self.assertEqual(405, resp.status_code)
144
+
145
+    def test_notification_status(self):
146
+        self.env.create_notification(status=consts.NOTIFICATION_STATUSES.read)
147
+        self.env.create_notification(
148
+            status=consts.NOTIFICATION_STATUSES.unread)
149
+        self.env.create_notification(
150
+            status=consts.NOTIFICATION_STATUSES.unread)
151
+
152
+        expected_status = consts.NOTIFICATION_STATUSES.unread
153
+        resp = self.app.put(
154
+            reverse('NotificationStatusHandler'),
155
+            params=jsonutils.dumps({'status': expected_status}),
156
+            headers=self.default_headers
157
+        )
158
+        self.assertEqual(200, resp.status_code)
159
+
160
+        # Checking statuses are changed
161
+        resp = self.app.get(
162
+            reverse('NotificationCollectionHandler'),
163
+            headers=self.default_headers
164
+        )
165
+        self.assertEqual(200, resp.status_code)
166
+        for notif in resp.json_body:
167
+            self.assertEqual(expected_status, notif['status'])
168
+
169
+    def test_notification_status_not_allowed_methods(self):
170
+        methods = ('get', 'post', 'delete', 'patch', 'head')
171
+        url = reverse('NotificationStatusHandler')
172
+        for m in methods:
173
+            method = getattr(self.app, m)
174
+            resp = method(
175
+                url,
176
+                headers=self.default_headers,
177
+                expect_errors=True
178
+            )
179
+            self.assertEqual(405, resp.status_code)

Loading…
Cancel
Save