Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend pipeline and user test coverage #754

Merged
merged 5 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ ignore_errors = true
[[tool.mypy.overrides]]
module = [
"common.helpers",
"tests.administration.test_users",
"tests.integration.*",
"tests.storage_service.test_helpers",
"tests.storage_service.test_oidc",
Expand Down
293 changes: 188 additions & 105 deletions tests/administration/test_users.py
Original file line number Diff line number Diff line change
@@ -1,125 +1,208 @@
from unittest import skipIf
import hmac
import uuid
from hashlib import sha1
from typing import Type
from unittest import mock

import pytest
import pytest_django
from administration import roles
from django.conf import settings
from django.contrib.auth.models import User
from django.test import TestCase
from django.test import Client
from django.urls import reverse
from tastypie.models import ApiKey


class TestUserManagement(TestCase):
def setUp(self):
self.user = User.objects.create_user(
username="admin",
password="admin",
email="[email protected]",
is_superuser=True,
)
self.client.login(username="admin", password="admin")
def as_reader(user: User) -> None:
user.set_role(roles.USER_ROLE_READER)

def as_reader(self):
self.user.set_role(roles.USER_ROLE_READER)

def as_manager(self):
self.user.set_role(roles.USER_ROLE_MANAGER)
def as_manager(user: User) -> None:
user.set_role(roles.USER_ROLE_MANAGER)

def test_list_users(self):
"""The user list is available to all users."""
resp = self.client.get(reverse("administration:user_list"))

self.assertContains(resp, "<td>[email protected]</td>")
@pytest.mark.django_db
def test_list_users(admin_client: Client) -> None:
"""The user list is available to all users."""
resp = admin_client.get(reverse("administration:user_list"))

@skipIf(not settings.ALLOW_USER_EDITS, "User edits are disabled")
def test_create_user_as_admin(self):
"""Only administrators are allowed to create new users."""
resp = self.client.post(
reverse("administration:user_create"),
{
"username": "demo",
"email": "[email protected]",
"role": "manager",
"password1": "ck61Qc873.KxoZ5G",
"password2": "ck61Qc873.KxoZ5G",
},
)
assert "<td>[email protected]</td>" in resp.content.decode()

self.assertRedirects(
resp,
reverse("administration:user_list"),
status_code=302,
target_status_code=200,
fetch_redirect_response=True,
)
assert User.objects.filter(username="demo").exists() is True

@skipIf(not settings.ALLOW_USER_EDITS, "User edits are disabled")
def test_create_user_as_non_admin(self):
"""Only administrators are allowed to create new users."""
self.as_reader()
resp = self.client.post(
reverse("administration:user_create"),
{
"username": "demo",
"email": "[email protected]",
"role": "manager",
"password1": "ck61Qc873.KxoZ5G",
"password2": "ck61Qc873.KxoZ5G",
},
)

self.assertRedirects(
resp,
reverse("administration:user_list"),
status_code=302,
target_status_code=200,
fetch_redirect_response=True,
)
assert User.objects.filter(username="demo").exists() is False
@pytest.fixture
def settings(
settings: pytest_django.fixtures.SettingsWrapper,
) -> pytest_django.fixtures.SettingsWrapper:
settings.ALLOW_USER_EDITS = True

@skipIf(not settings.ALLOW_USER_EDITS, "User edits are disabled")
def test_edit_user_promote_as_manager(self):
"""Only administrators are allowed to promote/demote users."""
test = User.objects.create_user(
username="test", password="ck61Qc873.KxoZ5G", email="[email protected]"
)
resp = self.client.post(
reverse("administration:user_edit", kwargs={"id": test.pk}),
{
"user": "Edit User",
"username": "test",
"email": "[email protected]",
"role": "manager",
},
follow=True,
)
return settings

assert list(resp.context["messages"])[0].message == "User information saved."
test.refresh_from_db()
assert test.get_role() == roles.USER_ROLE_MANAGER

@skipIf(not settings.ALLOW_USER_EDITS, "User edits are disabled")
def test_edit_user_promotion_requires_admin(self):
"""Only administrators are allowed to promote/demote users."""
self.as_manager()
test = User.objects.create_user(
username="test", password="ck61Qc873.KxoZ5G", email="[email protected]"
)
resp = self.client.post(
reverse("administration:user_edit", kwargs={"id": test.pk}),
@pytest.mark.django_db
def test_create_user_as_admin(
admin_client: Client, settings: pytest_django.fixtures.SettingsWrapper
) -> None:
"""Only administrators are allowed to create new users."""
resp = admin_client.post(
reverse("administration:user_create"),
{
"username": "demo",
"email": "[email protected]",
"role": "manager",
"password1": "ck61Qc873.KxoZ5G",
"password2": "ck61Qc873.KxoZ5G",
},
follow=True,
)
assert resp.status_code == 200

assert "<td>[email protected]</td>" in resp.content.decode()
assert User.objects.filter(username="demo").exists()


@pytest.mark.django_db
def test_create_user_as_non_admin(
admin_client: Client,
settings: pytest_django.fixtures.SettingsWrapper,
django_user_model: Type[User],
) -> None:
"""Only administrators are allowed to create new users."""
as_reader(django_user_model.objects.get(username="admin"))

resp = admin_client.post(
reverse("administration:user_create"),
{
"username": "demo",
"email": "[email protected]",
"role": "manager",
"password1": "ck61Qc873.KxoZ5G",
"password2": "ck61Qc873.KxoZ5G",
},
follow=True,
)
assert resp.status_code == 200

assert "<td>[email protected]</td>" not in resp.content.decode()
assert not User.objects.filter(username="demo").exists()


@pytest.fixture
def user(django_user_model: Type[User]) -> User:
return django_user_model.objects.create_user(
username="test", password="ck61Qc873.KxoZ5G", email="[email protected]"
)


@pytest.mark.django_db
def test_edit_user_promote_as_manager(
admin_client: Client,
settings: pytest_django.fixtures.SettingsWrapper,
user: User,
) -> None:
"""Only administrators are allowed to promote/demote users."""
resp = admin_client.post(
reverse("administration:user_edit", kwargs={"id": user.pk}),
{
"user": "Edit User",
"username": "test",
"email": "[email protected]",
"role": "manager",
},
follow=True,
)
assert resp.status_code == 200

assert list(resp.context["messages"])[0].message == "User information saved."
user.refresh_from_db()
assert user.get_role() == roles.USER_ROLE_MANAGER


@pytest.mark.django_db
def test_edit_user_promotion_requires_admin(
admin_client: Client,
settings: pytest_django.fixtures.SettingsWrapper,
django_user_model: Type[User],
user: User,
) -> None:
"""Only administrators are allowed to promote/demote users."""
as_manager(django_user_model.objects.get(username="admin"))

resp = admin_client.post(
reverse("administration:user_edit", kwargs={"id": user.pk}),
{
"user": "Edit User",
"username": "test",
"email": "[email protected]",
"role": "manager",
},
follow=True,
)
assert resp.status_code == 200

user.refresh_from_db()
assert user.get_role() == roles.USER_ROLE_READER


@pytest.fixture
def admin_user_apikey(admin_client: Client, django_user_model: Type[User]) -> ApiKey:
return ApiKey.objects.create(user=django_user_model.objects.get(username="admin"))


@pytest.mark.django_db
def test_user_edit_view_updates_password(
admin_client: Client,
settings: pytest_django.fixtures.SettingsWrapper,
django_user_model: Type[User],
admin_user_apikey: ApiKey,
) -> None:
user = django_user_model.objects.get(username="admin")
assert user.check_password("password")
new_password = "ck61Qc873.KxoZ5G"

response = admin_client.post(
reverse("administration:user_edit", kwargs={"id": user.pk}),
{
"new_password1": new_password,
"new_password2": new_password,
"password": "1",
},
follow=True,
)
assert response.status_code == 200

user.refresh_from_db()
assert user.check_password(new_password)
assert "Password changed" in response.content.decode()


@pytest.mark.django_db
def test_user_edit_view_regenerates_api_key(
admin_client: Client,
settings: pytest_django.fixtures.SettingsWrapper,
django_user_model: Type[User],
admin_user_apikey: ApiKey,
) -> None:
user = django_user_model.objects.get(username="admin")
assert user.check_password("password")
new_password = "ck61Qc873.KxoZ5G"
expected_uuid = uuid.uuid4()
expected_key = hmac.new(expected_uuid.bytes, digestmod=sha1).hexdigest()

with mock.patch("uuid.uuid4", return_value=expected_uuid):
response = admin_client.post(
reverse("administration:user_edit", kwargs={"id": user.pk}),
{
"user": "Edit User",
"username": "test",
"email": "[email protected]",
"role": "manager",
"new_password1": new_password,
"new_password2": new_password,
"password": "1",
},
follow=True,
)
assert response.status_code == 200

self.assertRedirects(
resp,
reverse("administration:user_list"),
status_code=302,
target_status_code=200,
fetch_redirect_response=True,
)
test.refresh_from_db()
assert test.get_role() == roles.USER_ROLE_READER
user.refresh_from_db()
assert user.check_password(new_password)
assert "Password changed" in response.content.decode()

admin_user_apikey.refresh_from_db()
assert admin_user_apikey.key == expected_key
Loading