Browse Source

Add endpoint to check cpic.

feature/bike-tracking
Drew Larson 8 years ago
parent
commit
63ff3f5ce7
  1. 10
      bikeshop_project/bike/consumers.py
  2. 39
      bikeshop_project/bike/tests.py
  3. 11
      bikeshop_project/bike/views.py

10
bikeshop_project/bike/consumers.py

@ -4,17 +4,18 @@ from typing import Dict, Union, Optional
import requests import requests
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from channels import Channel
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.utils import timezone from django.utils import timezone
from bike.models import Bike from bike.models import Bike
logger = logging.getLogger('cpic') logger = logging.getLogger('bikeshop')
def _is_stolen(serial: str) -> Optional[bool]: def _is_stolen(serial: str) -> Optional[bool]:
url = 'http://app.cpic-cipc.ca/English/searchFormResultsbikes.cfm' url = 'http://app.cpic-cipc.ca/English/searchFormResultsbikes.cfm'
data = {'ser': message.get('serial_number'), data = {'ser': serial,
'toc': 1, 'toc': 1,
'Submit': 'Begin Search'} 'Submit': 'Begin Search'}
@ -55,6 +56,7 @@ def check_cpic(message: Dict[str, Union[str, int]]) -> None:
bike.stolen = False bike.stolen = False
bike.save() bike.save()
response = {'stolen': stolen}
response.update(message)
Channel('check-cpic').send(response)

39
bikeshop_project/bike/tests.py

@ -1,4 +1,7 @@
from decimal import Decimal from decimal import Decimal
from channels import Channel
from channels.tests import ChannelTestCase
from django.test import TestCase from django.test import TestCase
from model_mommy import timezone from model_mommy import timezone
@ -12,7 +15,7 @@ from .models import Bike, BikeState
from unittest.mock import patch from unittest.mock import patch
class TestGet(TestCase): class TestBikeApi(TestCase):
def setUp(self): def setUp(self):
self.user = mommy.make('registration.CustomUser', is_admin=True, is_superuser=True) self.user = mommy.make('registration.CustomUser', is_admin=True, is_superuser=True)
@ -77,7 +80,6 @@ class TestGet(TestCase):
self.assertEqual(result.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(result.status_code, status.HTTP_400_BAD_REQUEST)
def test_assessed_cannot_transition(self): def test_assessed_cannot_transition(self):
data = { data = {
"colour": "black", "colour": "black",
@ -347,6 +349,18 @@ class TestGet(TestCase):
self.assertEqual(result.status_code, status.HTTP_200_OK) self.assertEqual(result.status_code, status.HTTP_200_OK)
@patch('bike.consumers.check_cpic')
def test_check_cpic(self, check_cpic_mock):
bike = mommy.make(model=Bike, cpic_searched_at=None, stolen=None)
client = APIClient()
client.force_authenticate(user=self.user, token='blah')
data = {'serial_number': '123abc'}
result = client.put(f'/api/v1/bikes/{bike.id}/check/', data=data)
self.assertEqual(result.status_code, status.HTTP_200_OK)
self.assertEqual(result.data, {'status': 'pending'})
check_cpic_mock.assert_called_once()
class TestBikeSignals(TestCase): class TestBikeSignals(TestCase):
@patch('bike.consumers._is_stolen') @patch('bike.consumers._is_stolen')
@ -372,3 +386,24 @@ class TestBikeSignals(TestCase):
self.assertFalse(updated_bike.stolen) self.assertFalse(updated_bike.stolen)
self.assertIsNotNone(updated_bike.cpic_searched_at) self.assertIsNotNone(updated_bike.cpic_searched_at)
class TestBikeCheckCpic(ChannelTestCase):
@patch('bike.consumers._is_stolen')
def test_start_check(self, is_stolen_mock):
is_stolen_mock.return_value = False
bike = mommy.make(Bike)
message = {'bike_id': bike.id, 'serial_number': bike.serial_number}
Channel('check-cpic').send(message)
check_cpic(self.get_next_message('check-cpic', require=True))
result = self.get_next_message('check-cpic', require=True)
updated_bike = Bike.objects.get(id=bike.id)
self.assertFalse(updated_bike.stolen)
self.assertIsNotNone(updated_bike.cpic_searched_at)
self.assertFalse(result['stolen'])
self.assertEqual(result['bike_id'], message['bike_id'])
self.assertEqual(result['serial_number'], message['serial_number'])

11
bikeshop_project/bike/views.py

@ -1,3 +1,5 @@
import logging
from channels import Channel
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
@ -15,6 +17,8 @@ from rest_framework import status
from registration.models import Member from registration.models import Member
logger = logging.getLogger('bikeshop')
@method_decorator(login_required, name='dispatch') @method_decorator(login_required, name='dispatch')
class BikesView(TemplateView): class BikesView(TemplateView):
@ -107,3 +111,10 @@ class BikeViewSet(viewsets.ModelViewSet):
serializer = BikeSerializer(bike, context={'request': request}) serializer = BikeSerializer(bike, context={'request': request})
return Response(serializer.data, status=status.HTTP_200_OK) return Response(serializer.data, status=status.HTTP_200_OK)
@detail_route(methods=['put'])
def check(self, request, pk):
message = {'bike_id': pk, 'serial_number': request.data.get('serial_number')}
Channel('check-cpic').send(message)
return Response({'status': 'pending'})

Loading…
Cancel
Save