-
Notifications
You must be signed in to change notification settings - Fork 51
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'bsoc-bitbyte:main' into main
- Loading branch information
Showing
3 changed files
with
290 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
from rest_framework import permissions | ||
|
||
from .models import Event | ||
|
||
|
||
class IsOwnerOrReadOnly(permissions.BasePermission): | ||
""" | ||
Custom permission to only allow owners of an event to edit it. | ||
""" | ||
def has_object_permission(self, request, view, obj): | ||
# Read permissions are allowed to any request, so we'll always | ||
# allow GET, HEAD, or OPTIONS requests. | ||
if request.method in permissions.SAFE_METHODS: | ||
return True | ||
|
||
# Write permissions are only allowed to the owner/organizer of the event. | ||
return obj.organizer == request.user |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,271 @@ | ||
from django.test import TestCase | ||
import pytest | ||
from rest_framework.test import APIClient | ||
from rest_framework import status | ||
from .models import Event | ||
from accounts.models import Account | ||
|
||
# Create your tests here. | ||
account_data = { | ||
"email": "[email protected]", | ||
"password": "testpassword", | ||
"first_name": "test", | ||
"last_name": "account", | ||
"phone_number": "1234567890", | ||
"address": "test address", | ||
} | ||
|
||
event_data = { | ||
"title": "test event", | ||
"description": "test description", | ||
"organizer": "test organizer", | ||
"date": "2021-01-01", | ||
"time": "00:00:00", | ||
"event_type": "virtual", | ||
"location": "test location", | ||
"ticket_price": 0.0, | ||
} | ||
|
||
|
||
@pytest.fixture | ||
def test_user(): | ||
user = Account.objects.create(**account_data) | ||
return user | ||
|
||
|
||
@pytest.fixture | ||
def test_event(test_user): | ||
event_data_copy = event_data.copy() | ||
event_data_copy['organizer'] = test_user | ||
event = Event.objects.create(**event_data_copy) | ||
return event | ||
|
||
|
||
@pytest.fixture | ||
def authenticated_client(test_user): | ||
client = APIClient() | ||
client.force_authenticate(user=test_user) | ||
return client | ||
|
||
|
||
@pytest.mark.django_db | ||
def testEventCreation_withValidDetails_byAuthenticatedUser_shouldCreateEvent( | ||
test_user, authenticated_client): | ||
# Arrange | ||
event_data_copy = event_data.copy() | ||
event_data_copy['organizer'] = test_user.id | ||
|
||
# Act | ||
response = authenticated_client.post('/api/events/', event_data_copy, format='json') | ||
|
||
# Assert | ||
assert response.status_code == status.HTTP_201_CREATED | ||
assert Event.objects.count() == 1 | ||
assert Event.objects.get().title == event_data['title'] | ||
|
||
|
||
@pytest.mark.django_db | ||
@pytest.mark.parametrize('field, invalid_value', | ||
[('title', ''), | ||
('organizer', -1), | ||
('date', 'invalid_date'), | ||
('date', ''), | ||
('time', 'invalid_time'), | ||
('time', ''), | ||
('event_type', 'invalid_event_type'), | ||
('event_type', ''), | ||
('location', ''), | ||
('ticket_price', 'invalid_ticket_price'), | ||
('ticket_price', '')]) | ||
def testEventCreation_withInvalidDetails_byAuthenticatedUser_shouldNotCreateEvent( | ||
test_user, authenticated_client, field, invalid_value): | ||
# Arrange | ||
event_data_copy = event_data.copy() | ||
event_data_copy['organizer'] = test_user.id | ||
event_data_copy[field] = invalid_value | ||
|
||
# Act | ||
response = authenticated_client.post('/api/events/', event_data_copy, format='json') | ||
|
||
# Assert | ||
assert response.status_code == status.HTTP_400_BAD_REQUEST | ||
assert Event.objects.count() == 0 | ||
|
||
|
||
@pytest.mark.django_db | ||
def testEventCreation_withValidDetails_byUnauthenticatedUser_shouldNotCreateEvent(test_user): | ||
# Arrange | ||
unauthenticated_client = APIClient() | ||
event_data_copy = event_data.copy() | ||
event_data_copy['organizer'] = test_user.id | ||
|
||
# Act | ||
response = unauthenticated_client.post('/api/events/', event_data_copy, format='json') | ||
|
||
# Assert | ||
assert response.status_code == status.HTTP_403_FORBIDDEN | ||
assert Event.objects.count() == 0 | ||
|
||
|
||
@pytest.mark.django_db | ||
def testEventRetrieval_withValidEventId_byAuthenticatedUser_shouldRetrieveEvent(test_event, test_user): | ||
# Arrange | ||
unauthenticated_client = APIClient() | ||
|
||
# Act | ||
response = unauthenticated_client.get(f'/api/events/{test_event.id}/') | ||
|
||
# Assert | ||
assert response.status_code == status.HTTP_200_OK | ||
response.data.pop('created_at') | ||
response.data.pop('updated_at') | ||
response.data.pop('cover_image') | ||
assert response.data == {'title': event_data['title'], | ||
'organizer': test_user.id, | ||
'description': event_data['description'], | ||
'date': event_data['date'], | ||
'email': '', | ||
'event_type': 'virtual', | ||
'location': 'test location', | ||
'time': '00:00:00', | ||
'phone': '', | ||
'ticket_price': '0.00' | ||
} | ||
|
||
|
||
@pytest.mark.django_db | ||
def testEventRetrieval_withInvalidEventId_shouldThrowNotFound(test_event): | ||
# Arrange | ||
unauthenticated_client = APIClient() | ||
|
||
# Act | ||
response = unauthenticated_client.get(f'/api/events/{test_event.id + 1}/') | ||
|
||
# Assert | ||
assert response.status_code == status.HTTP_404_NOT_FOUND | ||
|
||
|
||
@pytest.mark.django_db | ||
def testListEventsView_shouldListEvents(test_event): | ||
# Arrange | ||
unauthenticated_client = APIClient() | ||
|
||
# Act | ||
response = unauthenticated_client.get('/api/events/') | ||
|
||
# Assert | ||
assert response.status_code == status.HTTP_200_OK | ||
assert len(response.data) == 1 | ||
response.data[0].pop('created_at') | ||
response.data[0].pop('updated_at') | ||
response.data[0].pop('cover_image') | ||
assert response.data[0] == {'title': event_data['title'], | ||
'organizer': test_event.organizer.id, | ||
'description': event_data['description'], | ||
'date': event_data['date'], | ||
'email': '', | ||
'event_type': 'virtual', | ||
'location': 'test location', | ||
'time': '00:00:00', | ||
'phone': '', | ||
'ticket_price': '0.00' | ||
} | ||
|
||
|
||
@pytest.mark.django_db | ||
def testEventUpdate_withValidEventId_byOwner_shouldUpdateEvent( | ||
test_user, authenticated_client, test_event): | ||
# Arrange | ||
event_data_copy = event_data.copy() | ||
event_data_copy['title'] = 'updated title' | ||
event_data_copy['organizer'] = test_user.id | ||
event_data_copy['date'] = '2021-01-02' | ||
|
||
# Act | ||
response = authenticated_client.put(f'/api/events/{test_event.id}/', | ||
event_data_copy, format='json') | ||
|
||
# Assert | ||
assert response.status_code == status.HTTP_200_OK | ||
assert response.data['title'] == 'updated title' | ||
assert response.data['date'] == '2021-01-02' | ||
assert Event.objects.get().title == 'updated title' | ||
assert Event.objects.get().date == '2021-01-02' | ||
|
||
|
||
@pytest.mark.django_db | ||
def testEventUpdate_withValidEventId_byNonOwner_shouldThrowForbidden( | ||
authenticated_client): | ||
# Arrange | ||
account_data_copy = account_data.copy() | ||
account_data_copy['email'] = '[email protected]' | ||
test_user_2 = Account.objects.create(**account_data_copy) | ||
event_data_copy = event_data.copy() | ||
event_data_copy['organizer'] = test_user_2 | ||
event = Event.objects.create(**event_data_copy) | ||
|
||
event_data_copy['title'] = 'updated title' | ||
event_data_copy['organizer'] = test_user_2.id | ||
|
||
# Act | ||
response = authenticated_client.put(f'/api/events/{event.id}/', event_data_copy, format='json') | ||
|
||
# Assert | ||
assert response.status_code == status.HTTP_403_FORBIDDEN | ||
assert Event.objects.get().title == event_data['title'] | ||
|
||
|
||
@pytest.mark.django_db | ||
def testEventUpdate_withInvalidEventId_shouldThrowNotFound( | ||
test_user, authenticated_client, test_event): | ||
# Arrange | ||
event_data_copy = event_data.copy() | ||
event_data_copy['title'] = 'updated title' | ||
event_data_copy['organizer'] = test_user.id | ||
|
||
# Act | ||
response = authenticated_client.put(f'/api/events/{test_event.id + 1}/', | ||
event_data_copy, format='json') | ||
|
||
# Assert | ||
assert response.status_code == status.HTTP_404_NOT_FOUND | ||
|
||
|
||
@pytest.mark.django_db | ||
def testEventDelete_withValidEventId_byOwner_shouldDeleteEvent(authenticated_client, test_event): | ||
# Arrange | ||
# Act | ||
response = authenticated_client.delete(f'/api/events/{test_event.id}/') | ||
|
||
# Assert | ||
assert response.status_code == status.HTTP_204_NO_CONTENT | ||
assert Event.objects.count() == 0 | ||
|
||
|
||
@pytest.mark.django_db | ||
def testEventDelete_withValidEventId_byNonOwner_shouldThrowForbidden( | ||
authenticated_client): | ||
# Arrange | ||
account_data_copy = account_data.copy() | ||
account_data_copy['email'] = '[email protected]' | ||
test_user_2 = Account.objects.create(**account_data_copy) | ||
|
||
event_data_copy = event_data.copy() | ||
event_data_copy['organizer'] = test_user_2 | ||
event = Event.objects.create(**event_data_copy) | ||
|
||
# Act | ||
response = authenticated_client.delete(f'/api/events/{event.id}/') | ||
|
||
# Assert | ||
assert response.status_code == status.HTTP_403_FORBIDDEN | ||
assert Event.objects.count() == 1 | ||
|
||
|
||
@pytest.mark.django_db | ||
def testEventDelete_withInvalidEventId_shouldThrowNotFound(authenticated_client, test_event): | ||
# Arrange | ||
# Act | ||
response = authenticated_client.delete(f'/api/events/{test_event.id + 1}/') | ||
|
||
# Assert | ||
assert response.status_code == status.HTTP_404_NOT_FOUND | ||
assert Event.objects.count() == 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters