diff --git a/dashboard/conftest.py b/dashboard/conftest.py index 25a9e35..3ef9017 100644 --- a/dashboard/conftest.py +++ b/dashboard/conftest.py @@ -50,6 +50,18 @@ def user_can_change_projectobjective(client): return user +@pytest.fixture +def user_can_change_project(client): + user = User.objects.create_user(username="change_project", password="password") + permission = Permission.objects.get( + codename="change_project", + content_type__app_label="projects", + ) + user.user_permissions.add(permission) + client.login(username="change_project", password="password") + return user + + @pytest.fixture def user_can_change_workcycle(client): user = User.objects.create_user(username="change_workcycle", password="password") diff --git a/dashboard/projects/test_views.py b/dashboard/projects/test_views.py index cd3ab7b..371ebd1 100644 --- a/dashboard/projects/test_views.py +++ b/dashboard/projects/test_views.py @@ -84,6 +84,80 @@ def reason(): return Reason.objects.create(name="not-started", value=1) +@pytest.mark.django_db +def test_project_basic_form_save_denies_unauthenticated_user(client, project): + original_owner = project.owner + url = reverse("projects:project_basic_form_save", args=[project.id]) + response = client.post( + url, + data={ + "name": project.name, + "url": project.url, + "group": "", + "owner": "changed owner", + "driver": project.driver or "", + "agreement_status": "", + "last_review": "", + "last_review_status": "", + }, + ) + + project.refresh_from_db() + assert response.status_code == 302 + assert response.url == f"{reverse('login')}?next={url}" + assert project.owner == original_owner + + +@pytest.mark.django_db +def test_project_basic_form_save_denies_user_without_permission( + client, user_without_permissions, project +): + original_owner = project.owner + url = reverse("projects:project_basic_form_save", args=[project.id]) + response = client.post( + url, + data={ + "name": project.name, + "url": project.url, + "group": "", + "owner": "changed owner", + "driver": project.driver or "", + "agreement_status": "", + "last_review": "", + "last_review_status": "", + }, + ) + + project.refresh_from_db() + assert response.status_code == 302 + assert response.url == f"{reverse('login')}?next={url}" + assert project.owner == original_owner + + +@pytest.mark.django_db +def test_project_basic_form_save_allows_user_with_permission( + client, user_can_change_project, project +): + url = reverse("projects:project_basic_form_save", args=[project.id]) + response = client.post( + url, + data={ + "name": project.name, + "url": project.url, + "group": "", + "owner": "changed owner", + "driver": project.driver or "", + "agreement_status": "", + "last_review": "", + "last_review_status": "", + }, + ) + + project.refresh_from_db() + assert response.status_code == 200 + assert project.owner == "changed owner" + + @pytest.mark.django_db def test_action_toggle_commitment_denies_user_without_permission( client, user_without_permissions, commitment diff --git a/dashboard/projects/views.py b/dashboard/projects/views.py index 4e88c26..73e7a89 100644 --- a/dashboard/projects/views.py +++ b/dashboard/projects/views.py @@ -234,6 +234,7 @@ def action_select_reason(request, projectobjective_id): # form methods +@permission_required("projects.change_project") @require_http_methods(["POST"]) def project_basic_form_save(request, project_id): instance = Project.objects.get(id=project_id)