-
Notifications
You must be signed in to change notification settings - Fork 86
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: geistling <[email protected]> update testing module
- Loading branch information
1 parent
082685d
commit 5b4b619
Showing
10 changed files
with
580 additions
and
0 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,21 @@ | ||
from coldfront.config.base import INSTALLED_APPS | ||
|
||
INSTALLED_APPS += [ | ||
'django_filters', | ||
'rest_framework', | ||
'coldfront.plugins.api' | ||
] | ||
|
||
REST_FRAMEWORK = { | ||
'DEFAULT_AUTHENTICATION_CLASSES': ( | ||
'rest_framework.authentication.TokenAuthentication', | ||
'rest_framework.authentication.SessionAuthentication', | ||
'rest_framework.authentication.BasicAuthentication', | ||
), | ||
'DEFAULT_PERMISSION_CLASSES': [ | ||
'rest_framework.permissions.IsAuthenticated' | ||
], | ||
'DEFAULT_FILTER_BACKENDS': [ | ||
'django_filters.rest_framework.DjangoFilterBackend' | ||
], | ||
} |
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
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
Empty file.
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,157 @@ | ||
from datetime import timedelta | ||
|
||
from django.contrib.auth import get_user_model | ||
from rest_framework import serializers | ||
|
||
from coldfront.core.resource.models import Resource | ||
from coldfront.core.project.models import Project, ProjectUser | ||
from coldfront.core.allocation.models import Allocation, AllocationChangeRequest | ||
|
||
|
||
class UserSerializer(serializers.ModelSerializer): | ||
|
||
class Meta: | ||
model = get_user_model() | ||
fields = ( | ||
'id', | ||
'username', | ||
'first_name', | ||
'last_name', | ||
'is_active', | ||
'is_superuser', | ||
'is_staff', | ||
'date_joined', | ||
) | ||
|
||
|
||
class ResourceSerializer(serializers.ModelSerializer): | ||
resource_type = serializers.SlugRelatedField(slug_field='name', read_only=True) | ||
|
||
class Meta: | ||
model = Resource | ||
fields = ('id', 'resource_type', 'name', 'description', 'is_allocatable') | ||
|
||
|
||
class AllocationSerializer(serializers.ModelSerializer): | ||
resource = serializers.ReadOnlyField(source='get_resources_as_string') | ||
project = serializers.SlugRelatedField(slug_field='title', read_only=True) | ||
status = serializers.SlugRelatedField(slug_field='name', read_only=True) | ||
|
||
class Meta: | ||
model = Allocation | ||
fields = ( | ||
'id', | ||
'project', | ||
'resource', | ||
'status', | ||
) | ||
|
||
|
||
class AllocationRequestSerializer(serializers.ModelSerializer): | ||
project = serializers.SlugRelatedField(slug_field='title', read_only=True) | ||
resource = serializers.ReadOnlyField(source='get_resources_as_string', read_only=True) | ||
status = serializers.SlugRelatedField(slug_field='name', read_only=True) | ||
fulfilled_date = serializers.DateTimeField(read_only=True) | ||
created_by = serializers.SerializerMethodField(read_only=True) | ||
fulfilled_by = serializers.SerializerMethodField(read_only=True) | ||
time_to_fulfillment = serializers.DurationField(read_only=True) | ||
|
||
class Meta: | ||
model = Allocation | ||
fields = ( | ||
'id', | ||
'project', | ||
'resource', | ||
'status', | ||
'created', | ||
'created_by', | ||
'fulfilled_date', | ||
'fulfilled_by', | ||
'time_to_fulfillment', | ||
) | ||
|
||
def get_created_by(self, obj): | ||
historical_record = obj.history.earliest() | ||
creator = historical_record.history_user if historical_record else None | ||
if not creator: | ||
return None | ||
return historical_record.history_user.username | ||
|
||
def get_fulfilled_by(self, obj): | ||
historical_records = obj.history.filter(status__name='Active') | ||
if historical_records: | ||
user = historical_records.earliest().history_user | ||
if user: | ||
return user.username | ||
return None | ||
|
||
|
||
class AllocationChangeRequestSerializer(serializers.ModelSerializer): | ||
allocation = AllocationSerializer(read_only=True) | ||
status = serializers.SlugRelatedField(slug_field='name', read_only=True) | ||
created_by = serializers.SerializerMethodField(read_only=True) | ||
fulfilled_date = serializers.DateTimeField(read_only=True) | ||
fulfilled_by = serializers.SerializerMethodField(read_only=True) | ||
time_to_fulfillment = serializers.DurationField(read_only=True) | ||
|
||
class Meta: | ||
model = AllocationChangeRequest | ||
fields = ( | ||
'id', | ||
'allocation', | ||
'justification', | ||
'status', | ||
'created', | ||
'created_by', | ||
'fulfilled_date', | ||
'fulfilled_by', | ||
'time_to_fulfillment', | ||
) | ||
|
||
def get_created_by(self, obj): | ||
historical_record = obj.history.earliest() | ||
creator = historical_record.history_user if historical_record else None | ||
if not creator: | ||
return None | ||
return historical_record.history_user.username | ||
|
||
def get_fulfilled_by(self, obj): | ||
if not obj.status.name == 'Approved': | ||
return None | ||
historical_record = obj.history.latest() | ||
fulfiller = historical_record.history_user if historical_record else None | ||
if not fulfiller: | ||
return None | ||
return historical_record.history_user.username | ||
|
||
|
||
class ProjAllocationSerializer(serializers.ModelSerializer): | ||
resource = serializers.ReadOnlyField(source='get_resources_as_string') | ||
status = serializers.SlugRelatedField(slug_field='name', read_only=True) | ||
|
||
class Meta: | ||
model = Allocation | ||
fields = ('id', 'resource', 'status') | ||
|
||
|
||
class ProjectUserSerializer(serializers.ModelSerializer): | ||
user = serializers.SlugRelatedField(slug_field='username', read_only=True) | ||
status = serializers.SlugRelatedField(slug_field='name', read_only=True) | ||
role = serializers.SlugRelatedField(slug_field='name', read_only=True) | ||
|
||
class Meta: | ||
model = ProjectUser | ||
fields = ('user', 'role', 'status') | ||
|
||
|
||
class ProjectSerializer(serializers.ModelSerializer): | ||
pi = serializers.SlugRelatedField(slug_field='username', read_only=True) | ||
status = serializers.SlugRelatedField(slug_field='name', read_only=True) | ||
project_users = ProjectUserSerializer( | ||
source='projectuser_set', many=True, read_only=True) | ||
allocations = ProjAllocationSerializer( | ||
source='allocation_set', many=True, read_only=True) | ||
|
||
class Meta: | ||
model = Project | ||
fields = ('id', 'title', 'pi', 'status', 'project_users', 'allocations') |
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,68 @@ | ||
from rest_framework import status | ||
from rest_framework.test import APITestCase | ||
from coldfront.core.allocation.models import Allocation | ||
from coldfront.core.project.models import Project | ||
|
||
|
||
class ColdfrontAPI(APITestCase): | ||
"""Tests for the Coldfront REST API""" | ||
|
||
def test_requires_login(self): | ||
"""Test that the API requires authentication""" | ||
response = self.client.get('/api/') | ||
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) | ||
|
||
def test_allocation_request_api_permissions(self): | ||
"""Test that accessing the allocation-request API view as an admin returns all | ||
allocations, and that accessing it as a user is forbidden""" | ||
# login as admin | ||
self.client.force_login(self.admin_user) | ||
response = self.client.get('/api/allocation-requests/', format='json') | ||
self.assertEqual(response.status_code, status.HTTP_200_OK) | ||
|
||
self.client.force_login(self.pi_user) | ||
response = self.client.get('/api/allocation-requests/', format='json') | ||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) | ||
|
||
def test_allocation_api_permissions(self): | ||
"""Test that accessing the allocation API view as an admin returns all | ||
allocations, and that accessing it as a user returns only the allocations | ||
for that user""" | ||
# login as admin | ||
self.client.force_login(self.admin_user) | ||
response = self.client.get('/api/allocations/', format='json') | ||
self.assertEqual(response.status_code, status.HTTP_200_OK) | ||
self.assertEqual(len(response.data), Allocation.objects.all().count()) | ||
|
||
self.client.force_login(self.pi_user) | ||
response = self.client.get('/api/allocations/', format='json') | ||
self.assertEqual(response.status_code, status.HTTP_200_OK) | ||
self.assertEqual(len(response.data), 2) | ||
|
||
def test_project_api_permissions(self): | ||
"""Confirm permissions for project API: | ||
admin user should be able to access everything | ||
Projectusers should be able to access only their projects | ||
""" | ||
# login as admin | ||
self.client.force_login(self.admin_user) | ||
response = self.client.get('/api/projects/', format='json') | ||
self.assertEqual(response.status_code, status.HTTP_200_OK) | ||
self.assertEqual(len(response.data), Project.objects.all().count()) | ||
|
||
self.client.force_login(self.pi_user) | ||
response = self.client.get('/api/projects/', format='json') | ||
self.assertEqual(response.status_code, status.HTTP_200_OK) | ||
self.assertEqual(len(response.data), 1) | ||
|
||
def test_user_api_permissions(self): | ||
"""Test that accessing the user API view as an admin returns all | ||
allocations, and that accessing it as a user is forbidden""" | ||
# login as admin | ||
self.client.force_login(self.admin_user) | ||
response = self.client.get('/api/users/', format='json') | ||
self.assertEqual(response.status_code, status.HTTP_200_OK) | ||
|
||
self.client.force_login(self.pi_user) | ||
response = self.client.get('/api/users/', format='json') | ||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) |
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,16 @@ | ||
from django.urls import include, path | ||
from rest_framework import routers | ||
from coldfront.plugins.api import views | ||
|
||
router = routers.DefaultRouter() | ||
router.register(r'allocations', views.AllocationViewSet, basename='allocations') | ||
router.register(r'allocation-requests', views.AllocationRequestViewSet, basename='allocation-requests') | ||
router.register(r'allocation-change-requests', views.AllocationChangeRequestViewSet, basename='allocation-change-requests') | ||
router.register(r'projects', views.ProjectViewSet, basename='projects') | ||
router.register(r'resources', views.ResourceViewSet, basename='resources') | ||
router.register(r'users', views.UserViewSet, basename='users') | ||
|
||
urlpatterns = [ | ||
path('', include(router.urls)), | ||
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')) | ||
] |
Oops, something went wrong.