diff --git a/ckanext/datarequests/db.py b/ckanext/datarequests/db.py index 94eb10a0..6d47ce72 100644 --- a/ckanext/datarequests/db.py +++ b/ckanext/datarequests/db.py @@ -94,6 +94,13 @@ def get_ordered_by_date(cls, **kw): query = model.Session.query(cls).autoflush(False) return query.filter_by(**kw).order_by(cls.time.desc()).all() + @classmethod + def get_datarequest_comments(cls, **kw): + ''' + Returned the number of comments of a data request + ''' + return model.Session.query(func.count(cls.id)).filter_by(**kw).scalar() + Comment = _Comment # FIXME: References to the other tables... diff --git a/ckanext/datarequests/helpers.py b/ckanext/datarequests/helpers.py new file mode 100644 index 00000000..c2cc732f --- /dev/null +++ b/ckanext/datarequests/helpers.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2015 CoNWeT Lab., Universidad Politécnica de Madrid + +# This file is part of CKAN Data Requests Extension. + +# CKAN Data Requests Extension is free software: you can redistribute it and/or +# modify it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# CKAN Data Requests Extension is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# You should have received a copy of the GNU Affero General Public License +# along with CKAN Data Requests Extension. If not, see . + +import ckan.model as model +import ckan.plugins.toolkit as tk +import db + + +def get_comments_number(datarequest_id): + # DB can be not intialized + db.init_db(model) + return db.Comment.get_datarequest_comments(datarequest_id=datarequest_id) + + +def get_comments_badge(datarequest_id): + return tk.render_snippet('datarequests/snippets/comments_badge.html', + {'comments_count': get_comments_number(datarequest_id)}) diff --git a/ckanext/datarequests/plugin.py b/ckanext/datarequests/plugin.py index 841d6331..a0b5893f 100644 --- a/ckanext/datarequests/plugin.py +++ b/ckanext/datarequests/plugin.py @@ -22,6 +22,7 @@ import auth import actions import constants +import helpers from pylons import config @@ -169,4 +170,8 @@ def before_map(self, m): ###################################################################### def get_helpers(self): - return {'show_comments_tab': lambda: self.comments_enabled} + return { + 'show_comments_tab': lambda: self.comments_enabled, + 'get_comments_number': helpers.get_comments_number, + 'get_comments_badge': helpers.get_comments_badge + } diff --git a/ckanext/datarequests/public/datarequests.css b/ckanext/datarequests/public/datarequests.css index da490f46..fc4479ab 100644 --- a/ckanext/datarequests/public/datarequests.css +++ b/ckanext/datarequests/public/datarequests.css @@ -19,4 +19,13 @@ font-size: 12px; white-space: nowrap; margin-top: 8px; +} + +.divider { + display: inline-block; + margin-left: 10px; +} + +.datarequest-properties { + margin-top: 8px; } \ No newline at end of file diff --git a/ckanext/datarequests/templates/datarequests/show.html b/ckanext/datarequests/templates/datarequests/show.html index 722c7b9e..60bba69d 100644 --- a/ckanext/datarequests/templates/datarequests/show.html +++ b/ckanext/datarequests/templates/datarequests/show.html @@ -25,7 +25,7 @@ {{ h.build_nav_icon('datarequest_show', _('Data Request'), id=datarequest_id) }} {% if h.show_comments_tab() %} - {{ h.build_nav_icon('datarequest_comment', _('Comments'), id=datarequest_id) }} + {{ h.build_nav_icon('datarequest_comment', _('Comments') + ' ' + h.get_comments_badge(datarequest_id), id=datarequest_id) }} {% endif %} {% endblock %} diff --git a/ckanext/datarequests/templates/datarequests/snippets/comments_badge.html b/ckanext/datarequests/templates/datarequests/snippets/comments_badge.html new file mode 100644 index 00000000..5a5178ad --- /dev/null +++ b/ckanext/datarequests/templates/datarequests/snippets/comments_badge.html @@ -0,0 +1 @@ +{{ comments_count }} \ No newline at end of file diff --git a/ckanext/datarequests/templates/datarequests/snippets/datarequest_item.html b/ckanext/datarequests/templates/datarequests/snippets/datarequest_item.html index a3835c33..bef3e729 100644 --- a/ckanext/datarequests/templates/datarequests/snippets/datarequest_item.html +++ b/ckanext/datarequests/templates/datarequests/snippets/datarequest_item.html @@ -21,7 +21,13 @@

{% if description %}
{{ description }}
{% endif %} -
{{ h.time_ago_from_timestamp(datarequest.open_time) }}
+
+ {% if h.show_comments_tab() %} + {{ h.get_comments_number(datarequest.get('id', '')) }} + {% endif %} +
+ {{ h.time_ago_from_timestamp(datarequest.open_time) }} +
{% endblock %} \ No newline at end of file diff --git a/ckanext/datarequests/tests/test_db.py b/ckanext/datarequests/tests/test_db.py index 1521f68e..9387bc93 100644 --- a/ckanext/datarequests/tests/test_db.py +++ b/ckanext/datarequests/tests/test_db.py @@ -203,3 +203,37 @@ def test_comment_get(self): def test_comment_get_ordered_by_date(self): self._test_get_ordered_by_date('Comment', 'time') + + def test_get_datarequests_comments(self): + + n_comments = 7 + count = 'example' + + db.func = MagicMock() + db.func.count.return_value = count + + filter_by = MagicMock() + filter_by.scalar.return_value = n_comments + + query = MagicMock() + query.filter_by = MagicMock(return_value=filter_by) + + model = MagicMock() + model.DomainObject = object + model.Session.query = MagicMock(return_value=query) + + # Init the database + db.init_db(model) + + # Call the method + params = { + 'datarequest_id': 'example_uuid_v4' + } + db.Comment.id = 'id' + result = db.Comment.get_datarequest_comments(**params) + + # Assertions + self.assertEquals(n_comments, result) + query.filter_by.assert_called_once_with(**params) + model.Session.query.assert_called_once_with(count) + db.func.count.assert_called_once_with(db.Comment.id) diff --git a/ckanext/datarequests/tests/test_helpers.py b/ckanext/datarequests/tests/test_helpers.py new file mode 100644 index 00000000..c06d2c39 --- /dev/null +++ b/ckanext/datarequests/tests/test_helpers.py @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2015 CoNWeT Lab., Universidad Politécnica de Madrid + +# This file is part of CKAN Data Requests Extension. + +# CKAN Data Requests Extension is free software: you can redistribute it and/or +# modify it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# CKAN Data Requests Extension is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# You should have received a copy of the GNU Affero General Public License +# along with CKAN Data Requests Extension. If not, see . + +import ckanext.datarequests.helpers as helpers +import unittest + +from mock import MagicMock + + +class HelpersTest(unittest.TestCase): + + def setUp(self): + self._tk = helpers.tk + helpers.tk = MagicMock() + + self._model = helpers.model + helpers.model = MagicMock() + + self._db = helpers.db + helpers.db = MagicMock() + + def tearDown(self): + helpers.tk = self._tk + helpers.model = self._model + helpers.db = self._db + + def test_get_comments_number(self): + # Mocking + n_comments = 3 + helpers.db.Comment.get_datarequest_comments.return_value = 3 + + # Call the function + datarequest_id = 'example_uuidv4' + result = helpers.get_comments_number(datarequest_id) + + # Assertions + helpers.db.init_db.assert_called_once_with(helpers.model) + helpers.db.Comment.get_datarequest_comments.assert_called_once_with(datarequest_id=datarequest_id) + self.assertEquals(result, n_comments) + + def test_get_comments_badge(self): + # Mocking + n_comments = 3 + helpers.db.Comment.get_datarequest_comments.return_value = 3 + + # Call the function + datarequest_id = 'example_uuidv4' + result = helpers.get_comments_badge(datarequest_id) + + # Assertions + helpers.db.init_db.assert_called_once_with(helpers.model) + helpers.db.Comment.get_datarequest_comments.assert_called_once_with(datarequest_id=datarequest_id) + self.assertEquals(result, helpers.tk.render_snippet.return_value) + helpers.tk.render_snippet.assert_called_once_with('datarequests/snippets/comments_badge.html', + {'comments_count': n_comments}) diff --git a/ckanext/datarequests/tests/test_plugin.py b/ckanext/datarequests/tests/test_plugin.py index 3e050539..0d8f276d 100644 --- a/ckanext/datarequests/tests/test_plugin.py +++ b/ckanext/datarequests/tests/test_plugin.py @@ -29,7 +29,7 @@ ACTIONS_NO_COMMENTS = TOTAL_ACTIONS - COMMENTS_ACTIONS -class DataRequestPlutinTest(unittest.TestCase): +class DataRequestPluginTest(unittest.TestCase): def setUp(self): self._actions = plugin.actions @@ -44,6 +44,9 @@ def setUp(self): self._config = plugin.config plugin.config = MagicMock() + self._helpers = plugin.helpers + plugin.helpers = MagicMock() + # plg = plugin self.datarequest_create = constants.DATAREQUEST_CREATE self.datarequest_show = constants.DATAREQUEST_SHOW @@ -60,6 +63,7 @@ def tearDown(self): plugin.actions = self._actions plugin.auth = self._auth plugin.tk = self._tk + plugin.helpers = self._helpers @parameterized.expand([ ('True',), @@ -204,4 +208,7 @@ def test_helpers(self, comments_enabled): # Check result expected_result = True if comments_enabled == 'True' else False - self.assertEquals(self.plg_instance.get_helpers()['show_comments_tab'](), expected_result) + helpers = self.plg_instance.get_helpers() + self.assertEquals(helpers['show_comments_tab'](), expected_result) + self.assertEquals(helpers['get_comments_number'], plugin.helpers.get_comments_number) + self.assertEquals(helpers['get_comments_badge'], plugin.helpers.get_comments_badge)