tests factorised

This commit is contained in:
Qwann 2017-07-25 14:02:57 +02:00
parent a4da5d94c4
commit 3246552eba
6 changed files with 334 additions and 104 deletions

View file

@ -0,0 +1,7 @@
from equipment.models import Equipment
from api.event.serializers import EventSpecificSerializer
class EquipmentSerializer(EventSpecificSerializer):
pass

View file

@ -89,3 +89,7 @@ class ActivityTemplateSerializer(serializers.ModelSerializer):
for tag_data in tags_data] for tag_data in tags_data]
activity_template.tags = tags activity_template.tags = tags
return activity_template return activity_template
class ActivitySerializer(serializers.ModelSerializer):
pass

View file

@ -4,8 +4,8 @@ from django.db.models import Q
from rest_framework.viewsets import ModelViewSet from rest_framework.viewsets import ModelViewSet
from api.event.serializers import EventSerializer, PlaceSerializer,\ from api.event.serializers import EventSerializer, PlaceSerializer,\
ActivityTagSerializer, ActivityTemplateSerializer ActivityTagSerializer, ActivityTemplateSerializer, ActivitySerializer
from event.models import Event, Place, ActivityTag, ActivityTemplate from event.models import Event, Place, ActivityTag, ActivityTemplate, Activity
User = get_user_model() User = get_user_model()
@ -36,6 +36,10 @@ class EventSpecificViewSet(ModelViewSet):
event_pk = self.kwargs.get('event_pk') event_pk = self.kwargs.get('event_pk')
serializer.save(event_pk=event_pk) serializer.save(event_pk=event_pk)
def perform_update(self, serializer):
event_pk = self.kwargs.get('event_pk')
serializer.save(event_pk=event_pk)
# ViewSets # ViewSets
class EventViewSet(ModelViewSet): class EventViewSet(ModelViewSet):
@ -73,3 +77,25 @@ class ActivityTemplateViewSet(ModelViewSet):
def perform_create(self, serializer): def perform_create(self, serializer):
event_pk = self.kwargs.get('event_pk') event_pk = self.kwargs.get('event_pk')
serializer.save(event_pk=event_pk) serializer.save(event_pk=event_pk)
def perform_update(self, serializer):
event_pk = self.kwargs.get('event_pk')
serializer.save(event_pk=event_pk)
class ActivityViewSet(ModelViewSet):
"""
This viewset automatically provides `list`, `create`, `retrieve`,
`update` and `destroy` actions.
"""
queryset = Activity.objects.all()
serializer_class = ActivitySerializer
def perform_create(self, serializer):
event_pk = self.kwargs.get('event_pk')
serializer.save(event_pk=event_pk)
def perform_update(self, serializer):
event_pk = self.kwargs.get('event_pk')
serializer.save(event_pk=event_pk)

View file

@ -1,118 +1,56 @@
from datetime import timedelta
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.utils import timezone
from django.urls import reverse
from rest_framework.test import APIRequestFactory, APITestCase from rest_framework.test import APITestCase
from rest_framework import status
from event.models import Event, Place, ActivityTag, ActivityTemplate from event.models import Event, Place, ActivityTag, ActivityTemplate
from api.event.serializers import ActivityTemplateSerializer, EventSerializer
from api.test_mixins import EventBasedModelMixin, EventSpecificMixin,\
ModelTestMixin
User = get_user_model() User = get_user_model()
class EventTest(APITestCase): class EventTest(ModelTestMixin, APITestCase):
@classmethod model = Event
def setUpTestData(cls): base_name = 'event'
cls.user = User.objects.create( tested_fields = {'title': "I'm a test", }
username='enarmanli', # Création
email='erkan.narmanli@ens.fr', data_creation = 'event2_data'
first_name='Erkan', # Update/Delete
last_name='Narmanli', instance_name = 'event1'
) serializer = EventSerializer
cls.event_data = {
"title": "test event",
"slug": "test-event",
"description": "C'est trop cool !",
"beginning_date": "2017-07-18T18:05:00Z",
"ending_date": "2017-07-19T18:05:00Z",
}
# def test_anonymous_create(self):
# """
# ensure anonymous can't create a new event object using API
# """
# url = reverse('event-list')
# response = self.client.post(url, self.event_data, format='json')
# self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
def test_user_create(self):
"""
ensure we can create a new event object using API
"""
url = reverse('event-list')
self.client.force_authenticate(user=self.user)
response = self.client.post(url, self.event_data, format='json')
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual(Event.objects.count(), 1)
self.assertEqual(Event.objects.get().title, 'test event')
class EventSpecificTest(APITestCase): class ActivityTemplateTest(EventBasedModelMixin, APITestCase):
""" model = ActivityTemplate
Tests is the EventSpecifics querysets are rendered correctly base_name = 'event-activitytemplate'
using the API initial_count = 1
""" # Creation
@classmethod data_creation = 'act_temp2_data'
def setUpTestData(cls): # Update/Delete
cls.user = User.objects.create_user(username='user', password='pass', ) instance_name = 'act_temp1'
cls.event = Event.objects.create( field_tested = 'title'
title='La Nuit 2042', serializer = ActivityTemplateSerializer
slug='nuit42',
created_by=cls.user,
creation_date=timezone.now(),
description="La nuit c'est lol",
beginning_date=timezone.now()
+ timedelta(days=30),
ending_date=timezone.now()
+ timedelta(days=31),
)
cls.factory = APIRequestFactory()
def test_place(self): def test_create_extra(self):
Place.objects.create(name="root-place", event=None) self.assertEqual(self.model.objects.get(id=1).tags.count(), 1)
Place.objects.create(name="event-place", event=self.event)
self.client.force_authenticate(user=self.user) def pre_update_extra(self, data):
data['tags'].append(self.tag2_data)
return data
url = reverse('place-list') def post_update_extra(self, instance):
response = self.client.get(url, format='json') self.assertEqual(instance.tags.count(), 2)
self.assertEqual(response.json()['count'], 1)
event_id = self.event.id
url = reverse('event-place-list', kwargs={'event_pk': event_id})
response = self.client.get(url, format='json')
self.assertEqual(response.json()['count'], 2)
def test_tag(self): class EventSpecficTagTest(EventSpecificMixin, APITestCase):
ActivityTag.objects.create(name="root-tag", model = ActivityTag
is_public=True, root_base_name = 'activitytag'
color="#000", event_base_name = 'event-activitytag'
event=None)
ActivityTag.objects.create(name="event-tag",
is_public=True,
color="#FFF",
event=self.event)
self.client.force_authenticate(user=self.user)
url = reverse('activitytag-list') class EventSpecficPlaceTest(EventSpecificMixin, APITestCase):
response = self.client.get(url, format='json') model = Place
self.assertEqual(response.json()['count'], 1) root_base_name = 'place'
event_base_name = 'event-place'
event_id = self.event.id
url = reverse('event-activitytag-list', kwargs={'event_pk': event_id})
response = self.client.get(url, format='json')
self.assertEqual(response.json()['count'], 2)
def test_activitytemplate(self):
ActivityTemplate.objects.create(title="test", event=self.event)
self.client.force_authenticate(user=self.user)
event_id = self.event.id
url = reverse('event-activitytemplate-list',
kwargs={'event_pk': event_id})
response = self.client.get(url, format='json')
self.assertEqual(response.json()['count'], 1)

256
api/test_mixins.py Normal file
View file

@ -0,0 +1,256 @@
from datetime import timedelta
from django.contrib.auth import get_user_model
from django.db.models import Q
from django.utils import timezone
from django.urls import reverse
from rest_framework.test import APIRequestFactory
from rest_framework import status
from event.models import Event, Place, ActivityTag, ActivityTemplate
User = get_user_model()
class DataBaseMixin(object):
@classmethod
def setUpTestData(cls):
# Users
cls.user1_data = {'username': "user1", 'password': "pass1"}
cls.user1 = User.objects.create_user(**cls.user1_data)
def setUp(self):
# Events
self.event1_data = {'title': "event1", 'slug': "slug1",
'beginning_date': timezone.now()
+ timedelta(days=30),
"description": "C'est trop cool !",
'ending_date': timezone.now()+timedelta(days=31),
'created_by': self.user1, }
self.event2_data = {"title": "test event", "slug": "test-event",
"description": "C'est trop cool !",
"beginning_date": "2017-07-18T18:05:00Z",
"ending_date": "2017-07-19T18:05:00Z", }
self.event1 = Event.objects.create(**self.event1_data)
# ActivityTags
self.tag1_data = {"name": "tag1", "is_public": False, "color": "#111"}
self.tag2_data = {"name": "tag2", "is_public": False, "color": "#222"}
self.tag3_data = {"name": "tag3", "is_public": False, "color": "#333"}
self.tag1 = ActivityTag.objects.create(**self.tag1_data)
self.act_temp1_data = {'title': "act temp1", 'is_public': True,
'remarks': "test remark", 'event': self.event1}
self.act_temp2_data = {'title': "act temp2", 'is_public': False,
'remarks': "test remark",
'tags': [self.tag2_data, ]}
self.act_temp1 = ActivityTemplate.objects.create(**self.act_temp1_data)
self.act_temp1.tags.add(self.tag1)
class EventBasedModelMixin(DataBaseMixin):
"""
Note : need to define : `model`, `base_name`, `initial_count`,
`data_creation`, `instance_name`, `field_tested`, `serializer`
"""
def test_user_create_extra(self):
pass
def pre_update_extra(self, data):
return data
def post_update_extra(self):
pass
def test_user_create(self):
"""
ensure we can create a new %model object using API
"""
data = getattr(self, self.data_creation)
event_id = self.event1.id
url = reverse('{base_name}-list'.format(base_name=self.base_name),
kwargs={'event_pk': event_id})
self.client.force_authenticate(user=self.user1)
response = self.client.post(url, data,
format='json')
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual(self.model.objects.count(), self.initial_count + 1)
self.assertEqual(self.model.objects.get(id=self.initial_count+1).event,
self.event1)
self.test_create_extra()
def test_user_update(self):
"""
ensure we can update an %model object using API
"""
instance = getattr(self, self.instance_name)
factory = APIRequestFactory()
instance_id = instance.id
event_id = self.event1.id
url = reverse('{base_name}-list'.format(base_name=self.base_name),
kwargs={'event_pk': event_id})
url = "%s%d/" % (url, instance_id)
request = factory.get(url)
data = self.serializer(instance, context={'request': request}).data
newvalue = "I'm a test"
data[self.field_tested] = newvalue
data = self.pre_update_extra(data)
self.client.force_authenticate(user=self.user1)
response = self.client.patch(url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
instance.refresh_from_db()
self.assertEqual(getattr(instance, self.field_tested), newvalue)
self.post_update_extra(instance)
def test_user_delete(self):
"""
ensure we can update an %model object using API
"""
instance = getattr(self, self.instance_name)
instance_id = instance.id
event_id = self.event1.id
url = reverse('{base_name}-list'.format(base_name=self.base_name),
kwargs={'event_pk': event_id})
url = "%s%d/" % (url, instance_id)
self.client.force_authenticate(user=self.user1)
response = self.client.delete(url)
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
self.assertEqual(self.model.objects.count(), self.initial_count - 1)
# TODO rajouter la gestion des permissions dans le Mixin
# TODO rajouter un test pour s'assurer que les personnes non
# connectées ne peuvent pas create/update/delete
class EventSpecificMixin(object):
"""
Tests is the EventSpecifics querysets are rendered correctly
using the API
Note : need to define : `model`, `root_base_name` and `event_base_name`
"""
@classmethod
def setUpTestData(cls):
# Users
cls.user1_data = {'username': "user1", 'password': "pass1"}
cls.user1 = User.objects.create_user(**cls.user1_data)
# Events
cls.event1_data = {'title': "event1", 'slug': "slug1",
'beginning_date': timezone.now()
+ timedelta(days=30),
'ending_date': timezone.now()+timedelta(days=31),
'created_by': cls.user1, }
cls.event1 = Event.objects.create(**cls.event1_data)
def setUp(self):
# Tag
self.tag_root_data = {"name": "tag2", "is_public": False,
"color": "#222"}
self.tag_event_data = {"name": "tag3", "is_public": False,
"color": "#333", 'event': self.event1}
self.tag_root = ActivityTag.objects.create(**self.tag_root_data)
self.tag_event = ActivityTag.objects.create(**self.tag_event_data)
# Places
self.place_root_data = {'name': "place1", 'event': None, }
self.place_event_data = {'name': "place2", 'event': self.event1, }
self.place_root = Place.objects.create(**self.place_root_data)
self.place_event = Place.objects.create(**self.place_event_data)
def test_lists(self):
event_id = self.event1.id
root_count = self.model.objects.filter(event=None).count()
event_count = (self.model.objects
.filter(Q(event=self.event1) | Q(event=None)).count())
self.client.force_authenticate(user=self.user1)
url = reverse('{base}-list'.format(base=self.root_base_name))
response = self.client.get(url, format='json')
self.assertEqual(response.json()['count'], root_count)
event_id = self.event1.id
url = reverse('{base}-list'.format(base=self.event_base_name),
kwargs={'event_pk': event_id})
response = self.client.get(url, format='json')
self.assertEqual(response.json()['count'], event_count)
# TODO rajouter la gestion des permissions dans le Mixin
# TODO rajouter un test pour s'assurer que les personnes non
# connectées ne peuvent pas create/update/delete
# TODO? essayer de factoriser avec EventBasedMixin ?
# FIXME not working, peut être que le problème vient
# du fait que les dates sont mal envoyées dans le data ? A voir.
class ModelTestMixin(DataBaseMixin):
"""
Note : need to define : `model`, `base_name`,
`instance_name`, `field_tested`, `serializer`
"""
def test_user_create(self):
"""
ensure we can create a new %model object using API
"""
data = getattr(self, self.data_creation)
initial_count = self.model.objects.count()
url = reverse('{base_name}-list'.format(base_name=self.base_name))
self.client.force_authenticate(user=self.user1)
response = self.client.post(url, data)
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual(self.model.objects.count(), initial_count + 1)
instance = self.model.objects.get(id=initial_count+1)
for field in self.tested_fields.keys():
self.assertEqual(getattr(instance, field), data[field])
def test_user_update(self):
"""
ensure we can update an %model object using API
"""
instance = getattr(self, self.instance_name)
factory = APIRequestFactory()
instance_id = instance.id
url = reverse('{base_name}-detail'.format(base_name=self.base_name),
kwargs={'pk': instance_id})
request = factory.get(url)
data = self.serializer(instance, context={'request': request}).data
for field, value in self.tested_fields.items():
data[field] = value
self.client.force_authenticate(user=self.user1)
response = self.client.put(url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
instance.refresh_from_db()
for field, value in self.tested_fields.items():
self.assertEqual(getattr(instance, field), value)
def test_user_delete(self):
"""
ensure we can update an %model object using API
"""
instance = getattr(self, self.instance_name)
initial_count = self.model.objects.count()
instance_id = instance.id
url = reverse('{base_name}-detail'.format(base_name=self.base_name),
kwargs={'pk': instance_id})
self.client.force_authenticate(user=self.user1)
response = self.client.delete(url)
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
self.assertEqual(self.model.objects.count(), initial_count - 1)

View file

@ -78,7 +78,6 @@ REST_FRAMEWORK = {
'rest_framework.permissions.AllowAny', 'rest_framework.permissions.AllowAny',
], ],
'PAGE_SIZE': 10, 'PAGE_SIZE': 10,
'TEST_REQUEST_DEFAULT_FORMAT': 'json',
} }
ROOT_URLCONF = 'evenementiel.urls' ROOT_URLCONF = 'evenementiel.urls'