diff --git a/bikeshop_project/bike/consumers.py b/bikeshop_project/bike/consumers.py index 252a713..d21d04f 100644 --- a/bikeshop_project/bike/consumers.py +++ b/bikeshop_project/bike/consumers.py @@ -4,17 +4,18 @@ from typing import Dict, Union, Optional import requests from bs4 import BeautifulSoup +from channels import Channel from django.core.exceptions import ObjectDoesNotExist from django.utils import timezone from bike.models import Bike -logger = logging.getLogger('cpic') +logger = logging.getLogger('bikeshop') def _is_stolen(serial: str) -> Optional[bool]: url = 'http://app.cpic-cipc.ca/English/searchFormResultsbikes.cfm' - data = {'ser': message.get('serial_number'), + data = {'ser': serial, 'toc': 1, 'Submit': 'Begin Search'} @@ -55,6 +56,7 @@ def check_cpic(message: Dict[str, Union[str, int]]) -> None: bike.stolen = False bike.save() + response = {'stolen': stolen} + response.update(message) - - + Channel('check-cpic').send(response) diff --git a/bikeshop_project/bike/tests.py b/bikeshop_project/bike/tests.py index 72fb134..f5c79e3 100644 --- a/bikeshop_project/bike/tests.py +++ b/bikeshop_project/bike/tests.py @@ -1,4 +1,7 @@ from decimal import Decimal + +from channels import Channel +from channels.tests import ChannelTestCase from django.test import TestCase from model_mommy import timezone @@ -12,7 +15,7 @@ from .models import Bike, BikeState from unittest.mock import patch -class TestGet(TestCase): +class TestBikeApi(TestCase): def setUp(self): 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) - def test_assessed_cannot_transition(self): data = { "colour": "black", @@ -347,6 +349,18 @@ class TestGet(TestCase): 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): @patch('bike.consumers._is_stolen') @@ -372,3 +386,24 @@ class TestBikeSignals(TestCase): self.assertFalse(updated_bike.stolen) 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']) diff --git a/bikeshop_project/bike/views.py b/bikeshop_project/bike/views.py index 725b5f0..7a02ea6 100644 --- a/bikeshop_project/bike/views.py +++ b/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.shortcuts import get_object_or_404 from django.utils.decorators import method_decorator @@ -15,6 +17,8 @@ from rest_framework import status from registration.models import Member +logger = logging.getLogger('bikeshop') + @method_decorator(login_required, name='dispatch') class BikesView(TemplateView): @@ -107,3 +111,10 @@ class BikeViewSet(viewsets.ModelViewSet): serializer = BikeSerializer(bike, context={'request': request}) 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'})