From 0d42e36114972cbac095ef1621e3fb2a570cab14 Mon Sep 17 00:00:00 2001 From: Juan Madurga Date: Wed, 16 Mar 2016 22:55:18 +0100 Subject: [PATCH] hook api --- microbot/serializers.py | 51 ++++++++++++++++- microbot/urls.py | 2 + microbot/views.py | 27 ++++++++- tests/test_api.py | 118 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 191 insertions(+), 7 deletions(-) diff --git a/microbot/serializers.py b/microbot/serializers.py index 2ba70de..719623f 100644 --- a/microbot/serializers.py +++ b/microbot/serializers.py @@ -1,6 +1,6 @@ from rest_framework import serializers from microbot.models import User, Chat, Message, Update, Bot, EnvironmentVar, Handler, Request, UrlParam, HeaderParam, \ - Response + Response, Hook, Recipient from datetime import datetime import time @@ -155,4 +155,51 @@ def update(self, instance, validated_data): self._update_params(validated_data['request']['header_parameters'], instance.request.header_parameters.get) instance.save() - return instance \ No newline at end of file + return instance + +class RecipientSerializer(serializers.HyperlinkedModelSerializer): + id = serializers.IntegerField() + + class Meta: + model = Recipient + fields = ('id', ) + +class HookSerializer(serializers.ModelSerializer): + response = ResponseSerializer(many=False) + recipients = RecipientSerializer(many=True) + + class Meta: + model = Hook + fields = ('key', 'enabled', 'response', 'recipients') + read_only_fields = ('key', ) + + def _create_recipients(self, recipients, hook): + for recipient in recipients: + Recipient.objects.get_or_create(id=recipient['id'], + hook=hook) + + def _update_recipients(self, recipients, instance): + instance.recipients.all().delete() + self._create_recipients(recipients, instance) + + def create(self, validated_data): + response, _ = Response.objects.get_or_create(**validated_data['response']) + + hook, _ = Hook.objects.get_or_create(response=response, + enabled=validated_data['enabled']) + + self._create_recipients(validated_data['recipients'], hook) + + return hook + + def update(self, instance, validated_data): + instance.enabled = validated_data.get('enabled', instance.enabled) + + instance.response.text_template = validated_data['response'].get('text_template', instance.response.text_template) + instance.response.keyboard_template = validated_data['response'].get('keyboard_template', instance.response.keyboard_template) + instance.response.save() + + self._update_recipients(validated_data['recipients'], instance) + + instance.save() + return instance \ No newline at end of file diff --git a/microbot/urls.py b/microbot/urls.py index d69ecb2..ea498f4 100644 --- a/microbot/urls.py +++ b/microbot/urls.py @@ -11,4 +11,6 @@ url(r'^api/bots/(?P[0-9]+)/env/(?P[0-9]+)/$', views.EnvironmentVarDetail.as_view(), name='env-list'), url(r'^api/bots/(?P[0-9]+)/handlers/$', views.HandlerList.as_view(), name='handler-list'), url(r'^api/bots/(?P[0-9]+)/handlers/(?P[0-9]+)/$', views.HandlerDetail.as_view(), name='handler-detail'), + url(r'^api/bots/(?P[0-9]+)/hooks/$', views.HookList.as_view(), name='hook-list'), + url(r'^api/bots/(?P[0-9]+)/hooks/(?P[0-9]+)/$', views.HookDetail.as_view(), name='hook-detail'), ] diff --git a/microbot/views.py b/microbot/views.py index 2f79fc7..5d6b61b 100644 --- a/microbot/views.py +++ b/microbot/views.py @@ -1,7 +1,7 @@ from rest_framework.views import APIView from microbot.serializers import UpdateSerializer, BotSerializer, EnvironmentVarSerializer,\ - HandlerSerializer -from microbot.models import Bot, EnvironmentVar, Handler, Request, Hook + HandlerSerializer, HookSerializer +from microbot.models import Bot, EnvironmentVar, Handler, Request, Hook, Recipient from microbot.models import Response as handlerResponse from rest_framework.response import Response from rest_framework import status @@ -166,6 +166,7 @@ def put(self, request, bot_pk, pk, format=None): if serializer.is_valid(): serializer.save() return Response(serializer.data) + print serializer.errors return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) def delete(self, request, bot_pk, pk, format=None): @@ -211,3 +212,25 @@ def _creator(self, bot, serializer): class HandlerDetail(DetailBotAPIView): model = Handler serializer = HandlerSerializer + +class HookList(ListBotAPIView): + serializer = HookSerializer + + def _query(self, bot): + return bot.hooks.all() + + def _creator(self, bot, serializer): + + response = handlerResponse.objects.create(text_template=serializer.data['response']['text_template'], + keyboard_template=serializer.data['response']['keyboard_template']) + hook = Hook.objects.create(bot=bot, + enabled=serializer.data['enabled'], + response=response) + for recipient in serializer.data['recipients']: + Recipient.objects.create(hook=hook, + id=recipient['id']) + + +class HookDetail(DetailBotAPIView): + model = Hook + serializer = HookSerializer diff --git a/tests/test_api.py b/tests/test_api.py index b39a9c3..2935817 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1,10 +1,10 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from microbot.models import Bot, EnvironmentVar, Handler +from microbot.models import Bot, EnvironmentVar, Handler, Hook, Recipient from microbot.test import testcases, factories from rest_framework import status from rest_framework.test import APIRequestFactory, force_authenticate -from microbot.views import BotDetail, EnvironmentVarDetail, HandlerDetail +from microbot.views import BotDetail, EnvironmentVarDetail, HandlerDetail, HookDetail from django.conf import settings from django.apps import apps import json @@ -399,4 +399,116 @@ def test_delete_handler_not_auth(self): self._test_delete_detail_not_auth(self._handler_detail_url(), HandlerDetail, self.bot.pk, self.handler.pk) def test_delete_handler_not_found(self): - self._test_delete_detail_not_found(self._handler_detail_url(handler_pk=12), HandlerDetail, self.bot.pk, 12) \ No newline at end of file + self._test_delete_detail_not_found(self._handler_detail_url(handler_pk=12), HandlerDetail, self.bot.pk, 12) + + +class TestHookAPI(BaseTestAPI): + + def setUp(self): + super(TestHookAPI, self).setUp() + self.hook = factories.HookFactory(bot=self.bot) + self.recipient = factories.RecipientFactory(hook=self.hook) + + def _hook_list_url(self, bot_pk=None): + if not bot_pk: + bot_pk = self.bot.pk + return '%s/bots/%s/hooks/' % (self.api, bot_pk) + + def _hook_detail_url(self, bot_pk=None, hook_pk=None): + if not bot_pk: + bot_pk = self.bot.pk + if not hook_pk: + hook_pk = self.hook.pk + return '%s/bots/%s/hooks/%s/' % (self.api, bot_pk, hook_pk) + + def assertHook(self, response_text_template, response_keyboard_template, enabled, recipients, hook=None): + if not hook: + hook = self.hook + self.assertEqual(hook.response.text_template, response_text_template) + self.assertEqual(hook.response.keyboard_template, response_keyboard_template) + self.assertEqual(hook.enabled, enabled) + self.assertEqual(hook.recipients.count(), len(recipients)) + # check recipients + for recipient in recipients: + Recipient.objects.get(id=recipient['id']) + + def test_get_hooks_ok(self): + data = self._test_get_list_ok(self._hook_list_url()) + self.assertHook(data[0]['response']['text_template'], data[0]['response']['keyboard_template'], + data[0]['enabled'], data[0]['recipients']) + + def test_get_hooks_not_auth(self): + self._test_get_list_not_auth(self._hook_list_url()) + + def test_post_hooks_ok(self): + data = {'response': {'text_template': self.hook.response.text_template, + 'keyboard_template': self.hook.response.keyboard_template}, + 'enabled': False, 'recipients': [{'id': recipient.id} for recipient in self.hook.recipients.all()] + } + recipients = [{'id': recipient.id} for recipient in self.hook.recipients.all()] + self._test_post_list_ok(self._hook_list_url(), Hook, data) + new_hook = Hook.objects.filter(bot=self.bot)[0] + self.assertHook(self.hook.response.text_template, self.hook.response.keyboard_template, + False, recipients, hook=new_hook) + + def test_post_hooks_not_auth(self): + data = {'response': {'text_template': self.hook.response.text_template, + 'keyboard_template': self.hook.response.keyboard_template}, 'enabled': False, + 'recipients': [{'id': recipient.id} for recipient in self.hook.recipients.all()]} + self._test_post_list_not_auth(self._hook_list_url(), data) + + def test_get_hook_ok(self): + data = self._test_get_detail_ok(self._hook_detail_url()) + self.assertHook(data['response']['text_template'], data['response']['keyboard_template'], data['enabled'], + data['recipients']) + + def test_get_hook_from_other_bot(self): + self._test_get_detail_from_other_bot(self._hook_detail_url) + + def test_get_hook_not_auth(self): + self._test_get_detail_not_auth(self._hook_detail_url()) + + def test_get_hook_not_found(self): + self._test_get_detail_not_found(self._hook_detail_url(hook_pk=12)) + + def test_put_hook_ok(self): + data = {'response': {'text_template': self.hook.response.text_template, + 'keyboard_template': self.hook.response.keyboard_template}, + 'enabled': False, + 'recipients': [{'id': recipient.id} for recipient in self.hook.recipients.all()] + } + self._test_put_detail_ok(self._hook_detail_url(), data, HookDetail, self.bot.pk, self.hook.pk) + self.assertEqual(Hook.objects.get(pk=self.hook.pk).enabled, False) + + def test_put_hook_from_other_bot(self): + data = {'response': {'text_template': self.hook.response.text_template, + 'keyboard_template': self.hook.response.keyboard_template}, 'enabled': False, + 'recipients': [{'id': recipient.id} for recipient in self.hook.recipients.all()] + } + self._test_put_detail_from_other_bot(self._hook_detail_url, data, HookDetail, self.hook.pk) + + def test_put_hook_not_auth(self): + data = {'response': {'text_template': self.hook.response.text_template, + 'keyboard_template': self.hook.response.keyboard_template}, 'enabled': False, + 'recipients': [{'id': recipient.id} for recipient in self.hook.recipients.all()] + } + self._test_put_detail_not_auth(self._hook_detail_url(), data, HandlerDetail, self.bot.pk, self.hook.pk) + + def test_put_hook_not_found(self): + data = {'response': {'text_template': self.hook.response.text_template, + 'keyboard_template': self.hook.response.keyboard_template}, 'enabled': False, + 'recipients': [{'id': recipient.id} for recipient in self.hook.recipients.all()] + } + self._test_put_detail_not_found(self._hook_detail_url(hook_pk=12), data, HookDetail, self.bot.pk, 12) + + def test_delete_hook_ok(self): + self._test_delete_detail_ok(self._hook_detail_url(), HookDetail, self.bot.pk, self.hook.pk) + + def test_delete_hook_from_other_bot(self): + self._test_delete_detail_from_other_bot(self._hook_detail_url, HookDetail, self.hook.pk) + + def test_delete_hook_not_auth(self): + self._test_delete_detail_not_auth(self._hook_detail_url(), HookDetail, self.bot.pk, self.hook.pk) + + def test_delete_hook_not_found(self): + self._test_delete_detail_not_found(self._hook_detail_url(hook_pk=12), HookDetail, self.bot.pk, 12) \ No newline at end of file