Skip to content

Commit

Permalink
Merge pull request #1077 from rafalp/0.19.x
Browse files Browse the repository at this point in the history
0.19.1
  • Loading branch information
rafalp committed Aug 28, 2018
2 parents a81c500 + 6c25ada commit cf03f6d
Show file tree
Hide file tree
Showing 13 changed files with 91 additions and 48 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,9 @@ db.sqlite3
# Local development files
/avatargallery/
/avatar_store/
/manage.py
/devproject/
/testproject/
/media/
/static/
/userdata/
/manage.py
11 changes: 6 additions & 5 deletions initdev
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ python setup.py develop
rm -f /srv/misago/.DS_Store
rm -f /srv/misago/Thumbs.db

# If user specified "--f", clear after previous devinit
if [ "$1" = "--f" ]
# If user specified "-f", clear after previous devinit
if [ "$1" = "-f" ]
then
echo "Cleaned files created by previous initdev"
rm -f /srv/misago/cron.txt
Expand All @@ -17,6 +17,7 @@ then
rm -rf /srv/misago/media
rm -rf /srv/misago/static
rm -rf /srv/misago/theme
rm -rf /srv/misago/userdata
fi

# Create new project
Expand Down Expand Up @@ -48,10 +49,10 @@ echo " - python: can't open file 'manage.py': [Errno 2] No such file or directo
echo ""
echo "If you are experiencing either of those errors, this means that files are"
echo "present in the repository's main directory preventing 'initdev' from succedding."
echo "Please try running the 'initdev' with \"--f\" option to force old files deletion:"
echo "Please try running the 'initdev' with \"-f\" option to force old files deletion:"
echo ""
echo " docker-compose run --rm misago initdev --f"
echo " docker-compose run --rm misago initdev -f"
echo ""
echo -e "${RED}Warning:${DEFAULT} if you have uncommited changes to Misago's setup that should be included"
echo "in next release, make sure that they are commited to 'misago/project_template'"
echo "or 'initdev --f' will overwrite the files causing them to be lost."
echo "or 'initdev -f' will overwrite the files causing them to be lost."
2 changes: 1 addition & 1 deletion misago/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.19.0'
__version__ = '0.19.1'
8 changes: 6 additions & 2 deletions misago/core/templatetags/misago_absoluteurl.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from django import template
from django.urls import reverse
from django.urls import NoReverseMatch, reverse

from misago.conf import settings

Expand All @@ -13,7 +13,11 @@ def absoluteurl(url_or_name, *args, **kwargs):

absolute_url_prefix = settings.MISAGO_ADDRESS.rstrip('/')

if '/' not in url_or_name:
try:
url_or_name = reverse(url_or_name, args=args, kwargs=kwargs)
except NoReverseMatch:
# don't use URLValidator because its too explicit
if not url_or_name.startswith('/'):
return url_or_name

return u'{}{}'.format(absolute_url_prefix, url_or_name)
9 changes: 8 additions & 1 deletion misago/core/tests/test_templatetags.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,18 @@ def test_prefix_url(self):


@override_settings(MISAGO_ADDRESS=TEST_ADDRESS)
def test_rprefix_url_name(self):
def test_prefix_url_name(self):
"""template tag reverses url name and prefixes it"""
result = absoluteurl('misago:index')
self.assertEqual(result, TEST_ADDRESS)

@override_settings(MISAGO_ADDRESS=TEST_ADDRESS)
def test_dont_change_absolute_url(self):
"""template tag doesn't change already absolute urls"""
absolute_url = "https://github.com/rafalp/Misago/issues/1067"
result = absoluteurl(absolute_url)
self.assertEqual(result, absolute_url)


class CaptureTests(TestCase):
def setUp(self):
Expand Down
25 changes: 19 additions & 6 deletions misago/legal/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,14 @@ def test_agreement_text(self):

class GetRequiredUserAgreementTests(UserTestCase):
def setUp(self):
Agreement.objects.invalidate_cache()

self.agreement = Agreement.objects.create(
type=Agreement.TYPE_PRIVACY,
link='https://somewhre.com',
text='Lorem ipsum',
is_active=True,
)

self.agreements = Agreement.objects.get_agreements()

def tearDown(self):
Agreement.objects.invalidate_cache()
self.agreements = Agreement.objects.get_agreements_from_db()

def test_anonymous_user(self):
anonymous_user = self.get_anonymous_user()
Expand All @@ -88,6 +83,24 @@ def test_authenticated_user_with_agreement(self):
result = get_required_user_agreement(authenticated_user, self.agreements)
self.assertIsNone(result)

def test_prioritize_terms_of_service(self):
terms_of_service = Agreement.objects.create(
type=Agreement.TYPE_TOS,
link='https://somewhre.com',
text='Lorem ipsum',
is_active=True,
)

agreements = Agreement.objects.get_agreements_from_db()
agreements_in_wrong_order = {
Agreement.TYPE_PRIVACY: agreements[Agreement.TYPE_PRIVACY],
Agreement.TYPE_TOS: agreements[Agreement.TYPE_TOS],
}

authenticated_user = self.get_authenticated_user()
result = get_required_user_agreement(authenticated_user, agreements_in_wrong_order)
self.assertEqual(result, terms_of_service)


class SaveUserAgreementAcceptance(UserTestCase):
def test_no_commit(self):
Expand Down
5 changes: 3 additions & 2 deletions misago/legal/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ def get_required_user_agreement(user, agreements):
if user.is_anonymous:
return None

for agreement in agreements.values():
if agreement['id'] not in user.agreements:
for agreement_type, _ in Agreement.TYPE_CHOICES:
agreement = agreements.get(agreement_type)
if agreement and agreement['id'] not in user.agreements:
try:
return Agreement.objects.get(id=agreement['id'])
except Agreement.DoesNotExist:
Expand Down
20 changes: 10 additions & 10 deletions misago/users/avatars/store.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ def normalize_image(image):
return image.copy().convert('RGBA')


def delete_avatar(user):
if user.avatar_tmp:
user.avatar_tmp.delete(False)
def delete_avatar(user, delete_tmp=True, delete_src=True):
if delete_tmp and user.avatar_tmp:
user.avatar_tmp.delete(save=False)

if user.avatar_src:
user.avatar_src.delete(False)
if delete_src and user.avatar_src:
user.avatar_src.delete(save=False)

for avatar in user.avatar_set.all():
avatar.image.delete(False)
avatar.image.delete(save=False)
user.avatar_set.all().delete()


Expand All @@ -51,8 +51,8 @@ def store_avatar(user, image):
user.save(update_fields=['avatars'])


def store_new_avatar(user, image):
delete_avatar(user)
def store_new_avatar(user, image, delete_tmp=True, delete_src=True):
delete_avatar(user, delete_tmp=delete_tmp, delete_src=delete_src)
store_avatar(user, image)


Expand All @@ -63,15 +63,15 @@ def store_temporary_avatar(user, image):
image.save(image_stream, "PNG")

if user.avatar_tmp:
user.avatar_tmp.delete(False)
user.avatar_tmp.delete(save=False)

user.avatar_tmp = ContentFile(image_stream.getvalue(), 'avatar')
user.save(update_fields=['avatar_tmp'])


def store_original_avatar(user):
if user.avatar_src:
user.avatar_src.delete(False)
user.avatar_src.delete(save=False)
user.avatar_src = user.avatar_tmp
user.avatar_tmp = None
user.save(update_fields=['avatar_tmp', 'avatar_src'])
Expand Down
4 changes: 3 additions & 1 deletion misago/users/avatars/uploaded.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,11 @@ def crop_source_image(user, source, crop):
int(round((crop['y'] - min_size) * upscale * -1, 0)),
))

store.store_avatar(user, cropped_image)
if source == 'tmp':
store.store_new_avatar(user, cropped_image, delete_tmp=False)
store.store_original_avatar(user)
else:
store.store_new_avatar(user, cropped_image, delete_src=False)

return crop

Expand Down
15 changes: 3 additions & 12 deletions misago/users/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from django.contrib.postgres.fields import ArrayField, HStoreField, JSONField
from django.core.mail import send_mail
from django.db import IntegrityError, models, transaction
from django.db.models import Q
from django.urls import reverse
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
Expand Down Expand Up @@ -130,17 +129,9 @@ def get_by_email(self, email):
return self.get(email_hash=hash_email(email))

def get_by_username_or_email(self, login):
email_hash = hash_email(login)
slug = slugify(login)

users = list(self.filter(Q(slug=slug) | Q(email_hash=email_hash)))
for user in users:
if user.email_hash == email_hash:
return user
for user in users:
if user.slug == slug:
return user
raise User.DoesNotExist()
if '@' in login:
return self.get(email_hash=hash_email(login))
return self.get(slug=slugify(login))


class User(AbstractBaseUser, PermissionsMixin):
Expand Down
14 changes: 13 additions & 1 deletion misago/users/tests/test_auth_views.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
from django.test import TestCase
from django.urls import reverse

Expand Down Expand Up @@ -56,7 +57,18 @@ def test_login_view_redirect_to(self):
response = self.client.post(
reverse('misago:login'),
data={
'redirect_to': 'canada goose not url',
'redirect_to': 'canada goose not url!',
},
)

self.assertEqual(response.status_code, 302)
self.assertEqual(response['location'], '/')

# invalid redirect (unicode)
response = self.client.post(
reverse('misago:login'),
data={
'redirect_to': u'łelcome!',
},
)

Expand Down
17 changes: 14 additions & 3 deletions misago/users/tests/test_user_avatar_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from django.contrib.auth import get_user_model

from misago.acl.testutils import override_acl
from misago.conf import settings
from misago.users.avatars import gallery, store
from misago.users.models import AvatarGallery
from misago.users.testutils import AuthenticatedUserTestCase
Expand All @@ -23,10 +24,16 @@ class UserAvatarTests(AuthenticatedUserTestCase):
def setUp(self):
super(UserAvatarTests, self).setUp()
self.link = '/api/users/%s/avatar/' % self.user.pk
self.client.post(self.link, data={'avatar': 'generated'})

def get_current_user(self):
return UserModel.objects.get(pk=self.user.pk)

def assertOldAvatarsAreDeleted(self, user):
self.assertEqual(
user.avatar_set.count(), len(settings.MISAGO_AVATARS_SIZES)
)

def test_avatars_off(self):
"""custom avatars are not allowed"""
with self.settings(allow_custom_avatars=False):
Expand Down Expand Up @@ -109,16 +116,17 @@ def test_successful_gravatar_request(self):
response = self.client.post(self.link, data={'avatar': 'gravatar'})
self.assertContains(response, "Gravatar was downloaded and set")

self.assertOldAvatarsAreDeleted(self.user)

def test_generation_request(self):
"""generated avatar is set"""
response = self.client.post(self.link, data={'avatar': 'generated'})
self.assertContains(response, "New avatar based on your account")

self.assertOldAvatarsAreDeleted(self.user)

def test_avatar_upload_and_crop(self):
"""avatar can be uploaded and cropped"""
response = self.client.post(self.link, data={'avatar': 'generated'})
self.assertEqual(response.status_code, 200)

response = self.client.post(self.link, data={'avatar': 'upload'})
self.assertContains(response, "No file was sent.", status_code=400)

Expand Down Expand Up @@ -156,6 +164,7 @@ def test_avatar_upload_and_crop(self):
self.assertContains(response, "Uploaded avatar was set.")

self.assertFalse(self.get_current_user().avatar_tmp)
self.assertOldAvatarsAreDeleted(self.user)

avatar = Path(self.get_current_user().avatar_src.path)
self.assertTrue(avatar.exists())
Expand Down Expand Up @@ -192,6 +201,7 @@ def test_avatar_upload_and_crop(self):
content_type="application/json",
)
self.assertContains(response, "Avatar was re-cropped.")
self.assertOldAvatarsAreDeleted(self.user)

# delete user avatars, test if it deletes src and tmp
store.delete_avatar(self.get_current_user())
Expand Down Expand Up @@ -280,6 +290,7 @@ def test_gallery_set_valid_avatar(self):
)

self.assertContains(response, "Avatar from gallery was set.")
self.assertOldAvatarsAreDeleted(self.user)


class UserAvatarModerationTests(AuthenticatedUserTestCase):
Expand Down
6 changes: 3 additions & 3 deletions misago/users/views/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ def login(request):
if is_redirect_safe:
redirect_to_path = urlparse(redirect_to).path
if '?' not in redirect_to_path:
redirect_to_path = '{}?'.format(redirect_to_path)
redirect_to_path = u'{}?'.format(redirect_to_path)
else:
redirect_to_path = '{}&'.format(redirect_to_path)
redirect_to_path = '{}ref=login'.format(redirect_to_path)
redirect_to_path = u'{}&'.format(redirect_to_path)
redirect_to_path = u'{}ref=login'.format(redirect_to_path)
try:
return redirect(redirect_to_path)
except NoReverseMatch:
Expand Down

0 comments on commit cf03f6d

Please sign in to comment.