Skip to content

Commit

Permalink
Extend pipeline and user test coverage
Browse files Browse the repository at this point in the history
* Convert pipeline test into pytest tests
* Add tests for pipeline detail view
* Extend pipeline edit tests
* Convert user tests into pytest tests
* Add test for updating the user password
  • Loading branch information
replaceafill authored Dec 10, 2024
1 parent 9e915ce commit 2a6ce3a
Show file tree
Hide file tree
Showing 3 changed files with 399 additions and 257 deletions.
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

0 comments on commit 2a6ce3a

Please sign in to comment.