Skip to content

Commit

Permalink
Creates an update view and generation of a request action key
Browse files Browse the repository at this point in the history
  • Loading branch information
dirtycoder committed Dec 11, 2016
1 parent 68163af commit 90d198f
Show file tree
Hide file tree
Showing 9 changed files with 116 additions and 13 deletions.
4 changes: 3 additions & 1 deletion pets/common/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ class AboutPageView(TemplateView):


def not_found(request):
return render(request, 'staticpages/404.html')
response = render(request, 'staticpages/404.html')
response.status_code = 404
return response


def home(request):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ class Migration(migrations.Migration):
name='active',
field=models.BooleanField(default=True),
),
migrations.AddField(
model_name='pet',
name='request_key',
field=models.CharField(blank=True, max_length=40),
),
migrations.AddField(
model_name='pet',
name='request_sent',
Expand All @@ -25,7 +30,7 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='pet',
name='created',
field=django_extensions.db.fields.CreationDateTimeField(verbose_name='created', auto_now_add=True),
field=django_extensions.db.fields.CreationDateTimeField(auto_now_add=True, verbose_name='created'),
),
migrations.AlterField(
model_name='pet',
Expand All @@ -40,12 +45,12 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='pet',
name='sex',
field=models.CharField(blank=True, choices=[('FE', 'Female'), ('MA', 'Male')], max_length=2),
field=models.CharField(choices=[('FE', 'Female'), ('MA', 'Male')], blank=True, max_length=2),
),
migrations.AlterField(
model_name='pet',
name='size',
field=models.CharField(blank=True, choices=[('SM', 'Small'), ('MD', 'Medium'), ('LG', 'Large')], max_length=2),
field=models.CharField(choices=[('SM', 'Small'), ('MD', 'Medium'), ('LG', 'Large')], blank=True, max_length=2),
),
migrations.AlterField(
model_name='pet',
Expand Down
23 changes: 18 additions & 5 deletions pets/meupet/models.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import hashlib

from django.conf import settings
from django.core.urlresolvers import reverse
from django.db import models
from django.utils import timezone
from django.utils import timezone, crypto
from django.utils.text import slugify
from django.utils.translation import ugettext, ugettext_lazy as _

from autoslug import AutoSlugField
from django_extensions.db.models import TimeStampedModel

from users.models import OwnerProfile
from meupet import services
from users.models import OwnerProfile


class PetManager(models.Manager):
Expand All @@ -32,12 +35,12 @@ def get_staled_pets(self):
Pets considered as staled are not modified after a given
number of days and don't have a request_sent date
"""
stale_date = timezone.now() - timezone.timedelta(days=90)
stale_date = timezone.now() - timezone.timedelta(days=settings.DAYS_TO_STALE_REGISTER)
return self.filter(modified__lt=stale_date, request_sent__isnull=True)

def get_expired_pets(self):
"""Expired pets have request_sent date older than expected"""
expire_date = timezone.now() - timezone.timedelta(days=90)
expire_date = timezone.now() - timezone.timedelta(days=settings.DAYS_TO_STALE_REGISTER)
return self.filter(request_sent__lt=expire_date)


Expand Down Expand Up @@ -122,6 +125,7 @@ class Pet(TimeStampedModel):
help_text=ugettext('Maximum image size is 8MB'))
published = models.BooleanField(default=False) # published on facebook
request_sent = models.DateTimeField(null=True, blank=True)
request_key = models.CharField(blank=True, max_length=40)
active = models.BooleanField(default=True)
slug = AutoSlugField(max_length=50, populate_from=get_slug, unique=True)

Expand Down Expand Up @@ -150,15 +154,24 @@ def get_size(self):
return dict(self.PET_SIZE).get(self.size)

def request_action(self):
hash_input = (crypto.get_random_string(5) + self.name).encode('utf-8')
self.request_key = hashlib.sha1(hash_input).hexdigest()

if not services.send_request_action_email(self):
return

self.request_sent = timezone.now()
self.save(update_modified=False)

def activate(self):
self.request_sent = None
self.request_key = ''
self.active = True
self.save()

def deactivate(self):
self.active = False
self.save()
self.save(update_modified=False)

def __str__(self):
return self.name
Expand Down
5 changes: 4 additions & 1 deletion pets/meupet/services.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.conf import settings
from django.core import mail
from django.core.urlresolvers import reverse
from django.template.loader import render_to_string
from django.utils.translation import ugettext as _

Expand All @@ -20,7 +21,9 @@ def send_request_action_email(pet):
'username': pet.owner.first_name,
'pet': pet.name,
'days': settings.DAYS_TO_STALE_REGISTER,
'status': pet.get_status_display()
'status': pet.get_status_display(),
# ToDO: use full url
'link': reverse('meupet:update_register', args=[pet.request_key]),
}

return send_email(subject, to, template_name, context)
44 changes: 42 additions & 2 deletions pets/meupet/tests/test_model_pet.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from unittest import mock

from django.core import mail
from django.conf import settings
from django.test import TestCase
from django.utils import timezone
from django.core.urlresolvers import reverse

from model_mommy import mommy

Expand Down Expand Up @@ -63,6 +66,7 @@ def test_request_action_from_user(self):
pet.name,
pet.owner.first_name,
str(settings.DAYS_TO_STALE_REGISTER),
reverse('meupet:update_register', args=[pet.request_key]),
pet.get_status_display()
]

Expand All @@ -71,23 +75,59 @@ def test_request_action_from_user(self):
self.assertIn(expected, email.body)

def test_request_sent_saved(self):
"""Should set the request_sent date in the pet"""
"""Should set the request_sent date in the pet and keep modified date"""
pet = mommy.make(Pet)
modified = pet.modified

pet.request_action()
pet.refresh_from_db()

self.assertIsNotNone(pet.request_sent)
self.assertEqual(modified, pet.modified)
self.assertAlmostEqual(pet.request_sent, timezone.now(), delta=timezone.timedelta(seconds=1))

def test_request_action_email_set_activation_success(self):
"""Should set the request_key if the request_action_email succeed"""
pet = mommy.make(Pet, request_key='')

pet.request_action()
pet.refresh_from_db()

self.assertNotEqual('', pet.request_key)

def test_request_action_email_not_set_activation_fail(self):
"""Shouldn't set the request_key if the request_action_email fail"""
pet = mommy.make(Pet, request_key='')

with mock.patch('meupet.services.send_request_action_email') as mock_method:
mock_method.return_value = False
pet.request_action()

pet.refresh_from_db()

self.assertEqual('', pet.request_key)

def test_deactivate(self):
"""Should set the registration as inactive"""
"""Should set the registration as inactive and keep modified date"""
pet = mommy.make(Pet)
modified = pet.modified

pet.deactivate()
pet.refresh_from_db()

self.assertFalse(pet.active)
self.assertEqual(modified, pet.modified)

def test_activate(self):
"""Should set the registration to active and clear fields"""
pet = mommy.make(Pet, active=False, request_key='abc', request_sent=timezone.now())

pet.activate()
pet.refresh_from_db()

self.assertIsNone(pet.request_sent)
self.assertEqual('', pet.request_key)
self.assertTrue(pet.active)

@staticmethod
def create_pet_custom_date(modified_days, request_sent_days=None):
Expand Down
2 changes: 1 addition & 1 deletion pets/meupet/tests/test_view_pet_detail.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ def test_show_404_not_found(self):
"""Show the default 404 page if the pet could not be found"""
resp = self.client.get(reverse('meupet:detail', kwargs={'pk_or_slug': '404-pet'}))

self.assertContains(resp, 'Página não encontrada')
self.assertContains(resp, 'Página não encontrada', status_code=404)
33 changes: 33 additions & 0 deletions pets/meupet/tests/test_view_update_register.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from django.core.urlresolvers import reverse
from django.test import TestCase
from django.utils import timezone

from model_mommy import mommy

from meupet.models import Pet


class UpdateRegisterViewTest(TestCase):
def setUp(self):
stale_date = timezone.now() - timezone.timedelta(days=90)
self.pet = mommy.make(Pet, request_sent=stale_date, active=False, request_key='abc')

def test_redirect_to_pet(self):
"""Redirect to the detail view after updating the registration"""
resp = self.client.get(reverse('meupet:update_register', args=[self.pet.request_key]))

self.assertRedirects(resp, reverse('meupet:detail', args=[self.pet.slug]))

def test_not_found(self):
"""Shows 404 if pet not found with given request_key"""
resp = self.client.get(reverse('meupet:update_register', args=['cba']), follow=True)

self.assertEqual(404, resp.status_code)

def test_update_pet_registration(self):
"""Should set the registration as active"""
self.client.get(reverse('meupet:update_register', args=[self.pet.request_key]))

self.pet.refresh_from_db()

self.assertTrue(self.pet.active)
1 change: 1 addition & 0 deletions pets/meupet/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
url(r'^desaparecidos/(?P<kind>[-\w]*)/$', views.lost_pets, name='lost'),
url(r'^para-adocao/(?P<kind>[-\w]*)/$', views.adoption_pets, name='adoption'),
url(r'^busca/$', views.SearchView.as_view(), name='search'),
url(r'^atualizar-cadastro/(?P<request_key>\w+)/$', views.update_register, name='update_register'),
url(r'^pet/(?P<slug>[-\w]*)/foto/$', views.upload_image, name='upload_image'),
url(r'^(?P<slug>[-\w]*)/editar/$', views.EditPetView.as_view(), name='edit'),
url(r'^(?P<slug>[-\w]*)/poster/$', views.poster, name='poster'),
Expand Down
6 changes: 6 additions & 0 deletions pets/meupet/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,3 +193,9 @@ def registered(request, slug):
def poster(request, slug):
pet = get_object_or_404(models.Pet, slug=slug)
return render(request, 'meupet/poster.html', {'pet': pet})


def update_register(request, request_key):
pet = get_object_or_404(models.Pet, request_key=request_key)
pet.activate()
return HttpResponseRedirect(pet.get_absolute_url())

0 comments on commit 90d198f

Please sign in to comment.