Skip to content

Commit

Permalink
Added basic model validation for EmailAddress model #130
Browse files Browse the repository at this point in the history
  • Loading branch information
nemesifier committed Sep 7, 2014
1 parent 57dde59 commit 6832d3e
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 12 deletions.
8 changes: 6 additions & 2 deletions nodeshot/community/profiles/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ class UserAdmin(BaseUserAdmin):
ordering = ['-is_staff', '-date_joined']
search_fields = ('email', 'username', 'first_name', 'last_name')
list_filter = ('is_active', 'is_staff', 'is_superuser')

if EMAIL_CONFIRMATION:
readonly_fields = ['email']

form = UserChangeForm
add_form = UserCreationForm
Expand Down Expand Up @@ -107,7 +110,9 @@ class PasswordResetAdmin(admin.ModelAdmin):
from .models import EmailAddress, EmailConfirmation

class EmailAddressAdmin(admin.ModelAdmin):
list_display = ('__unicode__', 'verified', 'primary')
search_fields = ('email', 'user__username')
list_select_related = True
list_display = ('__unicode__', 'verified', 'primary', 'user')

class EmailConfirmationAdmin(admin.ModelAdmin):
list_display = ('__unicode__', 'key_expired')
Expand All @@ -120,4 +125,3 @@ class EmailAddressInline(admin.StackedInline):
extra = 0

UserAdmin.inlines = [EmailAddressInline] + UserAdmin.inlines
UserAdmin.fieldsets[1][1]['fields'].remove('email')
15 changes: 15 additions & 0 deletions nodeshot/community/profiles/models/emailconfirmation.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from django.db import models, IntegrityError
from django.core.mail import send_mail
from django.core.urlresolvers import reverse, NoReverseMatch
from django.core.exceptions import ValidationError
from django.template.loader import render_to_string
from django.utils.translation import gettext_lazy as _
from django.utils import timezone
Expand Down Expand Up @@ -64,6 +65,20 @@ class EmailAddress(models.Model):
primary = models.BooleanField(default=False)

objects = EmailAddressManager()

def clean(self):
try:
if self.pk and not self.primary and EmailAddress.objects.filter(user=self.user, primary=True).first().pk == self.pk:
raise ValidationError(_("You must have at least one primary email address."))
except IndexError:
pass

def save(self, *args, **kwargs):
# if this is not the only primary email address for this user
if self.primary and EmailAddress.objects.filter(user=self.user, primary=True).exclude(pk=self.pk).count() > 0:
# ensure there's only 1 primary address
self.set_as_primary()
super(EmailAddress, self).save(*args, **kwargs)

def set_as_primary(self):
old_primary = EmailAddress.objects.get_primary(self.user)
Expand Down
40 changes: 30 additions & 10 deletions nodeshot/community/profiles/tests.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
"""
ndoeshot.contrib.profiles tests
"""

import simplejson as json

from django.test import TestCase
Expand All @@ -15,7 +11,6 @@
from .settings import settings, EMAIL_CONFIRMATION

if EMAIL_CONFIRMATION:
from nodeshot.core.nodes.models import Node
from .models import EmailAddress, EmailConfirmation

from .models import Profile as User
Expand All @@ -28,18 +23,16 @@ class ProfilesTest(TestCase):
'test_profiles.json',
'test_layers.json',
'test_status.json',
'test_nodes.json',
]

def setUp(self):
self.fusolab = Node.objects.get(slug='fusolab')
self.client.login(username='registered', password='tester')
mail.outbox = []

def test_new_users_have_default_group(self):
""" users should have a default group when created """
# ensure owner of node fusolab has at least one group
self.assertEqual(self.fusolab.user.groups.count(), 1)
self.assertEqual(User.objects.get(username='romano').groups.count(), 1)

# create new user and check if it has any group
new_user = User(username='new_user_test', email='new_user@testing.com', password='tester', is_active=True)
Expand Down Expand Up @@ -354,11 +347,11 @@ def test_account_password_reset_API_regression(self):
self.client.logout()

user = User.objects.get(username='registered')

if EMAIL_CONFIRMATION:
email_address = EmailAddress(user=user, email=user.email, verified=True, primary=True)
email_address.save()

response = self.client.post(url, { 'email': user.email }, HTTP_ACCEPT='text/html')
self.assertEqual(200, response.status_code)

Expand Down Expand Up @@ -603,3 +596,30 @@ def test_password_confirmation_field_in_html(self):
def test_delete_user(self):
User.objects.all().delete()
self.assertEqual(User.objects.count(), 0)

def test_email_address_primary(self):
user = User.objects.get(username='registered')

email_address = EmailAddress(user=user, email=user.email, verified=True, primary=True)
email_address.full_clean()
email_address.save()
self.assertEqual(EmailAddress.objects.count(), 1)

email_address2 = EmailAddress(user=user, email='test@test.com', verified=True, primary=True)
email_address2.full_clean()
email_address2.save()
self.assertEqual(EmailAddress.objects.count(), 2)
self.assertEqual(EmailAddress.objects.filter(user=user, primary=True).count(), 1)
self.assertEqual(EmailAddress.objects.filter(user=user, primary=True).first().email, 'test@test.com')
self.assertEqual(User.objects.get(username='registered').email, 'test@test.com')

def test_email_address_remove_primary(self):
user = User.objects.get(username='registered')

email_address = EmailAddress(user=user, email=user.email, verified=True, primary=True)
email_address.full_clean()
email_address.save()

email_address.primary = False
with self.assertRaises(ValidationError):
email_address.full_clean()

0 comments on commit 6832d3e

Please sign in to comment.