mirror of
https://github.com/fspc/workstand.git
synced 2025-02-23 01:13:22 -05:00
Big refactor of views.
This commit is contained in:
parent
ec68c34701
commit
b6d2f5e88c
83
bikeshop_project/registration/tests/test_utils.py
Normal file
83
bikeshop_project/registration/tests/test_utils.py
Normal file
@ -0,0 +1,83 @@
|
||||
from datetime import timedelta
|
||||
|
||||
from django.test import TestCase
|
||||
from django.utils import timezone
|
||||
from model_mommy import mommy
|
||||
|
||||
from core.models import Visit
|
||||
from registration.models import Member
|
||||
from registration.utils import signin_member, AlreadySignedInError, member_signed_in, get_signed_in_members
|
||||
|
||||
|
||||
class GetSignedInMembersTests(TestCase):
|
||||
def setUp(self):
|
||||
self.now = timezone.now()
|
||||
|
||||
self.member1 = mommy.make(model=Member)
|
||||
self.member2 = mommy.make(model=Member)
|
||||
self.member3 = mommy.make(model=Member)
|
||||
|
||||
three_hours_ago = self.now - timedelta(hours=3)
|
||||
five_hours_ago = self.now - timedelta(hours=5)
|
||||
|
||||
self.visit1 = Visit.objects.create(member=self.member1, purpose=Visit.DONATE, created_at=self.now)
|
||||
self.visit2 = Visit.objects.create(member=self.member2, purpose=Visit.DONATE, created_at=three_hours_ago)
|
||||
self.visit3 = Visit.objects.create(member=self.member3, purpose=Visit.DONATE, created_at=five_hours_ago)
|
||||
|
||||
def test_get_signed_in_members(self):
|
||||
"""
|
||||
Only members signed-in in the window are returned
|
||||
"""
|
||||
result1 = get_signed_in_members(end=self.now) # default window=4
|
||||
self.assertEqual(len(result1), 2)
|
||||
|
||||
result2 = get_signed_in_members(window=2, end=self.now)
|
||||
self.assertEqual(len(result2), 1)
|
||||
|
||||
result3 = get_signed_in_members(window=5, end=self.now)
|
||||
self.assertEqual(len(result3), 3)
|
||||
|
||||
|
||||
class SigninMember(TestCase):
|
||||
def test_not_signed_in(self):
|
||||
"""
|
||||
A member who hasn't signed-in in 4 hours is signed-in.
|
||||
"""
|
||||
member = mommy.make(Member)
|
||||
purpose = Visit.FIX
|
||||
visit = signin_member(member, purpose)
|
||||
|
||||
self.assertIsInstance(visit, Visit)
|
||||
|
||||
def test_signed_in(self):
|
||||
"""
|
||||
A member who has signed-in in 4 hours is not signed-in.
|
||||
"""
|
||||
member = mommy.make(Member)
|
||||
purpose = Visit.FIX
|
||||
signin_member(member, purpose)
|
||||
|
||||
with self.assertRaises(AlreadySignedInError):
|
||||
signin_member(member, purpose)
|
||||
|
||||
|
||||
class CheckMemberSignedIn(TestCase):
|
||||
def test_member_not_signed_in(self):
|
||||
"""
|
||||
Returns false when member is not signed-in
|
||||
"""
|
||||
not_signed_member = mommy.make(model=Member)
|
||||
result = member_signed_in(not_signed_member)
|
||||
|
||||
self.assertFalse(result)
|
||||
|
||||
def test_member_signed_in(self):
|
||||
"""
|
||||
Returns true when member is signed-in
|
||||
"""
|
||||
|
||||
member = mommy.make(model=Member)
|
||||
Visit.objects.create(member=member, purpose=Visit.DONATE)
|
||||
result = member_signed_in(member)
|
||||
|
||||
self.assertTrue(result)
|
37
bikeshop_project/registration/utils.py
Normal file
37
bikeshop_project/registration/utils.py
Normal file
@ -0,0 +1,37 @@
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Optional
|
||||
|
||||
from django.db.models import QuerySet
|
||||
from django.utils import timezone
|
||||
|
||||
from core.models import Visit
|
||||
from registration.models import Member
|
||||
|
||||
|
||||
class AlreadySignedInError(ValueError):
|
||||
pass
|
||||
|
||||
|
||||
def signin_member(member: Member, purpose: str) -> Visit:
|
||||
"""
|
||||
Signs in a member, creating a new `Visit`
|
||||
:param member: the member to be signed in
|
||||
:param purpose: The reason for visit. E.g. Fix a bike or volunteer
|
||||
:return: a new `Visit`
|
||||
:raise: `AlreadySignedInError` or `ValidationError`
|
||||
"""
|
||||
if not member_signed_in(member):
|
||||
return Visit.objects.create(member=member, purpose=purpose)
|
||||
|
||||
raise AlreadySignedInError
|
||||
|
||||
|
||||
def member_signed_in(member: Member, window: int = 4) -> bool:
|
||||
return get_signed_in_members(window=window).filter(id__in=[member.id]).exists()
|
||||
|
||||
|
||||
def get_signed_in_members(window: int = 4, end: Optional[datetime] = None) -> QuerySet:
|
||||
new_end = end if end else timezone.now()
|
||||
start = new_end - timedelta(hours=window)
|
||||
visits = Visit.objects.filter(created_at__lte=new_end, created_at__gte=start)
|
||||
return visits
|
@ -1,27 +1,23 @@
|
||||
import json
|
||||
import logging
|
||||
from datetime import timedelta
|
||||
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.template.response import TemplateResponse
|
||||
from django.utils import timezone
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.views.generic import TemplateView, View
|
||||
from haystack.query import SearchQuerySet
|
||||
from rest_framework import serializers
|
||||
from rest_framework.renderers import JSONRenderer
|
||||
from rest_framework.serializers import ModelSerializer
|
||||
|
||||
from core.models import Visit
|
||||
from haystack.query import SearchQuerySet
|
||||
|
||||
from registration.utils import signin_member, get_signed_in_members
|
||||
from .forms import MemberForm
|
||||
from .models import Member
|
||||
|
||||
logger = logging.getLogger('bikeshop')
|
||||
|
||||
|
||||
@method_decorator(login_required, name='dispatch')
|
||||
class MemberFormView(View):
|
||||
@ -69,17 +65,23 @@ class MemberSearchView(View):
|
||||
|
||||
|
||||
class MemberSerializer(ModelSerializer):
|
||||
first_name = serializers.CharField(allow_blank=True, required=False)
|
||||
last_name = serializers.CharField(allow_blank=True, required=False)
|
||||
|
||||
class Meta:
|
||||
model = Member
|
||||
fields = ('full_name', 'email', 'id')
|
||||
fields = ('first_name', 'last_name', 'email', 'id')
|
||||
|
||||
|
||||
class VisitSerializer(ModelSerializer):
|
||||
member = MemberSerializer()
|
||||
|
||||
class Meta:
|
||||
model = Visit
|
||||
fields = ('created_at', 'purpose', 'member')
|
||||
depth = 1
|
||||
|
||||
|
||||
class MemberSignIn(View):
|
||||
@method_decorator(csrf_exempt)
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
@ -87,21 +89,17 @@ class MemberSignIn(View):
|
||||
|
||||
def post(self, request):
|
||||
member = get_object_or_404(Member, id=request.POST.get('id'))
|
||||
Visit.objects.create(member=member, purpose=request.POST.get('purpose'))
|
||||
data = json.dumps(dict(results=dict(id=member.id)))
|
||||
visit = signin_member(member, request.POST.get('purpose'))
|
||||
data = json.dumps(dict(results=dict(id=member.id, created_at=visit.created_at.isoformat())))
|
||||
|
||||
return JsonResponse(data=data, safe=False, status=201)
|
||||
|
||||
def get(self, request):
|
||||
start = timezone.now()
|
||||
end = start + timedelta(hours=4)
|
||||
visits = Visit.objects.filter(created_at__lte=end,
|
||||
created_at__gte=start).prefetch_related()
|
||||
|
||||
visits = get_signed_in_members().prefetch_related()
|
||||
serializer = VisitSerializer(visits, many=True)
|
||||
json = JSONRenderer().render(serializer.data)
|
||||
results_json = JSONRenderer().render(serializer.data)
|
||||
|
||||
return JsonResponse(data=json.decode(), safe=False, status=200)
|
||||
return JsonResponse(data=results_json.decode(), safe=False, status=200)
|
||||
|
||||
|
||||
@method_decorator(login_required, name='dispatch')
|
||||
|
Loading…
x
Reference in New Issue
Block a user