Revamped tests and added Travis config.
2
.gitignore
vendored
|
|
@ -6,3 +6,5 @@ pip-log.txt
|
|||
*~
|
||||
dist/
|
||||
*.egg-info/
|
||||
avatars
|
||||
.coverage
|
||||
21
.travis.yml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
language: python
|
||||
python:
|
||||
- 2.6
|
||||
- 2.7
|
||||
- 3.2
|
||||
- 3.3
|
||||
install:
|
||||
- pip install -e .
|
||||
- pip install -r tests/requirements.txt
|
||||
- pip install https://github.com/django/django/archive/${DJANGO}.zip#egg=django
|
||||
script: make test
|
||||
env:
|
||||
- DJANGO=1.4.5
|
||||
- DJANGO=1.5.1
|
||||
- DJANGO=stable/1.6.x
|
||||
matrix:
|
||||
exclude:
|
||||
- python: 3.2
|
||||
env: DJANGO=1.4.5
|
||||
- python: 3.3
|
||||
env: DJANGO=1.4.5
|
||||
|
|
@ -3,6 +3,6 @@ include LICENSE.txt
|
|||
include CONTRIBUTORS.txt
|
||||
include avatar/media/avatar/img/default.jpg
|
||||
recursive-include docs *
|
||||
recursive-include tests *
|
||||
recursive-include avatar/templates *.html *.txt
|
||||
recursive-include avatar/locale/*/LC_MESSAGES *.mo *.po
|
||||
recursive-include avatar/testdata *
|
||||
|
|
|
|||
9
Makefile
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
export DJANGO_SETTINGS_MODULE=tests.settings
|
||||
export PYTHONPATH=.
|
||||
|
||||
.PHONY: test
|
||||
|
||||
test:
|
||||
flake8 avatar --ignore=E124,E501,E127,E128
|
||||
coverage run --branch --source=avatar `which django-admin.py` test tests
|
||||
coverage report
|
||||
|
|
@ -3,12 +3,13 @@ from django.utils.translation import ugettext_lazy as _
|
|||
|
||||
from avatar.models import Avatar
|
||||
from avatar.templatetags.avatar_tags import avatar
|
||||
from avatar.util import User
|
||||
from avatar.util import get_user_model
|
||||
|
||||
|
||||
class AvatarAdmin(admin.ModelAdmin):
|
||||
list_display = ('get_avatar', 'user', 'primary', "date_uploaded")
|
||||
list_filter = ('primary',)
|
||||
search_fields = ('user__%s' % getattr(User, 'USERNAME_FIELD', 'username'),)
|
||||
search_fields = ('user__%s' % getattr(get_user_model(), 'USERNAME_FIELD', 'username'),)
|
||||
list_per_page = 50
|
||||
|
||||
def get_avatar(self, avatar_in):
|
||||
|
|
|
|||
|
|
@ -14,9 +14,10 @@ from avatar.settings import (AVATAR_MAX_AVATARS_PER_USER, AVATAR_MAX_SIZE,
|
|||
def avatar_img(avatar, size):
|
||||
if not avatar.thumbnail_exists(size):
|
||||
avatar.create_thumbnail(size)
|
||||
return mark_safe("""<img src="%s" alt="%s" width="%s" height="%s" />""" %
|
||||
return mark_safe('<img src="%s" alt="%s" width="%s" height="%s" />' %
|
||||
(avatar.avatar_url(size), unicode(avatar), size, size))
|
||||
|
||||
|
||||
class UploadAvatarForm(forms.Form):
|
||||
|
||||
avatar = forms.ImageField(label=_(u"avatar"))
|
||||
|
|
@ -31,25 +32,33 @@ class UploadAvatarForm(forms.Form):
|
|||
(root, ext) = os.path.splitext(data.name.lower())
|
||||
if ext not in AVATAR_ALLOWED_FILE_EXTS:
|
||||
raise forms.ValidationError(
|
||||
_(u"%(ext)s is an invalid file extension. Authorized extensions are : %(valid_exts_list)s") %
|
||||
_("%(ext)s is an invalid file extension. "
|
||||
"Authorized extensions are : %(valid_exts_list)s") %
|
||||
{'ext': ext, 'valid_exts_list': ", ".join(AVATAR_ALLOWED_FILE_EXTS)})
|
||||
if data.size > AVATAR_MAX_SIZE:
|
||||
raise forms.ValidationError(
|
||||
_(u"Your file is too big (%(size)s), the maximum allowed size is %(max_valid_size)s") %
|
||||
{ 'size' : filesizeformat(data.size), 'max_valid_size' : filesizeformat(AVATAR_MAX_SIZE)} )
|
||||
error = _("Your file is too big (%(size)s), "
|
||||
"the maximum allowed size is %(max_valid_size)s")
|
||||
raise forms.ValidationError(error % {
|
||||
'size': filesizeformat(data.size),
|
||||
'max_valid_size': filesizeformat(AVATAR_MAX_SIZE)
|
||||
})
|
||||
|
||||
count = Avatar.objects.filter(user=self.user).count()
|
||||
if AVATAR_MAX_AVATARS_PER_USER > 1 and \
|
||||
count >= AVATAR_MAX_AVATARS_PER_USER:
|
||||
raise forms.ValidationError(
|
||||
_(u"You already have %(nb_avatars)d avatars, and the maximum allowed is %(nb_max_avatars)d.") %
|
||||
{ 'nb_avatars' : count, 'nb_max_avatars' : AVATAR_MAX_AVATARS_PER_USER})
|
||||
if (AVATAR_MAX_AVATARS_PER_USER > 1 and
|
||||
count >= AVATAR_MAX_AVATARS_PER_USER):
|
||||
error = _("You already have %(nb_avatars)d avatars, "
|
||||
"and the maximum allowed is %(nb_max_avatars)d.")
|
||||
raise forms.ValidationError(error % {
|
||||
'nb_avatars': count,
|
||||
'nb_max_avatars': AVATAR_MAX_AVATARS_PER_USER,
|
||||
})
|
||||
return
|
||||
|
||||
|
||||
class PrimaryAvatarForm(forms.Form):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
user = kwargs.pop('user')
|
||||
kwargs.pop('user')
|
||||
size = kwargs.pop('size', AVATAR_DEFAULT_SIZE)
|
||||
avatars = kwargs.pop('avatars')
|
||||
super(PrimaryAvatarForm, self).__init__(*args, **kwargs)
|
||||
|
|
@ -57,10 +66,11 @@ class PrimaryAvatarForm(forms.Form):
|
|||
choices=[(c.id, avatar_img(c, size)) for c in avatars],
|
||||
widget=widgets.RadioSelect)
|
||||
|
||||
|
||||
class DeleteAvatarForm(forms.Form):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
user = kwargs.pop('user')
|
||||
kwargs.pop('user')
|
||||
size = kwargs.pop('size', AVATAR_DEFAULT_SIZE)
|
||||
avatars = kwargs.pop('avatars')
|
||||
super(DeleteAvatarForm, self).__init__(*args, **kwargs)
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
|
||||
|
|
@ -3,6 +3,7 @@ from django.core.management.base import NoArgsCommand
|
|||
from avatar.models import Avatar
|
||||
from avatar.settings import AUTO_GENERATE_AVATAR_SIZES
|
||||
|
||||
|
||||
class Command(NoArgsCommand):
|
||||
help = "Regenerates avatar thumbnails for the sizes specified in " + \
|
||||
"settings.AUTO_GENERATE_AVATAR_SIZES."
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import datetime
|
|||
import os
|
||||
import hashlib
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
from django.core.files.base import ContentFile
|
||||
from django.core.files.storage import get_storage_class
|
||||
|
|
@ -9,7 +10,7 @@ from django.utils.translation import ugettext as _
|
|||
from django.utils.encoding import smart_str
|
||||
from django.db.models import signals
|
||||
|
||||
from avatar.util import User, get_username
|
||||
from avatar.util import get_username
|
||||
|
||||
try:
|
||||
from cStringIO import StringIO
|
||||
|
|
@ -76,7 +77,7 @@ def find_extension(format):
|
|||
|
||||
|
||||
class Avatar(models.Model):
|
||||
user = models.ForeignKey(User)
|
||||
user = models.ForeignKey(getattr(settings, 'AUTH_USER_MODEL', 'auth.User'))
|
||||
primary = models.BooleanField(default=False)
|
||||
avatar = models.ImageField(max_length=1024,
|
||||
upload_to=avatar_file_path,
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ from django.core.urlresolvers import reverse
|
|||
|
||||
from avatar.settings import (AVATAR_GRAVATAR_BACKUP, AVATAR_GRAVATAR_DEFAULT,
|
||||
AVATAR_DEFAULT_SIZE, AVATAR_GRAVATAR_BASE_URL)
|
||||
from avatar.util import (
|
||||
get_primary_avatar, get_default_avatar_url, cache_result, User, get_user)
|
||||
from avatar.util import (get_primary_avatar, get_default_avatar_url,
|
||||
cache_result, get_user_model, get_user)
|
||||
from avatar.models import Avatar
|
||||
|
||||
register = template.Library()
|
||||
|
|
@ -37,12 +37,12 @@ def avatar_url(user, size=AVATAR_DEFAULT_SIZE):
|
|||
@cache_result
|
||||
@register.simple_tag
|
||||
def avatar(user, size=AVATAR_DEFAULT_SIZE, **kwargs):
|
||||
if not isinstance(user, User):
|
||||
if not isinstance(user, get_user_model()):
|
||||
try:
|
||||
user = get_user(user)
|
||||
alt = unicode(user)
|
||||
url = avatar_url(user, size)
|
||||
except User.DoesNotExist:
|
||||
except get_user_model().DoesNotExist:
|
||||
url = get_default_avatar_url()
|
||||
alt = _("Default Avatar")
|
||||
else:
|
||||
|
|
@ -59,7 +59,7 @@ def avatar(user, size=AVATAR_DEFAULT_SIZE, **kwargs):
|
|||
|
||||
@register.filter
|
||||
def has_avatar(user):
|
||||
if not isinstance(user, User):
|
||||
if not isinstance(user, get_user_model()):
|
||||
return False
|
||||
return Avatar.objects.filter(user=user, primary=True).exists()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
try:
|
||||
from django.conf.urls import patterns, url
|
||||
except ImportError:
|
||||
from django.conf.urls.defaults import patterns, url
|
||||
|
||||
urlpatterns = patterns(
|
||||
|
|
|
|||
|
|
@ -9,9 +9,12 @@ try:
|
|||
from django.contrib.auth import get_user_model
|
||||
except ImportError:
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
def get_user_model():
|
||||
return User
|
||||
|
||||
custom_user_model = False
|
||||
else:
|
||||
User = get_user_model()
|
||||
custom_user_model = True
|
||||
|
||||
from avatar.settings import (AVATAR_DEFAULT_URL, AVATAR_CACHE_TIMEOUT,
|
||||
|
|
@ -19,6 +22,7 @@ from avatar.settings import (AVATAR_DEFAULT_URL, AVATAR_CACHE_TIMEOUT,
|
|||
|
||||
cached_funcs = set()
|
||||
|
||||
|
||||
def get_username(user):
|
||||
""" Return username of a User instance """
|
||||
if hasattr(user, 'get_username'):
|
||||
|
|
@ -26,19 +30,20 @@ def get_username(user):
|
|||
else:
|
||||
return user.username
|
||||
|
||||
|
||||
def get_user(username):
|
||||
""" Return user from a username/ish identifier """
|
||||
if custom_user_model:
|
||||
return User.objects.get_by_natural_key(username)
|
||||
return get_user_model().objects.get_by_natural_key(username)
|
||||
else:
|
||||
return User.objects.get(username=username)
|
||||
return get_user_model().objects.get(username=username)
|
||||
|
||||
|
||||
def get_cache_key(user_or_username, size, prefix):
|
||||
"""
|
||||
Returns a cache key consisten of a username and image size.
|
||||
"""
|
||||
if isinstance(user_or_username, User):
|
||||
if isinstance(user_or_username, get_user_model()):
|
||||
user_or_username = get_username(user_or_username)
|
||||
key = u'%s_%s_%s' % (prefix, user_or_username, size)
|
||||
return u'%s_%s' % (slugify(key)[:100],
|
||||
|
|
@ -61,6 +66,7 @@ def cache_result(func):
|
|||
return cache.get(key) or cache_set(key, func(user, size))
|
||||
return cached_func
|
||||
|
||||
|
||||
def invalidate_cache(user, size=None):
|
||||
"""
|
||||
Function to be called when saving or changing an user's avatars.
|
||||
|
|
@ -72,6 +78,7 @@ def invalidate_cache(user, size=None):
|
|||
for size in sizes:
|
||||
cache.delete(get_cache_key(user, size, prefix))
|
||||
|
||||
|
||||
def get_default_avatar_url():
|
||||
base_url = getattr(settings, 'STATIC_URL', None)
|
||||
if not base_url:
|
||||
|
|
@ -88,7 +95,9 @@ def get_default_avatar_url():
|
|||
return '%s/%s' % (base_url, AVATAR_DEFAULT_URL)
|
||||
return '%s%s' % (base_url, AVATAR_DEFAULT_URL)
|
||||
|
||||
|
||||
def get_primary_avatar(user, size=AVATAR_DEFAULT_SIZE):
|
||||
User = get_user_model()
|
||||
if not isinstance(user, User):
|
||||
try:
|
||||
user = get_user(user)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
from django.core.files.base import ContentFile
|
||||
from django.http import HttpResponseRedirect, HttpResponse, Http404
|
||||
from django.shortcuts import get_object_or_404, render_to_response
|
||||
from django.template import RequestContext
|
||||
from django.http import HttpResponse, Http404
|
||||
from django.shortcuts import get_object_or_404, render, redirect
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
|
||||
|
|
@ -12,8 +11,8 @@ from avatar.forms import PrimaryAvatarForm, DeleteAvatarForm, UploadAvatarForm
|
|||
from avatar.models import Avatar
|
||||
from avatar.settings import AVATAR_MAX_AVATARS_PER_USER, AVATAR_DEFAULT_SIZE
|
||||
from avatar.signals import avatar_updated
|
||||
from avatar.util import (
|
||||
get_primary_avatar, get_default_avatar_url, User, get_user)
|
||||
from avatar.util import (get_primary_avatar, get_default_avatar_url,
|
||||
get_user_model, get_user)
|
||||
|
||||
|
||||
def _get_next(request):
|
||||
|
|
@ -59,7 +58,7 @@ def _get_avatars(user):
|
|||
@csrf_exempt
|
||||
def webcam_upload(request, id):
|
||||
# TODO: add proper security by attaching session to flash request
|
||||
user = get_object_or_404(User, pk=id)
|
||||
user = get_object_or_404(get_user_model(), pk=id)
|
||||
if request.method == "POST":
|
||||
avatar = Avatar(user=user, primary=True)
|
||||
avatar.avatar.save("%s_webcam_%s.jpg" %
|
||||
|
|
@ -86,18 +85,16 @@ def add(request, extra_context=None, next_override=None,
|
|||
avatar.save()
|
||||
messages.success(request, _("Successfully uploaded a new avatar."))
|
||||
avatar_updated.send(sender=Avatar, user=request.user, avatar=avatar)
|
||||
return HttpResponseRedirect(next_override or _get_next(request))
|
||||
return render_to_response(
|
||||
'avatar/add.html',
|
||||
extra_context,
|
||||
context_instance = RequestContext(
|
||||
request,
|
||||
{ 'avatar': avatar,
|
||||
return redirect(next_override or _get_next(request))
|
||||
context = {
|
||||
'avatar': avatar,
|
||||
'avatars': avatars,
|
||||
'upload_avatar_form': upload_avatar_form,
|
||||
'next': next_override or _get_next(request), }
|
||||
)
|
||||
)
|
||||
'next': next_override or _get_next(request),
|
||||
}
|
||||
context.update(extra_context)
|
||||
return render(request, 'avatar/add.html', context)
|
||||
|
||||
|
||||
@login_required
|
||||
def change(request, extra_context=None, next_override=None,
|
||||
|
|
@ -124,19 +121,18 @@ def change(request, extra_context=None, next_override=None,
|
|||
messages.success(request, _("Successfully updated your avatar."))
|
||||
if updated:
|
||||
avatar_updated.send(sender=Avatar, user=request.user, avatar=avatar)
|
||||
return HttpResponseRedirect(next_override or _get_next(request))
|
||||
return render_to_response(
|
||||
'avatar/change.html',
|
||||
extra_context,
|
||||
context_instance = RequestContext(
|
||||
request,
|
||||
{ 'avatar': avatar,
|
||||
return redirect(next_override or _get_next(request))
|
||||
|
||||
context = {
|
||||
'avatar': avatar,
|
||||
'avatars': avatars,
|
||||
'upload_avatar_form': upload_avatar_form,
|
||||
'primary_avatar_form': primary_avatar_form,
|
||||
'next': next_override or _get_next(request), }
|
||||
)
|
||||
)
|
||||
'next': next_override or _get_next(request)
|
||||
}
|
||||
context.update(extra_context)
|
||||
return render(request, 'avatar/change.html', context)
|
||||
|
||||
|
||||
@login_required
|
||||
def delete(request, extra_context=None, next_override=None, *args, **kwargs):
|
||||
|
|
@ -158,35 +154,33 @@ def delete(request, extra_context=None, next_override=None, *args, **kwargs):
|
|||
break
|
||||
Avatar.objects.filter(id__in=ids).delete()
|
||||
messages.success(request, _("Successfully deleted the requested avatars."))
|
||||
return HttpResponseRedirect(next_override or _get_next(request))
|
||||
return render_to_response(
|
||||
'avatar/confirm_delete.html',
|
||||
extra_context,
|
||||
context_instance = RequestContext(
|
||||
request,
|
||||
{ 'avatar': avatar,
|
||||
return redirect(next_override or _get_next(request))
|
||||
context = {
|
||||
'avatar': avatar,
|
||||
'avatars': avatars,
|
||||
'delete_avatar_form': delete_avatar_form,
|
||||
'next': next_override or _get_next(request), }
|
||||
)
|
||||
)
|
||||
'next': next_override or _get_next(request),
|
||||
}
|
||||
context.update(extra_context)
|
||||
|
||||
return render(request, 'avatar/confirm_delete.html', context)
|
||||
|
||||
|
||||
def avatar_gallery(request, username, template_name="avatar/gallery.html"):
|
||||
try:
|
||||
user = get_user(username)
|
||||
except User.DoesNotExist:
|
||||
except get_user_model().DoesNotExist:
|
||||
raise Http404
|
||||
return render_to_response(template_name, {
|
||||
return render(request, template_name, {
|
||||
"other_user": user,
|
||||
"avatars": user.avatar_set.all(),
|
||||
}, context_instance=RequestContext(request))
|
||||
})
|
||||
|
||||
|
||||
def avatar(request, username, id, template_name="avatar/avatar.html"):
|
||||
try:
|
||||
user = get_user(username)
|
||||
except User.DoesNotExist:
|
||||
except get_user_model().DoesNotExist:
|
||||
raise Http404
|
||||
avatars = user.avatar_set.order_by("-date_uploaded")
|
||||
index = None
|
||||
|
|
@ -217,7 +211,7 @@ def avatar(request, username, id, template_name="avatar/avatar.html"):
|
|||
else:
|
||||
next = avatars[index + 1]
|
||||
|
||||
return render_to_response(template_name, {
|
||||
return render(request, template_name, {
|
||||
"other_user": user,
|
||||
"avatar": avatar,
|
||||
"index": index + 1,
|
||||
|
|
@ -225,7 +219,7 @@ def avatar(request, username, id, template_name="avatar/avatar.html"):
|
|||
"next": next,
|
||||
"prev": prev,
|
||||
"count": count,
|
||||
}, context_instance=RequestContext(request))
|
||||
})
|
||||
|
||||
|
||||
def render_primary(request, extra_context={}, user=None, size=AVATAR_DEFAULT_SIZE, *args, **kwargs):
|
||||
|
|
@ -237,7 +231,6 @@ def render_primary(request, extra_context={}, user=None, size=AVATAR_DEFAULT_SIZ
|
|||
# be useful in certain situations, particulary if there is a CDN and
|
||||
# we want to minimize the storage usage on our static server, letting
|
||||
# the CDN store those files instead
|
||||
return HttpResponseRedirect(avatar.avatar_url(size))
|
||||
return redirect(avatar.avatar_url(size))
|
||||
else:
|
||||
url = get_default_avatar_url()
|
||||
return HttpResponseRedirect(url)
|
||||
return redirect(get_default_avatar_url())
|
||||
|
|
|
|||
0
tests/__init__.py
Normal file
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
3
tests/requirements.txt
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
flake8
|
||||
coverage
|
||||
django-discover-runner
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
ROOT = os.path.abspath(os.path.dirname(__file__))
|
||||
APP_ROOT = os.path.join(ROOT, '..')
|
||||
sys.path.append(APP_ROOT)
|
||||
|
||||
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
# We do this here because settings.py has a tendency to be imported more than
|
||||
# once, in certain situations, and we only want one temporary test folder.
|
||||
MEDIA_ROOT = os.path.join(tempfile.gettempdir(), 'avatars')
|
||||
if not os.path.exists(MEDIA_ROOT):
|
||||
os.makedirs(os.path.join(MEDIA_ROOT, 'test'))
|
||||
settings.MEDIA_ROOT = MEDIA_ROOT
|
||||
|
||||
from django.test.simple import run_tests
|
||||
|
||||
if __name__ == "__main__":
|
||||
failures = run_tests(['avatar'], verbosity=1)
|
||||
if failures:
|
||||
sys.exit(failures)
|
||||
|
|
@ -1,36 +1,36 @@
|
|||
from django.conf.urls.defaults import patterns, include, handler500, handler404
|
||||
|
||||
DEFAULT_CHARSET = 'utf-8'
|
||||
import django
|
||||
|
||||
DATABASE_ENGINE = 'sqlite3'
|
||||
DATABASE_NAME = ':memory:'
|
||||
|
||||
ROOT_URLCONF = 'settings'
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': ':memory:',
|
||||
}
|
||||
}
|
||||
|
||||
STATIC_URL = '/site_media/static/'
|
||||
|
||||
SITE_ID = 1
|
||||
|
||||
INSTALLED_APPS = (
|
||||
INSTALLED_APPS = [
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sites',
|
||||
'django.contrib.comments',
|
||||
'avatar',
|
||||
)
|
||||
]
|
||||
|
||||
TEMPLATE_LOADERS = (
|
||||
'django.template.loaders.app_directories.load_template_source',
|
||||
)
|
||||
ROOT_URLCONF = 'tests.urls'
|
||||
|
||||
SITE_ID = 1
|
||||
|
||||
SECRET_KEY = 'something-something'
|
||||
|
||||
if django.VERSION[:2] < (1, 6):
|
||||
TEST_RUNNER = 'discover_runner.DiscoverRunner'
|
||||
|
||||
ROOT_URLCONF = 'tests.urls'
|
||||
|
||||
STATIC_URL = '/site_media/static/'
|
||||
|
||||
AVATAR_ALLOWED_FILE_EXTS = ('.jpg', '.png')
|
||||
AVATAR_MAX_SIZE = 1024 * 1024
|
||||
AVATAR_MAX_AVATARS_PER_USER = 20
|
||||
|
||||
urlpatterns = patterns('',
|
||||
(r'^avatar/', include('avatar.urls')),
|
||||
)
|
||||
|
||||
def __exported_functionality__():
|
||||
return (handler500, handler404)
|
||||
|
|
|
|||
|
|
@ -5,14 +5,9 @@ from django.core.urlresolvers import reverse
|
|||
from django.conf import settings
|
||||
|
||||
from avatar.settings import AVATAR_DEFAULT_URL, AVATAR_MAX_AVATARS_PER_USER
|
||||
from avatar.util import get_primary_avatar, User
|
||||
from avatar.util import get_primary_avatar, get_user_model
|
||||
from avatar.models import Avatar
|
||||
|
||||
try:
|
||||
from PIL import Image
|
||||
dir(Image) # Placate PyFlakes
|
||||
except ImportError:
|
||||
import Image
|
||||
|
||||
|
||||
def upload_helper(o, filename):
|
||||
|
|
@ -23,11 +18,12 @@ def upload_helper(o, filename):
|
|||
f.close()
|
||||
return response
|
||||
|
||||
|
||||
class AvatarUploadTests(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.testdatapath = os.path.join(os.path.dirname(__file__), "testdata")
|
||||
self.user = User.objects.create_user('test', 'lennon@thebeatles.com', 'testpassword')
|
||||
self.testdatapath = os.path.join(os.path.dirname(__file__), "data")
|
||||
self.user = get_user_model().objects.create_user('test', 'lennon@thebeatles.com', 'testpassword')
|
||||
self.user.save()
|
||||
self.client.login(username='test', password='testpassword')
|
||||
Image.init()
|
||||
|
|
@ -104,7 +100,7 @@ class AvatarUploadTests(TestCase):
|
|||
self.testThereCanBeOnlyOnePrimaryAvatar()
|
||||
primary = get_primary_avatar(self.user)
|
||||
oid = primary.id
|
||||
response = self.client.post(reverse('avatar_delete'), {
|
||||
self.client.post(reverse('avatar_delete'), {
|
||||
'choices': [oid],
|
||||
})
|
||||
primaries = Avatar.objects.filter(user=self.user, primary=True)
|
||||
9
tests/urls.py
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
try:
|
||||
from django.conf.urls import patterns, include
|
||||
except ImportError:
|
||||
from django.conf.urls.defaults import patterns, include
|
||||
|
||||
|
||||
urlpatterns = patterns('',
|
||||
(r'^avatar/', include('avatar.urls')),
|
||||
)
|
||||