aboutsummaryrefslogtreecommitdiffstats
path: root/mediagoblin
diff options
context:
space:
mode:
Diffstat (limited to 'mediagoblin')
-rw-r--r--mediagoblin/db/models.py15
-rw-r--r--mediagoblin/static/css/base.css6
-rw-r--r--mediagoblin/tests/test_tools.py57
-rw-r--r--mediagoblin/tools/pagination.py7
4 files changed, 73 insertions, 12 deletions
diff --git a/mediagoblin/db/models.py b/mediagoblin/db/models.py
index 6448de36..f4644b9f 100644
--- a/mediagoblin/db/models.py
+++ b/mediagoblin/db/models.py
@@ -998,10 +998,17 @@ class Comment(Base):
return self.comment().get_actor # noqa
def __getattr__(self, attr):
+ if attr.startswith('_'):
+ # if attr starts with '_', then it's probably some internal
+ # sqlalchemy variable. Since __getattr__ is called when
+ # non-existing attributes are being accessed, we should not try to
+ # fetch it from self.comment()
+ raise AttributeError
try:
+ _log.debug('Old attr is being accessed: {0}'.format(attr))
return getattr(self.comment(), attr) # noqa
except Exception as e:
- print(e)
+ _log.error(e)
raise
class TextComment(Base, TextCommentMixin, CommentingMixin):
@@ -1155,11 +1162,11 @@ class Collection(Base, CollectionMixin, CommentingMixin):
def get_collection_items(self, ascending=False):
#TODO, is this still needed with self.collection_items being available?
- order_col = MediaEntry.created
+ order_col = CollectionItem.position
if not ascending:
order_col = desc(order_col)
- return CollectionItem.query.join(MediaEntry).filter(
- CollectionItem.collection==self.id).order_by(order_col)
+ return CollectionItem.query.filter_by(
+ collection=self.id).order_by(order_col)
def __repr__(self):
safe_title = self.title.encode('ascii', 'replace')
diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css
index 7852cae9..1628232b 100644
--- a/mediagoblin/static/css/base.css
+++ b/mediagoblin/static/css/base.css
@@ -457,11 +457,9 @@ text-align: center;
}
.form_field_label {
- margin-bottom: 4px;
-}
-
-.form_field_label {
font-size:1.125em;
+ margin-bottom: 0;
+ padding: 10px 0;
}
.form_field_description {
diff --git a/mediagoblin/tests/test_tools.py b/mediagoblin/tests/test_tools.py
index 6d3dd475..5f916400 100644
--- a/mediagoblin/tests/test_tools.py
+++ b/mediagoblin/tests/test_tools.py
@@ -16,10 +16,16 @@
from __future__ import absolute_import, unicode_literals
+try:
+ import mock
+except ImportError:
+ import unittest.mock as mock
+
from werkzeug.wrappers import Request
from werkzeug.test import EnvironBuilder
from mediagoblin.tools.request import decode_request
+from mediagoblin.tools.pagination import Pagination
class TestDecodeRequest(object):
"""Test the decode_request function."""
@@ -59,3 +65,54 @@ class TestDecodeRequest(object):
request.form = {'foo': 'bar'}
data = decode_request(request)
assert data['foo'] == 'bar'
+
+
+class TestPagination(object):
+ def _create_paginator(self, num_items, page, per_page):
+ """Create a Paginator with a mock database cursor."""
+ mock_cursor = mock.MagicMock()
+ mock_cursor.count.return_value = num_items
+ return Pagination(page, mock_cursor, per_page)
+
+ def test_creates_valid_page_url_from_explicit_base_url(self):
+ """Check that test_page_url_explicit runs.
+
+ This is a regression test for a Python 2/3 compatibility fix.
+
+ """
+ paginator = self._create_paginator(num_items=1, page=1, per_page=30)
+ url = paginator.get_page_url_explicit('http://example.com', [], 1)
+ assert url == 'http://example.com?page=1'
+
+ def test_iter_pages_handles_single_page(self):
+ """Check that iter_pages produces the expected result for single page.
+
+ This is a regression test for a Python 2/3 compatibility fix.
+
+ """
+ paginator = self._create_paginator(num_items=1, page=1, per_page=30)
+ assert list(paginator.iter_pages()) == [1]
+
+ def test_zero_items(self):
+ """Check that no items produces no pages."""
+ paginator = self._create_paginator(num_items=0, page=1, per_page=30)
+ assert paginator.total_count == 0
+ assert paginator.pages == 0
+
+ def test_single_item(self):
+ """Check that one item produces one page."""
+ paginator = self._create_paginator(num_items=1, page=1, per_page=30)
+ assert paginator.total_count == 1
+ assert paginator.pages == 1
+
+ def test_full_page(self):
+ """Check that a full page of items produces one page."""
+ paginator = self._create_paginator(num_items=30, page=1, per_page=30)
+ assert paginator.total_count == 30
+ assert paginator.pages == 1
+
+ def test_multiple_pages(self):
+ """Check that more than a full page produces two pages."""
+ paginator = self._create_paginator(num_items=31, page=1, per_page=30)
+ assert paginator.total_count == 31
+ assert paginator.pages == 2
diff --git a/mediagoblin/tools/pagination.py b/mediagoblin/tools/pagination.py
index a525caf7..db5f69fb 100644
--- a/mediagoblin/tools/pagination.py
+++ b/mediagoblin/tools/pagination.py
@@ -14,13 +14,12 @@
# 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/>.
-import urllib
import copy
from math import ceil, floor
from itertools import count
from werkzeug.datastructures import MultiDict
-from six.moves import zip
+from six.moves import range, urllib, zip
PAGINATION_DEFAULT_PER_PAGE = 30
@@ -86,7 +85,7 @@ class Pagination(object):
def iter_pages(self, left_edge=2, left_current=2,
right_current=5, right_edge=2):
last = 0
- for num in xrange(1, self.pages + 1):
+ for num in range(1, self.pages + 1):
if num <= left_edge or \
(num > self.page - left_current - 1 and \
num < self.page + right_current) or \
@@ -107,7 +106,7 @@ class Pagination(object):
new_get_params['page'] = page_no
return "%s?%s" % (
- base_url, urllib.urlencode(new_get_params))
+ base_url, urllib.parse.urlencode(new_get_params))
def get_page_url(self, request, page_no):
"""