diff options
-rw-r--r-- | app/handlers/base.py | 45 | ||||
-rw-r--r-- | app/handlers/tests/test_handler_static.py | 94 | ||||
-rw-r--r-- | app/tests/__init__.py | 1 |
3 files changed, 140 insertions, 0 deletions
diff --git a/app/handlers/base.py b/app/handlers/base.py index 09f4024..0feedbd 100644 --- a/app/handlers/base.py +++ b/app/handlers/base.py @@ -21,6 +21,13 @@ import tornado import types from bson.json_util import dumps +from bson import tz_util +from datetime import ( + date, + datetime, + time, + timedelta, +) from functools import partial from pymongo import ( ASCENDING, @@ -40,6 +47,10 @@ from utils.db import ( from utils.log import get_log from utils.validator import is_valid_json +# Default value to calculate a date range in case the provided value is +# out of range. +DEFAULT_DATE_RANGE = 15 + class BaseHandler(RequestHandler): """The base handler.""" @@ -354,6 +365,13 @@ class BaseHandler(RequestHandler): ] } + date_range = self.get_query_argument('date_range', default=None) + if date_range: + today = datetime.combine(date.today(), time(tzinfo=tz_util.utc)) + previous = self._calculate_date_range(date_range) + + spec['created'] = {'$gte': previous, '$lt': today} + return spec def _get_query_sort(self): @@ -415,3 +433,30 @@ class BaseHandler(RequestHandler): self.finish() else: super(BaseHandler, self).write_error(status_code, kwargs) + + @staticmethod + def _calculate_date_range(date_range): + """Calculate the new date subtracting the passed number of days. + + It removes the passed days from today date, calculated at midnight + UTC. + + :param date_range: The number of days to remove from today. + :type date_range int, long, str + :return A new `datetime.date` object that is the result of the + subtraction of `datetime.date.today()` and + `datetime.timedelta(days=date_range)`. + """ + if isinstance(date_range, types.StringTypes): + date_range = int(date_range) + + date_range = abs(date_range) + if date_range > timedelta.max.days: + date_range = DEFAULT_DATE_RANGE + + today = datetime.combine( + date.today(), time(tzinfo=tz_util.utc) + ) + delta = timedelta(days=date_range) + + return today - delta diff --git a/app/handlers/tests/test_handler_static.py b/app/handlers/tests/test_handler_static.py new file mode 100644 index 0000000..afb086b --- /dev/null +++ b/app/handlers/tests/test_handler_static.py @@ -0,0 +1,94 @@ +# Copyright (C) 2014 Linaro Ltd. +# +# This program 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. +# +# This program 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 this program. If not, see <http://www.gnu.org/licenses/>. + +"""Test static or class methods from handler classes.""" + +import unittest + +from bson import tz_util + +from datetime import ( + date, + datetime, + timedelta, + time, +) + +from mock import patch + +from handlers.base import BaseHandler + + +class TestHandlerStatic(unittest.TestCase): + + def setUp(self): + super(TestHandlerStatic, self).setUp() + + self.min_time = time(tzinfo=tz_util.utc) + patched_date = patch('handlers.base.date') + self.mock_date = patched_date.start() + + self.addCleanup(patched_date.stop,) + + def test_calculate_date_range_valid(self): + self.mock_date.today.return_value = date(2014, 1, 1) + + expected = datetime.combine(date(2013, 12, 17), self.min_time) + self.assertEqual(expected, BaseHandler._calculate_date_range(15)) + + def test_calculate_date_range_zero(self): + self.mock_date.today.return_value = date(2014, 1, 1) + + expected = datetime.combine(date(2014, 1, 1), self.min_time) + self.assertEqual(expected, BaseHandler._calculate_date_range(0)) + + def test_calculate_date_range_leap(self): + self.mock_date.today.return_value = date(2012, 3, 14) + + expected = datetime.combine(date(2012, 2, 28), self.min_time) + self.assertEqual(expected, BaseHandler._calculate_date_range(15)) + + def test_calculate_date_range_non_leap(self): + self.mock_date.today.return_value = date(2013, 3, 14) + + expected = datetime.combine(date(2013, 2, 27), self.min_time) + self.assertEqual(expected, BaseHandler._calculate_date_range(15)) + + def test_calculate_date_range_with_string(self): + self.mock_date.today.return_value = date(2014, 1, 1) + + expected = datetime.combine(date(2013, 12, 31), self.min_time) + self.assertEqual(expected, BaseHandler._calculate_date_range('1')) + + def test_calculate_date_range_negative(self): + self.mock_date.today.return_value = date(2014, 1, 1) + + expected = datetime.combine(date(2013, 12, 31), self.min_time) + self.assertEqual(expected, BaseHandler._calculate_date_range(-1)) + + def test_calculate_date_range_negative_string(self): + self.mock_date.today.return_value = date(2014, 1, 1) + + expected = datetime.combine(date(2013, 12, 31), self.min_time) + self.assertEqual(expected, BaseHandler._calculate_date_range('-1')) + + def test_calculate_date_range_out_of_range(self): + self.mock_date.today.return_value = date(2014, 1, 1) + + expected = datetime.combine(date(2013, 12, 17), self.min_time) + self.assertEqual( + expected, + BaseHandler._calculate_date_range(timedelta.max.days + 10) + ) diff --git a/app/tests/__init__.py b/app/tests/__init__.py index 9f22093..1075d00 100644 --- a/app/tests/__init__.py +++ b/app/tests/__init__.py @@ -22,6 +22,7 @@ def test_modules(): return [ 'handlers.tests.test_count_handler', 'handlers.tests.test_defconf_handler', + 'handlers.tests.test_handler_static', 'handlers.tests.test_job_handler', 'handlers.tests.test_subscription_handler', 'models.tests.test_boot_model', |