From 8a13c0356c134b03b544901189ed652c6a4be2b1 Mon Sep 17 00:00:00 2001 From: Drew Larson Date: Sat, 7 Jan 2017 19:03:14 -0600 Subject: [PATCH] Claim endpoint. --- bikeshop_project/bike/tests.py | 76 ++++++++++++++++++++++++++++++++++ bikeshop_project/bike/views.py | 16 +++++++ 2 files changed, 92 insertions(+) diff --git a/bikeshop_project/bike/tests.py b/bikeshop_project/bike/tests.py index 90037e0..9c3840b 100644 --- a/bikeshop_project/bike/tests.py +++ b/bikeshop_project/bike/tests.py @@ -5,6 +5,8 @@ from model_mommy import timezone from rest_framework.test import APIClient from model_mommy import mommy from rest_framework import status + +from registration.models import Member from .models import Bike, BikeState @@ -150,3 +152,77 @@ class TestGet(TestCase): self.assertEqual(result.status_code, status.HTTP_200_OK) self.assertEqual(result.data['state'], BikeState.AVAILABLE) + + def test_claim_cannot_transition_wrong_state(self): + member = mommy.make(Member) + + data = { + "colour": "black", + "make": "Miyata", + "serial_number": "12345676", + "source": Bike.COS_BIKE_DIVERSION_PILOT, + "donated_by": "Greg", + "donated_at": "2017-01-01", + "size": Bike.SMALL, + "price": Decimal('68.00'), + "state": BikeState.ASSESSED, + "stolen": False, + "cpic_searched_at": timezone.now(), + } + bike = Bike.objects.create(**data) + client = APIClient() + client.force_authenticate(user=self.user, token='blah') + result = client.put(f'/api/v1/bikes/{bike.id}/claim/', data={'member': member.id}, format='json') + + self.assertEqual(result.status_code, status.HTTP_400_BAD_REQUEST) + + def test_claim_cannot_transition_claimed(self): + member = mommy.make(Member) + + data = { + "colour": "black", + "make": "Miyata", + "serial_number": "12345676", + "source": Bike.COS_BIKE_DIVERSION_PILOT, + "donated_by": "Greg", + "donated_at": "2017-01-01", + "size": Bike.SMALL, + "price": Decimal('68.00'), + "state": BikeState.CLAIMED, + "stolen": False, + "cpic_searched_at": timezone.now(), + "claimed_by": member, + "last_worked_on": timezone.now() + } + bike = Bike.objects.create(**data) + client = APIClient() + client.force_authenticate(user=self.user, token='blah') + result = client.put('/api/v1/bikes/{bike_id}/claim/'.format(bike_id=bike.id), data={'member': member.id}, format='json') + + self.assertEqual(result.status_code, status.HTTP_400_BAD_REQUEST) + + def test_claim_can_transition(self): + member = mommy.make(Member) + + data = { + "colour": "black", + "make": "Miyata", + "serial_number": "12345676", + "source": Bike.COS_BIKE_DIVERSION_PILOT, + "donated_by": "Greg", + "donated_at": "2017-01-01", + "size": Bike.SMALL, + "price": Decimal('68.00'), + "state": BikeState.AVAILABLE, + "stolen": False, + "cpic_searched_at": timezone.now(), + } + + bike = Bike.objects.create(**data) + self.assertEqual(bike.state, BikeState.AVAILABLE) + client = APIClient() + client.force_authenticate(user=self.user, token='blah') + result = client.put(f'/api/v1/bikes/{bike.id}/claim/', data={'member': member.id}, format='json') + + self.assertEqual(result.status_code, status.HTTP_200_OK) + self.assertEqual(result.data['state'], BikeState.CLAIMED) diff --git a/bikeshop_project/bike/views.py b/bikeshop_project/bike/views.py index 9c4c349..7c67631 100644 --- a/bikeshop_project/bike/views.py +++ b/bikeshop_project/bike/views.py @@ -13,6 +13,8 @@ from bike.serializers import BikeSerializer from rest_framework import status +from registration.models import Member + @method_decorator(login_required, name='dispatch') class BikesView(TemplateView): @@ -52,3 +54,17 @@ class BikeViewSet(viewsets.ModelViewSet): serializer = BikeSerializer(bike, context={'request': request}) return Response(serializer.data, status=status.HTTP_200_OK) + @detail_route(methods=['put']) + def claim(self, request, pk): + bike = get_object_or_404(Bike, pk=pk) + member = get_object_or_404(Member, id=request.data.get('member')) + state = BikeState.CLAIMED + if not can_proceed(bike.claim): + raise ValidationError(detail=f'Transition from {bike.state} to {state}') + + bike.claim(member) + bike.save() + + serializer = BikeSerializer(bike, context={'request': request}) + return Response(serializer.data, status=status.HTTP_200_OK) +