from datetime import datetime, timedelta from django.contrib.auth import get_user_model from django.utils import timezone from rest_framework.test import APITestCase from event.models import Event, Place, ActivityTag, ActivityTemplate from api.test.testcases import ModelAPITestCaseMixin from api.test.utils import json_format User = get_user_model() class EventAPITests(ModelAPITestCaseMixin, APITestCase): model = Event url_label = 'event' list_ordering = 'beginning_date' @property def user_auth_mapping(self): return { 'create': self.user, } def get_expected_data(self, instance): return json_format({ 'url': ( 'http://testserver/api/event/{pk}/' .format(pk=instance.pk) ), 'id': instance.id, 'title': instance.title, 'slug': instance.slug, 'description': instance.description, 'beginning_date': instance.beginning_date, 'ending_date': instance.ending_date, 'created_by': instance.created_by.get_full_name(), 'created_at': self.now, }) @property def instances_data(self): return [ { 'title': "A first event", 'slug': 'first-event', 'description': "It's the first event.", 'beginning_date': self.now + timedelta(days=100), 'ending_date': self.now + timedelta(days=120), 'created_by': self.user, }, { 'title': "Another event", 'slug': 'another-event', 'description': "It's another event.", 'beginning_date': self.now + timedelta(days=50), 'ending_date': self.now + timedelta(days=60), 'created_by': self.user, }, ] @property def create_data(self): return { 'title': "An Event", 'slug': 'event', 'description': "I am an event.", 'beginning_date': '2017-08-10 05:30:00', 'ending_date': '2017-10-21 17:16:20', } @property def create_expected(self): return { **self.create_data, 'beginning_date': timezone.make_aware( datetime(2017, 8, 10, 5, 30, 0)), 'ending_date': timezone.make_aware( datetime(2017, 10, 21, 17, 16, 20)), 'id': 1, 'created_by': self.user, 'created_at': self.now, } @property def update_data(self): return { 'title': "An updated event.", 'slug': 'first-event', 'description': "It's the first updated event.", 'beginning_date': '2017-08-10 05:30:00', 'ending_date': '2017-10-21 17:16:20', 'created_by': 1, } @property def update_expected(self): return { **self.update_data, 'beginning_date': timezone.make_aware( datetime(2017, 8, 10, 5, 30, 0)), 'ending_date': timezone.make_aware( datetime(2017, 10, 21, 17, 16, 20)), 'id': 1, 'created_by': self.user, 'created_at': self.now, } class ActivityTemplateAPITests(ModelAPITestCaseMixin, APITestCase): model = ActivityTemplate url_label = 'activitytemplate' list_ordering = 'title' def setUp(self): super().setUp() self.event = Event.objects.create(**{ 'title': "event1", 'slug': "slug1", 'beginning_date': self.now + timedelta(days=30), 'description': "C'est trop cool !", 'ending_date': self.now + timedelta(days=31), 'created_by': self.user, }) self.activity_tag = ActivityTag.objects.create(**{ 'name': "tag2", 'is_public': False, 'color': "#222", }) def get_url_model(self, *args, **kwargs): kwargs['event_pk'] = 1 return super().get_url_model(*args, **kwargs) def get_url_object(self, *args, **kwargs): kwargs['event_pk'] = 1 return super().get_url_object(*args, **kwargs) def get_expected_data(self, instance): return json_format({ 'url': ( 'http://testserver/api/event/{event_pk}/template/{pk}/' .format(event_pk=instance.event.pk, pk=instance.pk) ), 'id': instance.id, 'title': instance.title, 'is_public': instance.is_public, 'remarks': instance.remarks, 'event': instance.event.pk, 'tags': [ { **(tag.event and { 'url': ( 'http://testserver/api/event/{event_pk}/' 'tag/{tag_pk}/' .format(event_pk=tag.event.pk, tag_pk=tag.pk) ), 'event': tag.event.pk, } or { 'url': ( 'http://testserver/api/tag/{tag_pk}/' .format(tag_pk=tag.pk) ), 'event': None, }), 'id': tag.id, 'name': tag.name, 'is_public': tag.is_public, 'color': tag.color, } for tag in instance.tags.all() ], 'has_perm': instance.has_perm, 'min_perm': instance.min_perm, 'max_perm': instance.max_perm, 'description': instance.description, }) @property def instances_data(self): return [ { 'title': "act temp1", 'is_public': True, 'remarks': "test remark", 'event': self.event, }, { 'title': "act temp2", 'is_public': False, 'remarks': "test remark", 'event': self.event, 'tags': [self.activity_tag] }, ] @property def create_data(self): return { 'title': "act temp2", 'is_public': False, 'remarks': "test remark", 'tags': [ { 'name': "tag2", 'is_public': False, 'color': '#222', }, ], } @property def create_expected(self): return { **self.create_data, 'tags': [ActivityTag.objects.get(name='tag2')], } @property def update_data(self): return { 'title': "act temp3", 'is_public': False, 'remarks': "another test remark", 'tags': [ { 'name': "tag2", 'is_public': False, 'color': '#222', }, { 'name': "body", 'is_public': True, 'color': '#555', }, ], } @property def update_expected(self): tag_root = ActivityTag.objects.get(name='tag2') self.assertIsNone(tag_root.event) tag_bound = ActivityTag.objects.get(name='body') self.assertEqual(tag_bound.event, self.event) return { 'title': "act temp3", 'is_public': False, 'remarks': "another test remark", 'tags': [tag_root, tag_bound] } class BaseActivityTagAPITests: model = ActivityTag url_label = 'activitytag' list_ordering = ('is_public', 'name') def setUp(self): super().setUp() self.event = Event.objects.create(**{ 'title': "event1", 'slug': "slug1", 'beginning_date': self.now + timedelta(days=30), 'description': "C'est trop cool !", 'ending_date': self.now + timedelta(days=31), 'created_by': self.user, }) def get_expected_data(self, instance): return { **(instance.event and { 'url': ( 'http://testserver/api/event/{event_pk}/tag/{pk}/' .format(event_pk=instance.event.pk, pk=instance.pk) ), 'event': instance.event.pk, } or { 'url': ( 'http://testserver/api/tag/{pk}/' .format(pk=instance.pk) ), 'event': None, }), 'id': instance.id, 'name': instance.name, 'is_public': instance.is_public, 'color': instance.color, } @property def instances_data(self): return [ { 'name': 'a tag', 'is_public': False, 'color': '#222', 'event': None, }, { 'name': 'another tag', 'is_public': True, 'color': '#555', 'event': self.event, } ] @property def create_data(self): return { 'name': 'plop tag', 'is_public': True, 'color': '#888999', } @property def update_data(self): return { 'name': 'this is the tag', 'is_public': True, 'color': '#333', } class RootActivityTagAPITests( BaseActivityTagAPITests, ModelAPITestCaseMixin, APITestCase ): @property def list_expected(self): return [ActivityTag.objects.get(name='a tag')] @property def create_expected(self): return { **self.create_data, 'event': None, } @property def instance_data(self): data = self.instances_data[0] self.assertIsNone( data['event'], msg="This test should use a tag unbound to any event.", ) return data @property def update_expected(self): return { **self.update_data, 'event': None, } class EventActivityTagAPITests( BaseActivityTagAPITests, ModelAPITestCaseMixin, APITestCase ): def get_url_model(self, *args, **kwargs): kwargs['event_pk'] = 1 return super().get_url_model(*args, **kwargs) def get_url_object(self, *args, **kwargs): kwargs['event_pk'] = 1 return super().get_url_object(*args, **kwargs) @property def list_expected(self): return [ ActivityTag.objects.get(name='a tag'), ActivityTag.objects.get(name='another tag'), ] @property def create_expected(self): return { **self.create_data, 'event': self.event, } @property def instance_data(self): data = self.instances_data[1] self.assertIsNotNone( data['event'], msg="This test should use an event-bound tag.", ) return data @property def update_expected(self): return { **self.update_data, 'event': self.event, } class BasePlaceAPITests: model = Place url_label = 'place' list_ordering = 'name' def setUp(self): super().setUp() self.event = Event.objects.create(**{ 'title': "event1", 'slug': "slug1", 'beginning_date': self.now + timedelta(days=30), 'description': "C'est trop cool !", 'ending_date': self.now + timedelta(days=31), 'created_by': self.user, }) def get_expected_data(self, instance): return { **(instance.event and { 'url': ( 'http://testserver/api/event/{event_pk}/place/{pk}/' .format(event_pk=instance.event.pk, pk=instance.pk) ), 'event': instance.event.pk, } or { 'url': ( 'http://testserver/api/place/{pk}/' .format(pk=instance.pk) ), 'event': None, }), 'id': instance.id, 'name': instance.name, 'description': instance.description, } @property def instances_data(self): return [ { 'name': 'a place', 'event': None, 'description': 'a description', }, { 'name': 'another place', 'event': self.event, } ] @property def create_data(self): return { 'name': 'plop place', 'description': 'the couro is a chill place', } @property def update_data(self): return { 'name': 'this is the place', 'description': 'to be', } class RootPlaceAPITests( BasePlaceAPITests, ModelAPITestCaseMixin, APITestCase ): @property def list_expected(self): return [Place.objects.get(name='a place')] @property def create_expected(self): return { **self.create_data, 'event': None, } @property def instance_data(self): data = self.instances_data[0] self.assertIsNone( data['event'], msg="This test should use a place unbound to any event.", ) return data @property def update_expected(self): return { **self.update_data, 'event': None, } class EventPlaceTagAPITests( BasePlaceAPITests, ModelAPITestCaseMixin, APITestCase ): def get_url_model(self, *args, **kwargs): kwargs['event_pk'] = 1 return super().get_url_model(*args, **kwargs) def get_url_object(self, *args, **kwargs): kwargs['event_pk'] = 1 return super().get_url_object(*args, **kwargs) @property def list_expected(self): return [ Place.objects.get(name='a place'), Place.objects.get(name='another place'), ] @property def create_expected(self): return { **self.create_data, 'event': self.event, } @property def instance_data(self): data = self.instances_data[1] self.assertIsNotNone( data['event'], msg="This test should use an event-bound place.", ) return data @property def update_expected(self): return { **self.update_data, 'event': self.event, }