Skip to content

Commit

Permalink
Merge branch 'Spynacz:backend' into backend
Browse files Browse the repository at this point in the history
  • Loading branch information
Rafa13io authored May 23, 2024
2 parents ca99b5b + 5f50614 commit 498c6b2
Show file tree
Hide file tree
Showing 16 changed files with 292 additions and 52 deletions.
2 changes: 1 addition & 1 deletion backend/events/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class Event(models.Model):
title = models.CharField(_('title'), max_length=150)
desc = models.CharField(_('description'), max_length=300)
picture = models.ImageField(_('picture'), blank=True, null=True)
start = models.DateTimeField(_('start date'), blank=True, null=False)
start = models.DateTimeField(_('start date'), blank=True, null=True)
end = models.DateTimeField(_('end date'), blank=True, null=True)
location = models.ForeignKey(Location, related_name='event',
on_delete=models.DO_NOTHING)
Expand Down
48 changes: 43 additions & 5 deletions backend/events/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ class Meta:
model = models.Event
fields = '__all__'

def to_representation(self, instance):
rep = super().to_representation(instance)
rep['location'] = self.get_location(instance)
return rep

def create(self, validated_data):
event = models.Event.objects.create(**validated_data)
models.Role.objects.create(
Expand All @@ -46,11 +51,17 @@ def update(self, instance, validated_data):
self._schedule_reminder(instance)
return instance

def get_location(self, event):
return {
'id': event.location.id,
'address_line': event.location.address_line,
}


class EventDetailsSerializer(EventFeedSerializer):
event_contacts = serializers.SerializerMethodField()
social_media = serializers.SerializerMethodField()
location = serializers.SerializerMethodField()
ticket = serializers.SerializerMethodField()

def get_event_contacts(self, event):
response = []
Expand Down Expand Up @@ -81,6 +92,18 @@ def get_location(self, event):
'country': event.location.country
}

def get_ticket(self, event):
response = []
for ticket in event.ticket.all():
response.append({
'id': ticket.id,
'title': ticket.title,
'desc': ticket.desc,
'quantity': ticket.quantity,
'amount': ticket.amount
})
return response


class RoleSerializer(ValidateUserInContextMixin,
serializers.ModelSerializer):
Expand Down Expand Up @@ -167,14 +190,14 @@ class Meta:
fields = "__all__"

def validate_quantity(self, quantity):
if quantity < 0:
raise ValidationError("Ticket quantity cannot be lower than 0")
if quantity <= 0:
raise ValidationError("Ticket quantity cannot be lower or equal 0")

return quantity

def validate_amount(self, amount):
if amount < 0:
raise ValidationError("Amount cannot be lower than 0")
if amount <= 0:
raise ValidationError("Amount cannot be lower or equal 0")

return amount

Expand All @@ -187,11 +210,26 @@ class CartItemSerializer(serializers.Serializer):
ticket_type = serializers.ChoiceField(choices=TICKET_CHOICES)
quantity = serializers.IntegerField()
amount = serializers.DecimalField(max_digits=9, decimal_places=2)
ticket = serializers.IntegerField()
total_amount = serializers.SerializerMethodField()

class Meta:
fields = "__all__"

def to_representation(self, instance):
rep = super().to_representation(instance)
id = instance.get('ticket')
ticket = models.Ticket.objects.get(id=id)
rep['ticket'] = {
'id': ticket.id,
'title': ticket.title,
'desc': ticket.desc,
'quantity': ticket.quantity,
'amount': ticket.amount,
'event': ticket.event.id
}
return rep

def get_total_amount(self, cart_item):
return (decimal.Decimal(cart_item.get("amount"))
* decimal.Decimal(cart_item.get("quantity"))
Expand Down
149 changes: 142 additions & 7 deletions backend/events/tests/tests_serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,12 @@ def setUp(self):
# TODO split test
@patch('events.serializers.EventFeedSerializer.send_reminders.apply_async')
def test_create(self, mock_apply_async):
"""create method should make an owner role
for the user that creates it and also should schedule the proces of creating notifications."""

request = self.factory.get(reverse('events:event-list'))
"""
create method should make an owner role
for the user that creates it and also should
schedule the proces of creating notifications.
"""
request = self.factory.post(reverse('events:event-list'))
request.user = self.user

serializer = self.serializer_class(
Expand All @@ -105,7 +107,10 @@ def test_create(self, mock_apply_async):
)

def test_send_reminders(self):
"""Before the event start there should be notifications created for each intrested user"""
"""
Before the event start there should be notifications
created for each intrested user
"""
event = Event.objects.create(
title='test1',
desc='Test test1',
Expand Down Expand Up @@ -144,8 +149,10 @@ def test_send_reminders(self):
@patch('events.serializers.EventFeedSerializer.revoke_task')
@patch('events.serializers.EventFeedSerializer.send_reminders.apply_async')
def test_update(self, mock_apply_async, mock_revoke_task):
"""When event updated scheduled task should deleted and new task should be scheduled"""

"""
When event updated scheduled task should deleted
and new task should be scheduled
"""
request = self.factory.put(reverse('events:event-list'))
request.user = self.user
event = Event.objects.create(
Expand Down Expand Up @@ -484,3 +491,131 @@ def test_create_notifications(self):

self.assertEqual(Notification.objects.count(), 1)
self.assertDictEqual(serializer.validated_data, self.data)


class TestScheduleItem(TestCase):
def setUp(self):
self.serializer_class = serializers.ScheduleItemSerializer
self.user = ConcertifyUser.objects.create(
username="test",
email='test@email.com',
password='test'
)
location = Location.objects.create(
name='test',
address_line='test',
city='test',
postal_code='test',
country='TST'
)
self.event = Event.objects.create(
title='test1',
desc='Test test1',
location=location
)
Role.objects.create(
user=self.user,
event=self.event,
name=Role.NameChoice.OWNER
)
self.data = {
'title': 'test',
'desc': 'test',
'place': 'test',
'event': self.event.id
}

def test_schedule_time_valid(self):
"""Adding schedule with future date will pass"""
self.data.update(when=timezone.now() + timezone.timedelta(days=1))
serializer = self.serializer_class(data=self.data)
serializer.is_valid(raise_exception=True)

def test_schedule_time_invalid(self):
"""Adding schedule with past date will raise an error"""
self.data.update(when=timezone.now() - timezone.timedelta(days=1))
serializer = self.serializer_class(data=self.data)
with self.assertRaisesMessage(
ValidationError,
"You can't create a schedule with items in the past"):
serializer.is_valid(raise_exception=True)


class TestTicketSerializer(TestCase):
def setUp(self):
self.serializer_class = serializers.TicketSerializer
self.user = ConcertifyUser.objects.create(
username="test",
email='test@email.com',
password='test'
)
location = Location.objects.create(
name='test',
address_line='test',
city='test',
postal_code='test',
country='TST'
)
self.event = Event.objects.create(
title='test1',
desc='Test test1',
location=location
)
Role.objects.create(
user=self.user,
event=self.event,
name=Role.NameChoice.OWNER
)
self.data = {
'title': 'test',
'desc': 'test',
'quantity': 1,
'amount': 1.11,
'event': self.event.id
}

def test_quantity_less_than_zero(self):
"""Setting quantity lower than will raise an error"""
self.data.update(quantity=-1)
serializer = self.serializer_class(data=self.data)
with self.assertRaisesMessage(
ValidationError,
"Ticket quantity cannot be lower or equal 0"):
serializer.is_valid(raise_exception=True)

def test_quantity_equal_zero(self):
"""Setting quantity lower than will raise an error"""
self.data.update(quantity=0)
serializer = self.serializer_class(data=self.data)
with self.assertRaisesMessage(
ValidationError,
"Ticket quantity cannot be lower or equal 0"):
serializer.is_valid(raise_exception=True)

def test_quantity_valid(self):
"""Setting quantity lower than will raise an error"""
serializer = self.serializer_class(data=self.data)
serializer.is_valid(raise_exception=True)

def test_amount_equal_zero(self):
"""Setting amount lower than will raise an error"""
self.data.update(amount=0)
serializer = self.serializer_class(data=self.data)
with self.assertRaisesMessage(
ValidationError,
"Amount cannot be lower or equal 0"):
serializer.is_valid(raise_exception=True)

def test_amount_less_than_zero(self):
"""Setting amount lower than will raise an error"""
self.data.update(amount=-1)
serializer = self.serializer_class(data=self.data)
with self.assertRaisesMessage(
ValidationError,
"Amount cannot be lower or equal 0"):
serializer.is_valid(raise_exception=True)

def test_amount_valid(self):
"""Setting amount lower than will raise an error"""
serializer = self.serializer_class(data=self.data)
serializer.is_valid(raise_exception=True)
12 changes: 10 additions & 2 deletions backend/events/tests/tests_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,12 @@ def test_update_action(self):
self.client.credentials(HTTP_AUTHORIZATION=self.token)
serializer = EventFeedSerializer(instance=self.event1)
data = serializer.data
data.update({'title': 'PUT', 'picture': ""})
id = data['location'].get('id')
data.update({
'title': 'PUT',
'picture': "",
'location': id
})

response = self.client.put(self.url_details, data=data)
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
Expand All @@ -121,9 +126,12 @@ def test_update_action(self):
name=Role.NameChoice.MODERATOR)
response = self.client.put(self.url_details, data=data)
data.update({'picture': None})
response_data = response.data
id = response_data['location'].get('id')
response_data.update({'location': id})

self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertDictEqual(data, response.data)
self.assertDictEqual(data, response_data)

def test_partial_update_action(self):
"""Only users with at least moderator permission
Expand Down
22 changes: 22 additions & 0 deletions backend/posts_comments/routers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from rest_framework.routers import Route, DynamicRoute, SimpleRouter


class VoteRouter(SimpleRouter):
routes = [
Route(
url=r'^{prefix}{trailing_slash}$',
mapping={
'delete': 'destroy',
'post': 'create'
},
name='{basename}-list',
detail=False,
initkwargs={'suffix': 'List'}
),
DynamicRoute(
url=r'^{prefix}/{url_path}{trailing_slash}$',
name='{basename}-{url_name}',
detail=False,
initkwargs={}
)
]
9 changes: 4 additions & 5 deletions backend/posts_comments/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
from rest_framework.exceptions import ValidationError

from events.mixins import ValidateUserInContextMixin
from events.models import Role
from events.serializers import NotificationSerializer
from posts_comments import models
from posts_comments.mixins import VoteMixin

from events.serializers import NotificationSerializer
from events.models import Role

from users import models as users_models
from users.serializers import ReadOnlyUserSerializer


class PostSerializer(VoteMixin,
Expand Down Expand Up @@ -61,13 +60,13 @@ def update(self, instance, validated_data):
class CommentSerializer(VoteMixin,
ValidateUserInContextMixin,
serializers.ModelSerializer):
user = ReadOnlyUserSerializer(read_only=True)
vote_count = serializers.SerializerMethodField()
has_voted = serializers.SerializerMethodField()

class Meta:
model = models.Comment
fields = '__all__'
extra_kwargs = {'user': {'read_only': True}}

def validate(self, attrs):
attrs = super().validate(attrs)
Expand Down
15 changes: 8 additions & 7 deletions backend/posts_comments/tests/tests_permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,9 @@ def setUp(self):
email='testtest1@email.com',
password='testtest1'
)
post = Post.objects.first()
post_vote = PostVote.objects.create(user=self.user1, post=post)
self.url = reverse('posts_comments:post-vote-detail',
kwargs={'pk': post_vote.id})
self.post = Post.objects.first()
PostVote.objects.create(user=self.user1, post=self.post)
self.url = reverse('posts_comments:post-vote-list')

def test_not_authenticated(self):
"""Unauthenticated user shouldn't be able to acces the view"""
Expand All @@ -38,14 +37,16 @@ def test_is_owner(self):
"""User that is bound to the object can edit it"""
token = f"Token {AuthToken.objects.create(user=self.user1)[-1]}"
self.client.credentials(HTTP_AUTHORIZATION=token)
response = self.client.delete(self.url)
data = {'post': self.post.id}
response = self.client.delete(self.url, data=data)

self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)

def test_is_not_owner(self):
"""User that is not bound to the object cannot edit it"""
token = f"Token {AuthToken.objects.create(user=self.user)[-1]}"
self.client.credentials(HTTP_AUTHORIZATION=token)
response = self.client.delete(self.url)
data = {'post': self.post.id}
response = self.client.delete(self.url, data=data)

self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
Loading

0 comments on commit 498c6b2

Please sign in to comment.