Update unit testing and remove relative imports

master
Joshua Rubingh 6 months ago
parent 2ea79195f5
commit 6ab73d1239
  1. 4
      .drone.yml
  2. 2
      VRE/apps/storage/admin.py
  3. 2
      VRE/apps/storage/apps.py
  4. 4
      VRE/apps/storage/models.py
  5. 2
      VRE/apps/storage/serializers.py
  6. 2
      VRE/apps/storage/signals.py
  7. 4
      VRE/apps/storage/views.py
  8. 0
      VRE/apps/study/tests/__init__.py
  9. 10
      VRE/apps/study/tests/test_models.py
  10. 65
      VRE/apps/study/tests/test_urls.py
  11. 72
      VRE/apps/study/tests/test_views.py
  12. 4
      VRE/apps/study/urls.py
  13. 4
      VRE/apps/study/views.py
  14. 0
      VRE/storages/README.md
  15. 0
      VRE/storages/__init__.py
  16. 0
      VRE/storages/engines/fs.py
  17. 0
      VRE/storages/engines/gitea.py
  18. 0
      VRE/storages/engines/github.py
  19. 0
      VRE/storages/engines/irods.py
  20. 0
      VRE/storages/engines/webdav.py
  21. 0
      VRE/storages/exceptions.py
  22. 2
      VRE/storages/storage.py
  23. 0
      VRE/storages/utils.py

@ -110,9 +110,7 @@ steps:
OIDC_OP_JWKS_ENDPOINT: dummy
commands:
- cd VRE
- python manage.py test apps/api
- python manage.py test apps/study
- python manage.py test apps/researcher
- python manage.py test apps
depends_on:
- build-docker-image

@ -1,6 +1,6 @@
from django.contrib import admin
from .models import StorageEngine, StorageLocation
from apps.storage.models import StorageEngine, StorageLocation
@admin.register(StorageEngine)

@ -9,4 +9,4 @@ class StorageConfig(AppConfig):
verbose_name_plural = _('Storages')
def ready(self):
from . import signals
from apps.storage import signals

@ -13,8 +13,8 @@ from lib.utils.general import get_random_int_value, generate_encryption_key
# Here we import the different storage engine libraries. TODO: Should this be somehow some external part? Does not look right to do it here...
from django.template.defaultfilters import slugify
from storage.storage import Storage
import storage.exceptions as StorageException
from storages.storage import Storage
import storages.exceptions as StorageException
class StorageEngineType(models.TextChoices):

@ -1,5 +1,5 @@
from rest_framework import serializers
from .models import StorageEngine, StorageLocation
from apps.storage.models import StorageEngine, StorageLocation
class StorageEngineSerializer(serializers.ModelSerializer):

@ -1,7 +1,7 @@
from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import StorageLocation
from apps.storage.models import StorageLocation
@receiver(post_save, sender=StorageLocation)

@ -1,5 +1,5 @@
from .serializers import StorageEngineSerializer, StorageLocationSerializer
from .models import StorageEngine, StorageLocation
from apps.storage.serializers import StorageEngineSerializer, StorageLocationSerializer
from apps.storage.models import StorageEngine, StorageLocation
from lib.api.base import BaseViewSet

@ -15,7 +15,9 @@ class StudyCreateTest(TestCase):
fixtures = ('university_initial_data', 'virtual_machine_initial_data')
@classmethod
def setUpTestData(cls):
def setUpClass(cls):
super().setUpClass()
cls.firstname = 'Albert'
cls.lastname = 'Einstein'
cls.email = 'dummy@rug.nl'
@ -280,7 +282,7 @@ class StudyCreateTest(TestCase):
# Get the first study through Django Models, which should be the new created study
study = Study.objects.get(contributors__in=[self.user.researcher])
endpoint = 'http://testserver' + reverse('api:v1:study-contributors', kwargs={'study_id': study.id, 'contributor_id': study.owner.pk})
endpoint = 'http://testserver' + reverse('api:v1:study-contributor-detail', kwargs={'study_id': study.id, 'contributor_id': study.owner.pk})
response = self.client.delete(endpoint)
@ -302,13 +304,13 @@ class StudyCreateTest(TestCase):
role=StudyRoleNames.ADMIN,
active=True)
endpoint = 'http://testserver' + reverse('api:v1:study-contributors', kwargs={'study_id': study.id, 'contributor_id': contributor.pk})
endpoint = 'http://testserver' + reverse('api:v1:study-contributor-detail', kwargs={'study_id': study.id, 'contributor_id': contributor.pk})
response = self.client.delete(endpoint)
# First admin can be deleted
self.assertEqual(response.status_code, 204)
# Last admin is owner, which should fail again
endpoint = 'http://testserver' + reverse('api:v1:study-contributors', kwargs={'study_id': study.id, 'contributor_id': current_admin.pk})
endpoint = 'http://testserver' + reverse('api:v1:study-contributor-detail', kwargs={'study_id': study.id, 'contributor_id': current_admin.pk})
response = self.client.delete(endpoint)
# First admin can be deleted
self.assertEqual(response.status_code, 400)

@ -0,0 +1,65 @@
from django.test import TestCase
from django.urls import resolve
from apps.study.views import Contributors, process_study_invite, show_invite, validate_invite
class StudyURLsTestCase(TestCase):
"""
A collection of simple tests to test all the used Study API urls
"""
def test_study_contributors_list(self):
"""
Test that the contributors of a study list to a 'Contributors view'
"""
# path = resolve(reverse('api:v1:study-contributors', kwargs={'study_id' : 1}))
path = resolve('/api/v1/studies/1/contributors/')
self.assertEqual(path.kwargs['study_id'], 1)
self.assertEqual(path.func.__name__, Contributors.as_view({'get': 'list'}).__name__)
def test_study_contributor_detail(self):
"""
Test that the contributors detail url uses the 'Contributors view'
"""
# path = resolve(reverse('api:v1:study-contributor-detail', kwargs={'study_id' : 1, 'contributor_id' : 1}))
path = resolve('/api/v1/studies/1/contributors/1/')
self.assertEqual(path.kwargs['study_id'], 1)
self.assertEqual(path.kwargs['contributor_id'], 1)
self.assertEqual(path.func.__name__, Contributors.as_view({'get': 'get', 'put': 'update', 'delete': 'delete'}).__name__)
def test_study_send_invite(self):
"""
Test that the contributor invite page show the 'process_study_invite' function
"""
# path = resolve(reverse('api:v1:study-invite', kwargs={'study_id' : 1}))
path = resolve('/api/v1/studies/1/contributors/invite/')
self.assertEqual(path.kwargs['study_id'], 1)
self.assertEqual(path.func, process_study_invite)
def test_study_show_invite(self):
"""
Test that the contributor invitation is shown by the 'show_invite' function
"""
# path = resolve(reverse('api:v1:study-invite-join', kwargs={'study_id' : 1}))
path = resolve('/api/v1/studies/1/contributors/join/')
self.assertEqual(path.kwargs['study_id'], 1)
self.assertEqual(path.func, show_invite)
def test_study_validate_invite(self):
"""
Test that the contributor validation action is processed by 'validate_invite' function
"""
#path = resolve(reverse('api:v1:study-invite-join-validate', kwargs={'study_id' : 1, 'jwt_token' : 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'}))
path = resolve('/api/v1/studies/1/contributors/join/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c/')
self.assertEqual(path.kwargs['study_id'], 1)
self.assertEqual(path.kwargs['jwt_token'], 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c')
self.assertEqual(path.func, validate_invite)

@ -0,0 +1,72 @@
from django.contrib.auth.models import User
from django.urls import reverse
from django.test import TestCase
from rest_framework.test import RequestsClient
from apps.study.models import Study
from apps.university.models import Faculty, StudyField
class StudyViewsTestCase(TestCase):
fixtures = ('university_initial_data',)
@classmethod
def setUpTestData(cls):
cls.testserver = 'http://testserver'
# Create a researcher as user to test with
user = User.objects.create_user(username='testuser1', password='testPassword', email='a@dummy.org')
user.first_name = 'John'
user.last_name = 'Doe'
user.save()
# Make a researcher member of a faculty
user.researcher.faculty = Faculty.objects.get(pk=13)
# Save the updated researcher
user.researcher.save()
# Map the researcher to this test class
cls.researcher = user.researcher
# Create a study and add a contributor
cls.study = Study.objects.create(
**{
'name': 'Test Onderzoek',
'description': 'Doe maar een lange onderzoek',
'code': '12345',
'human_subject': False,
'field': StudyField.objects.filter(faculty=cls.researcher.faculty).first(),
'owner' : cls.researcher
}
)
cls.study.contributors.set([cls.researcher])
def setUp(self):
# We want to use the API REST Framework request client, as this enables us to use HAWK authentication during testing
self.client = RequestsClient()
# Get a JWT token
login_data = {'username': 'testuser1', 'password': 'testPassword'}
endpoint = self.testserver + reverse('api:jwt-create')
response = self.client.post(endpoint, json=login_data)
self.client.headers.update({'Authorization': 'JWT ' + response.json()['access']})
def test_index_view_basic(self):
"""
Test that contributor list view returns a 200 response and uses
the correct template
"""
endpoint = self.testserver + reverse('api:v1:study-contributors', kwargs={'study_id': self.study.pk})
response = self.client.get(endpoint)
self.assertEqual(response.status_code, 200)
content = response.json()
self.assertEqual(len(content['results']), 1)
self.assertEqual(content['results'][0]['researcher']['email_address'], self.researcher.user.email)

@ -4,10 +4,10 @@ from .views import Contributors, process_study_invite, show_invite, validate_inv
urlpatterns = [
path('<int:study_id>/contributors/', Contributors.as_view({'get': 'list'}), name='study-contributors'),
path('<int:study_id>/contributors/<int:contributor_id>/', Contributors.as_view({'get': 'get', 'put': 'update', 'delete': 'delete'}), name='study-contributors'),
path('<int:study_id>/contributors/<int:contributor_id>/', Contributors.as_view({'get': 'get', 'put': 'update', 'delete': 'delete'}), name='study-contributor-detail'),
path('<int:study_id>/contributors/invite/', process_study_invite, name='study-invite'),
path('<int:study_id>/contributors/join/<path:jwt_token>/', validate_invite, name='study-invite-join'),
path('<int:study_id>/contributors/join/<path:jwt_token>/', validate_invite, name='study-invite-join-validate'),
path('<int:study_id>/contributors/join/', show_invite, name='study-invite-join'),
]

@ -113,7 +113,7 @@ class Studies(ModelViewSet):
"""
# Check if logged in user is an admin for this study
study = get_object_or_404(Study, pk=study_response.data['id'], contributors__in=[self.request.user.researcher])
study = get_object_or_404(Study, pk=kwargs['pk'], contributors__in=[self.request.user.researcher])
if not (study.owner == request.user.researcher or study.is_an_admin(request.user.researcher)):
raise PermissionDenied(_('You are not allowed to update this study.'))
@ -127,7 +127,7 @@ class Studies(ModelViewSet):
@swagger_auto_schema(responses={200: StudyRoleSerializer(many=True)})
@action(detail=False, methods=['get'])
def roles(self, request):
"""Get all the availabe researcher roles for a study.
"""Get all the available researcher roles for a study.
Args:
request ([type]): The incoming web request

@ -1,6 +1,6 @@
import shlex
import subprocess
import storage.exceptions as StorageException
import storages.exceptions as StorageException
import importlib
from pathlib import Path
import re
Loading…
Cancel
Save