[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 json
from typing import Union, List, Optional, Set, Dict, Any
from uuid import UUID
from django.contrib.auth import get_user_model
from django.db import transaction
@ -326,9 +327,9 @@ class PackageManager(object):
return False
@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)
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.http import JsonResponse, HttpResponse, HttpResponseNotAllowed, HttpResponseBadRequest
from django.shortcuts import render, redirect
from django.urls import reverse
from django.views.decorators.csrf import csrf_exempt
from envipy_additional_information import NAME_MAPPING
from oauth2_provider.decorators import protected_resource
@ -81,7 +82,7 @@ def login(request):
if next := request.POST.get('next'):
return redirect(next)
return redirect(s.SERVER_URL)
return redirect(reverse("index"))
else:
context['message'] = "Login failed!"
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
from functools import wraps
from django.shortcuts import render
from django.shortcuts import get_object_or_404
from epdb.logic import PackageManager
from epdb.models import Package
# Map HTTP methods to required permissions
DEFAULT_METHOD_PERMISSIONS = {
@ -24,6 +25,9 @@ def package_permission_required(method_permissions=None):
user = _anonymous_or_real(request)
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):
from epdb.views import error
return error(