2016-07-07 14:56:30 +02:00
|
|
|
# -*- encoding: utf-8 -*-
|
2017-03-03 12:07:11 +01:00
|
|
|
|
2016-10-12 16:01:30 +02:00
|
|
|
import unittest
|
2016-07-07 14:56:30 +02:00
|
|
|
|
|
|
|
from bson import ObjectId
|
2016-08-19 09:19:06 +02:00
|
|
|
from pillar.tests import AbstractPillarTest
|
2016-07-07 14:56:30 +02:00
|
|
|
from werkzeug.exceptions import BadRequest
|
|
|
|
|
|
|
|
|
|
|
|
class Str2idTest(AbstractPillarTest):
|
|
|
|
def test_happy(self):
|
2016-08-19 09:19:06 +02:00
|
|
|
from pillar.api.utils import str2id
|
2016-07-07 14:56:30 +02:00
|
|
|
|
|
|
|
def happy(str_id):
|
|
|
|
self.assertEqual(ObjectId(str_id), str2id(str_id))
|
|
|
|
|
|
|
|
happy(24 * 'a')
|
2017-03-03 14:14:36 +01:00
|
|
|
happy(12 * b'a')
|
2017-03-03 12:07:11 +01:00
|
|
|
happy('577e23ad98377323f74c368c')
|
2016-07-07 14:56:30 +02:00
|
|
|
|
|
|
|
def test_unhappy(self):
|
2016-08-19 09:19:06 +02:00
|
|
|
from pillar.api.utils import str2id
|
2016-07-07 14:56:30 +02:00
|
|
|
|
|
|
|
def unhappy(str_id):
|
|
|
|
self.assertRaises(BadRequest, str2id, str_id)
|
|
|
|
|
|
|
|
unhappy(13 * 'a')
|
2017-03-03 14:14:36 +01:00
|
|
|
unhappy(13 * b'a')
|
2017-03-03 12:07:11 +01:00
|
|
|
unhappy('577e23ad 8377323f74c368c')
|
|
|
|
unhappy('김치') # Kimchi
|
|
|
|
unhappy('')
|
2017-03-03 14:14:36 +01:00
|
|
|
unhappy(b'')
|
2016-07-07 14:56:30 +02:00
|
|
|
unhappy(None)
|
2016-10-12 16:01:30 +02:00
|
|
|
|
|
|
|
|
|
|
|
class DocDiffTest(unittest.TestCase):
|
|
|
|
def test_no_diff_simple(self):
|
|
|
|
from pillar.api.utils import doc_diff
|
|
|
|
diff = doc_diff({'a': 'b', 3: 42},
|
|
|
|
{'a': 'b', 3: 42})
|
|
|
|
|
|
|
|
self.assertEqual([], list(diff))
|
|
|
|
|
|
|
|
def test_no_diff_privates(self):
|
|
|
|
from pillar.api.utils import doc_diff
|
|
|
|
diff = doc_diff({'a': 'b', 3: 42, '_updated': 5133},
|
|
|
|
{'a': 'b', 3: 42, '_updated': 42})
|
|
|
|
|
|
|
|
self.assertEqual([], list(diff))
|
|
|
|
|
|
|
|
def test_diff_values_simple(self):
|
|
|
|
from pillar.api.utils import doc_diff
|
|
|
|
diff = doc_diff({'a': 'b', 3: 42},
|
|
|
|
{'a': 'b', 3: 513})
|
|
|
|
|
|
|
|
self.assertEqual([(3, 42, 513)], list(diff))
|
|
|
|
|
2016-10-12 17:09:48 +02:00
|
|
|
def test_diff_values_falsey(self):
|
|
|
|
from pillar.api.utils import doc_diff, DoesNotExist
|
|
|
|
|
|
|
|
# DoesNotExist vs. empty string
|
|
|
|
diff = doc_diff({'a': 'b', 3: ''},
|
|
|
|
{'a': 'b'})
|
|
|
|
self.assertEqual([], list(diff))
|
|
|
|
|
|
|
|
diff = doc_diff({'a': 'b', 3: ''},
|
|
|
|
{'a': 'b'}, falsey_is_equal=False)
|
|
|
|
self.assertEqual([(3, '', DoesNotExist)], list(diff))
|
|
|
|
|
|
|
|
# Empty string vs. None
|
|
|
|
diff = doc_diff({'a': 'b', 3: ''},
|
|
|
|
{'a': 'b', 3: None})
|
|
|
|
self.assertEqual([], list(diff))
|
|
|
|
|
|
|
|
diff = doc_diff({'a': 'b', 3: ''},
|
|
|
|
{'a': 'b', 3: None}, falsey_is_equal=False)
|
|
|
|
self.assertEqual([(3, '', None)], list(diff))
|
|
|
|
|
2016-10-12 16:01:30 +02:00
|
|
|
def test_diff_keys_simple(self):
|
|
|
|
from pillar.api.utils import doc_diff, DoesNotExist
|
|
|
|
diff = doc_diff({'a': 'b', 3: 42},
|
|
|
|
{'a': 'b', 2: 42})
|
|
|
|
|
|
|
|
self.assertEqual({(3, 42, DoesNotExist), (2, DoesNotExist, 42)}, set(diff))
|
|
|
|
|
|
|
|
def test_no_diff_nested(self):
|
|
|
|
from pillar.api.utils import doc_diff
|
2017-03-03 12:07:11 +01:00
|
|
|
diff = doc_diff({'a': 'b', 'props': {'status': 'todo', 'notes': 'jemoeder'}},
|
|
|
|
{'a': 'b', 'props': {'status': 'todo', 'notes': 'jemoeder'}})
|
2016-10-12 16:01:30 +02:00
|
|
|
|
|
|
|
self.assertEqual([], list(diff))
|
|
|
|
|
|
|
|
def test_diff_values_nested(self):
|
|
|
|
from pillar.api.utils import doc_diff
|
2017-03-03 12:07:11 +01:00
|
|
|
diff = doc_diff({'a': 'b', 'props': {'status': 'todo', 'notes': 'jemoeder'}},
|
|
|
|
{'a': 'c', 'props': {'status': 'done', 'notes': 'jemoeder'}})
|
2016-10-12 16:01:30 +02:00
|
|
|
|
2017-03-03 12:07:11 +01:00
|
|
|
self.assertEqual({('a', 'b', 'c'), ('props.status', 'todo', 'done')},
|
2016-10-12 16:01:30 +02:00
|
|
|
set(diff))
|
|
|
|
|
|
|
|
def test_diff_keys_nested(self):
|
|
|
|
from pillar.api.utils import doc_diff, DoesNotExist
|
2017-03-03 12:07:11 +01:00
|
|
|
diff = doc_diff({'a': 'b', 'props': {'status1': 'todo', 'notes': 'jemoeder'}},
|
|
|
|
{'a': 'b', 'props': {'status2': 'todo', 'notes': 'jemoeder'}})
|
2016-10-12 16:01:30 +02:00
|
|
|
|
2017-03-03 12:07:11 +01:00
|
|
|
self.assertEqual({('props.status1', 'todo', DoesNotExist),
|
|
|
|
('props.status2', DoesNotExist, 'todo')},
|
2016-10-12 16:01:30 +02:00
|
|
|
set(diff))
|
2016-11-09 12:50:30 +01:00
|
|
|
|
2018-03-27 11:19:46 +02:00
|
|
|
def test_diff_list_values(self):
|
|
|
|
from pillar.api.utils import doc_diff
|
|
|
|
diff = doc_diff({'a': 'b', 'props': ['status', 'todo', 'notes', 'jemoeder']},
|
|
|
|
{'a': 'b', 'props': ['todo', 'others', 'notes', 'jemoeder']})
|
|
|
|
|
|
|
|
self.assertEqual({
|
|
|
|
('props[0]', 'status', 'todo'),
|
|
|
|
('props[1]', 'todo', 'others'),
|
|
|
|
}, set(diff))
|
|
|
|
|
|
|
|
def test_diff_list_unequal_lengths(self):
|
|
|
|
from pillar.api.utils import doc_diff, DoesNotExist
|
|
|
|
diff = doc_diff({'a': 'b', 'props': ['status', 'todo', 'notes']},
|
|
|
|
{'a': 'b', 'props': ['todo', 'others', 'notes', 'jemoeder']})
|
|
|
|
|
|
|
|
self.assertEqual({
|
|
|
|
('props[0]', 'status', 'todo'),
|
|
|
|
('props[1]', 'todo', 'others'),
|
|
|
|
('props[3]', DoesNotExist, 'jemoeder'),
|
|
|
|
}, set(diff))
|
|
|
|
|
2016-11-09 12:50:30 +01:00
|
|
|
|
|
|
|
class NodeSetattrTest(unittest.TestCase):
|
|
|
|
def test_simple(self):
|
|
|
|
from pillar.api.utils import node_setattr
|
|
|
|
|
|
|
|
node = {}
|
|
|
|
node_setattr(node, 'a', 5)
|
|
|
|
self.assertEqual({'a': 5}, node)
|
|
|
|
|
|
|
|
node_setattr(node, 'b', {'complexer': 'value'})
|
|
|
|
self.assertEqual({'a': 5, 'b': {'complexer': 'value'}}, node)
|
|
|
|
|
|
|
|
def test_dotted(self):
|
|
|
|
from pillar.api.utils import node_setattr
|
|
|
|
|
|
|
|
node = {}
|
|
|
|
self.assertRaises(KeyError, node_setattr, node, 'a.b', 5)
|
|
|
|
|
|
|
|
node = {'b': {}}
|
|
|
|
node_setattr(node, 'b.simple', 'value')
|
|
|
|
self.assertEqual({'b': {'simple': 'value'}}, node)
|
|
|
|
|
|
|
|
node_setattr(node, 'b.complex', {'yes': 'value'})
|
|
|
|
self.assertEqual({'b': {'simple': 'value',
|
|
|
|
'complex': {'yes': 'value'}}}, node)
|
|
|
|
|
|
|
|
node_setattr(node, 'b.complex', {'yes': 5})
|
|
|
|
self.assertEqual({'b': {'simple': 'value',
|
|
|
|
'complex': {'yes': 5}}}, node)
|
|
|
|
|
|
|
|
def test_none_simple(self):
|
|
|
|
from pillar.api.utils import node_setattr
|
|
|
|
|
|
|
|
node = {}
|
|
|
|
node_setattr(node, 'a', None)
|
|
|
|
node_setattr(node, None, 'b')
|
|
|
|
self.assertEqual({None: 'b'}, node)
|
|
|
|
|
|
|
|
def test_none_dotted(self):
|
|
|
|
from pillar.api.utils import node_setattr
|
|
|
|
|
|
|
|
node = {}
|
|
|
|
self.assertRaises(KeyError, node_setattr, node, 'a.b', None)
|
|
|
|
|
|
|
|
node = {'b': {}}
|
|
|
|
node_setattr(node, 'b.simple', None)
|
|
|
|
self.assertEqual({'b': {}}, node)
|
|
|
|
|
|
|
|
node_setattr(node, 'b.complex', {'yes': None})
|
|
|
|
self.assertEqual({'b': {'complex': {'yes': None}}}, node)
|
|
|
|
|
|
|
|
node_setattr(node, 'b.complex.yes', None)
|
|
|
|
self.assertEqual({'b': {'complex': {}}}, node)
|
|
|
|
|
|
|
|
node_setattr(node, 'b.complex', {None: 5})
|
|
|
|
self.assertEqual({'b': {'complex': {None: 5}}}, node)
|
2018-06-03 02:09:20 +02:00
|
|
|
|
|
|
|
|
|
|
|
class TestRating(unittest.TestCase):
|
|
|
|
def test_hotness(self):
|
|
|
|
"""We expect the sorted values to reflect the original order in the
|
|
|
|
list.
|
|
|
|
"""
|
|
|
|
from datetime import datetime, timezone
|
|
|
|
from pillar.api.utils.rating import hot
|
|
|
|
t = datetime(2017, 2, 11, 0, 0, 0, 0, timezone.utc)
|
|
|
|
y = datetime(2017, 2, 10, 0, 0, 0, 0, timezone.utc)
|
|
|
|
w = datetime(2017, 2, 5, 0, 0, 0, 0, timezone.utc)
|
|
|
|
cases = [
|
|
|
|
(hot(1, 8, t), 'today super bad'),
|
|
|
|
(hot(0, 3, t), 'today slightly worse'),
|
|
|
|
(hot(0, 2, y), 'yesterday bad'),
|
|
|
|
(hot(0, 2, t), 'today bad'),
|
|
|
|
(hot(4, 4, w), 'last week controversial'),
|
|
|
|
(hot(7, 1, w), 'last week very good'),
|
|
|
|
(hot(5, 1, y), 'yesterday medium'),
|
|
|
|
(hot(5, 0, y), 'yesterday good'),
|
|
|
|
(hot(7, 1, y), 'yesterday very good'),
|
|
|
|
(hot(4, 4, t), 'today controversial'),
|
|
|
|
(hot(7, 1, t), 'today very good'),
|
|
|
|
]
|
|
|
|
sorted_by_hot = sorted(cases, key=lambda tup: tup[0])
|
|
|
|
for idx, t in enumerate(sorted_by_hot):
|
|
|
|
self.assertEqual(cases[idx][0], t[0])
|
2018-10-03 18:30:40 +02:00
|
|
|
|
|
|
|
|
|
|
|
class TestPrettyDuration(unittest.TestCase):
|
|
|
|
def test_formatting(self):
|
|
|
|
from pillar.api.utils import pretty_duration
|
|
|
|
pretty_duration(500)
|
2019-05-10 16:28:23 +02:00
|
|
|
self.assertEqual('00:00', pretty_duration(0))
|
|
|
|
self.assertEqual('00:15', pretty_duration(15))
|
|
|
|
self.assertEqual('01:05', pretty_duration(65))
|
|
|
|
self.assertEqual('42:53', pretty_duration(2573))
|
|
|
|
self.assertEqual('01:11:22', pretty_duration(4282))
|
|
|
|
self.assertEqual('01:41', pretty_duration(100.85))
|
|
|
|
self.assertEqual('25:00:00', pretty_duration(90000)) # More than a day
|
|
|
|
self.assertEqual('', pretty_duration(None))
|