[Feature] Register / Login / Logout View Testing (#126)

Co-authored-by: Tim Lorsbach <tim@lorsba.ch>
Reviewed-on: enviPath/enviPy#126
This commit is contained in:
2025-09-19 06:44:25 +12:00
parent b3079834c1
commit b5c759d74e
7 changed files with 271 additions and 4 deletions

View File

@ -2,6 +2,7 @@ import re
import logging import logging
import json import json
from typing import Union, List, Optional, Set, Dict, Any from typing import Union, List, Optional, Set, Dict, Any
from uuid import UUID
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.db import transaction from django.db import transaction
@ -326,9 +327,9 @@ class PackageManager(object):
return False return False
@staticmethod @staticmethod
def has_package_permission(user: 'User', package: Union[str, 'Package'], permission: str): def has_package_permission(user: 'User', package: Union[str, UUID, 'Package'], permission: str):
if isinstance(package, str): if isinstance(package, str) or isinstance(package, UUID):
package = Package.objects.get(uuid=package) package = Package.objects.get(uuid=package)
groups = GroupManager.get_groups(user) groups = GroupManager.get_groups(user)

View File

@ -6,6 +6,7 @@ from django.conf import settings as s
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.http import JsonResponse, HttpResponse, HttpResponseNotAllowed, HttpResponseBadRequest from django.http import JsonResponse, HttpResponse, HttpResponseNotAllowed, HttpResponseBadRequest
from django.shortcuts import render, redirect from django.shortcuts import render, redirect
from django.urls import reverse
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
from envipy_additional_information import NAME_MAPPING from envipy_additional_information import NAME_MAPPING
from oauth2_provider.decorators import protected_resource from oauth2_provider.decorators import protected_resource
@ -81,7 +82,7 @@ def login(request):
if next := request.POST.get('next'): if next := request.POST.get('next'):
return redirect(next) return redirect(next)
return redirect(s.SERVER_URL) return redirect(reverse("index"))
else: else:
context['message'] = "Login failed!" context['message'] = "Login failed!"
return render(request, 'static/login.html', context) return render(request, 'static/login.html', context)

File diff suppressed because one or more lines are too long

0
tests/views/__init__.py Normal file
View File

View File

@ -0,0 +1,180 @@
from django.conf import settings as s
from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import TestCase, tag
from django.urls import reverse
from epdb.logic import UserManager
from epdb.models import Package, UserPackagePermission, Permission, GroupPackagePermission, Group
class PackageViewTest(TestCase):
fixtures = ["test_fixtures.jsonl.gz"]
@classmethod
def setUpClass(cls):
super(PackageViewTest, cls).setUpClass()
cls.user1 = UserManager.create_user("user1", "user1@envipath.com", "SuperSafe",
set_setting=False, add_to_group=True, is_active=True)
cls.user2 = UserManager.create_user("user2", "user2@envipath.com", "SuperSafe",
set_setting=False, add_to_group=True, is_active=True)
def setUp(self):
self.client.force_login(self.user1)
def test_create_package(self):
response = self.client.post(reverse("packages"), {
"package-name": "Test Package",
"package-description": "Just a Description",
})
self.assertEqual(response.status_code, 302)
package_url = response.url
p = Package.objects.get(url=package_url)
self.assertEqual(p.name, "Test Package")
self.assertEqual(p.description, "Just a Description")
upp = UserPackagePermission.objects.get(package=p, user=self.user1)
self.assertEqual(upp.permission, Permission.ALL[0])
def test_import_package(self):
file = SimpleUploadedFile(
"Fixture_Package.json",
open(s.FIXTURE_DIRS[0] / "Fixture_Package.json", "rb").read(),
content_type="application/json"
)
response = self.client.post(reverse("packages"), {
"file": file,
"hidden": "import-package-json"
})
self.assertEqual(response.status_code, 302)
package_url = response.url
p = Package.objects.get(url=package_url)
self.assertEqual(p.pathways.count(), 22)
self.assertEqual(p.rules.count(), 45)
self.assertEqual(p.compounds.count(), 223)
self.assertEqual(p.reactions.count(), 212)
upp = UserPackagePermission.objects.get(package=p, user=self.user1)
self.assertEqual(upp.permission, Permission.ALL[0])
@tag("slow")
def test_import_legacy_package(self):
file = SimpleUploadedFile(
"EAWAG-BBD.json",
open(s.FIXTURE_DIRS[0] / "packages" / "2025-07-18" / "EAWAG-BBD.json", "rb").read(),
content_type="application/json"
)
response = self.client.post(reverse("packages"), {
"file": file,
"hidden": "import-legacy-package-json"
})
self.assertEqual(response.status_code, 302)
package_url = response.url
p = Package.objects.get(url=package_url)
self.assertEqual(p.pathways.count(), 219)
self.assertEqual(p.rules.count(), 498)
self.assertEqual(p.compounds.count(), 1399)
self.assertEqual(p.reactions.count(), 1480)
self.assertEqual(p.scenarios.count(), 1914)
upp = UserPackagePermission.objects.get(package=p, user=self.user1)
self.assertEqual(upp.permission, Permission.ALL[0])
def test_edit_package(self):
response = self.client.post(reverse("packages"), {
"package-name": "Test Package",
"package-description": "Just a Description",
})
self.assertEqual(response.status_code, 302)
package_url = response.url
self.client.post(package_url, {
"package-name": "New Name",
"package-description": "New Description",
})
p = Package.objects.get(url=package_url)
self.assertEqual(p.name, "New Name")
self.assertEqual(p.description, "New Description")
def test_edit_package_permissions(self):
response = self.client.post(reverse("packages"), {
"package-name": "Test Package",
"package-description": "Just a Description",
})
self.assertEqual(response.status_code, 302)
package_url = response.url
p = Package.objects.get(url=package_url)
with self.assertRaises(UserPackagePermission.DoesNotExist):
UserPackagePermission.objects.get(package=p, user=self.user2)
self.client.post(package_url, {
"grantee": self.user2.url,
"read": "on",
"write": "on",
})
upp = UserPackagePermission.objects.get(package=p, user=self.user2)
self.assertEqual(upp.permission, Permission.WRITE[0])
def test_publish_package(self):
response = self.client.post(reverse("packages"), {
"package-name": "Test Package",
"package-description": "Just a Description",
})
self.assertEqual(response.status_code, 302)
package_url = response.url
p = Package.objects.get(url=package_url)
self.client.post(package_url, {
"hidden": "publish-package"
})
self.assertEqual(Group.objects.filter(public=True).count(), 1)
g = Group.objects.get(public=True)
gpp = GroupPackagePermission.objects.get(package=p, group=g)
self.assertEqual(gpp.permission, Permission.READ[0])
def test_set_package_license(self):
response = self.client.post(reverse("packages"), {
"package-name": "Test Package",
"package-description": "Just a Description",
})
package_url = response.url
p = Package.objects.get(url=package_url)
self.client.post(package_url, {
"license": "no-license"
})
self.assertIsNone(p.license)
# TODO test others
def test_delete_package(self):
response = self.client.post(reverse("packages"), {
"package-name": "Test Package",
"package-description": "Just a Description",
})
package_url = response.url
p = Package.objects.get(url=package_url)
p.delete()
response = self.client.get(package_url)
self.assertEqual(response.status_code, 404)

View File

@ -0,0 +1,80 @@
from django.test import TestCase
from epdb.logic import PackageManager
from epdb.models import Package, User
from django.urls import reverse
class UserViewTest(TestCase):
fixtures = ["test_fixtures.jsonl.gz"]
@classmethod
def setUpClass(cls):
super(UserViewTest, cls).setUpClass()
cls.user = User.objects.get(username='anonymous')
cls.package = PackageManager.create_package(cls.user, 'Anon Test Package', 'No Desc')
cls.BBD_SUBSET = Package.objects.get(name='Fixtures')
def test_login_with_valid_credentials(self):
response = self.client.post(reverse("login"), {
"username": "user0",
"password": 'SuperSafe',
})
self.assertRedirects(response, reverse("index"))
self.assertTrue(response.wsgi_request.user.is_authenticated)
def test_login_with_invalid_credentials(self):
response = self.client.post(reverse("login"), {
"username": "user0",
"password": "wrongpassword",
})
self.assertEqual(response.status_code, 200)
self.assertFalse(response.wsgi_request.user.is_authenticated)
def test_register(self):
response = self.client.post(reverse("register"), {
"username": "user1",
"email": "user1@envipath.com",
"password": "SuperSafe",
"rpassword": "SuperSafe",
})
self.assertEqual(response.status_code, 200)
# TODO currently fails as the fixture does not provide a global setting...
self.assertContains(response, "Registration failed!")
def test_register_password_mismatch(self):
response = self.client.post(reverse("register"), {
"username": "user1",
"email": "user1@envipath.com",
"password": "SuperSafe",
"rpassword": "SuperSaf3",
})
self.assertEqual(response.status_code, 200)
self.assertContains(response, "Registration failed, provided passwords differ")
def test_logout(self):
response = self.client.post(reverse("login"), {
"username": "user0",
"password": 'SuperSafe',
"login": "true"
})
self.assertTrue(response.wsgi_request.user.is_authenticated)
response = self.client.post(reverse('logout'), {
"logout": "true",
})
self.assertFalse(response.wsgi_request.user.is_authenticated)
def test_next_param_properly_handled(self):
response = self.client.get(reverse('packages'))
self.assertRedirects(response, f"{reverse('login')}/?next=/package")
response = self.client.post(reverse('login'), {
"username": "user0",
"password": 'SuperSafe',
"login": "true",
"next": "/package"
})
self.assertRedirects(response, reverse('packages'))

View File

@ -1,9 +1,10 @@
# decorators.py # decorators.py
from functools import wraps from functools import wraps
from django.shortcuts import render from django.shortcuts import get_object_or_404
from epdb.logic import PackageManager from epdb.logic import PackageManager
from epdb.models import Package
# Map HTTP methods to required permissions # Map HTTP methods to required permissions
DEFAULT_METHOD_PERMISSIONS = { DEFAULT_METHOD_PERMISSIONS = {
@ -24,6 +25,9 @@ def package_permission_required(method_permissions=None):
user = _anonymous_or_real(request) user = _anonymous_or_real(request)
permission_required = method_permissions[request.method] permission_required = method_permissions[request.method]
# Check if the requested Package exists
get_object_or_404(Package, uuid=package_uuid)
if not PackageManager.has_package_permission(user, package_uuid, permission_required): if not PackageManager.has_package_permission(user, package_uuid, permission_required):
from epdb.views import error from epdb.views import error
return error( return error(