Skip to content

Commit

Permalink
add ui logic and tests (#1090)
Browse files Browse the repository at this point in the history
  • Loading branch information
mikkonie committed Jan 21, 2025
1 parent 24930d3 commit ba70721
Show file tree
Hide file tree
Showing 4 changed files with 296 additions and 143 deletions.
26 changes: 16 additions & 10 deletions projectroles/templates/projectroles/project_form.html
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,10 @@
<h3 id="sodar-pr-project-form-title" data-project-type={{ object.type }}>
Update {% get_display_name object.type title=True %}
</h3>
{% if object.type == 'PROJECT' %}
<div class="btn-group ml-auto" role="group">
{# TODO: Add logic to disable button with tooltip #}
<a role="button" class="btn btn-danger"
href="{% url 'projectroles:delete' project=object.sodar_uuid %}"
id="sodar-pr-btn-delete">
<i class="iconify" data-icon="mdi:close-thick"></i> Delete
</a>

{# TODO: Convert to btn-group, how to enable tooltip for disabled button? #}
<div class="ml-auto">
{% if object.type == 'PROJECT' %}
<a role="button" class="btn btn-warning"
href="{% url 'projectroles:archive' project=object.sodar_uuid %}"
id="sodar-pr-btn-archive">
Expand All @@ -58,8 +54,18 @@ <h3 id="sodar-pr-project-form-title" data-project-type={{ object.type }}>
<i class="iconify" data-icon="mdi:archive-arrow-down"></i> Unarchive
{% endif %}
</a>
</div>
{% endif %}
{% endif %}
<span class="d-inline-block" tabindex="0" data-toggle="tooltip"
id="sodar-pr-btn-delete-tooltip"
title="{{ project_delete_msg }}">
<a role="button" class="btn btn-danger"
href="{% url 'projectroles:delete' project=object.sodar_uuid %}"
{% if not project_delete_access %}disabled="disabled"{% endif %}
id="sodar-pr-btn-delete">
<i class="iconify" data-icon="mdi:close-thick"></i> Delete
</a>
</span>
</div>
{% elif parent.pk %}
<h2>Create {{ project_display }} or {{ category_display }} Under {{ parent.title }}</h2>
{% elif disable_categories %}
Expand Down
79 changes: 79 additions & 0 deletions projectroles/tests/test_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -1773,6 +1773,12 @@ def test_archive_button(self):
[self.superuser], self.url_top, 'sodar-pr-btn-archive', False
)

def test_delete_button(self):
"""Test rendering form without delete button"""
self.assert_element_exists(
[self.superuser], self.url_top, 'sodar-pr-btn-delete', False
)

def test_fields_top(self):
"""Test rendering of dynamic fields for top level creation view"""
self.login_and_redirect(self.superuser, self.url_top)
Expand Down Expand Up @@ -1897,6 +1903,79 @@ def test_archive_button_archived(self):
element = self.selenium.find_element(By.ID, 'sodar-pr-btn-archive')
self.assertEqual(element.text, 'Unarchive')

def test_delete_button(self):
"""Test rendering delete button"""
self.login_and_redirect(self.superuser, self.url)
elem = self.selenium.find_element(By.ID, 'sodar-pr-btn-delete')
self.assertIsNone(elem.get_attribute('disabled'))

def test_delete_button_category_with_children(self):
"""Test rendering delete button with category and children"""
self.login_and_redirect(self.superuser, self.url_cat)
elem = self.selenium.find_element(By.ID, 'sodar-pr-btn-delete')
self.assertEqual(elem.get_attribute('disabled'), 'true')

def test_delete_button_category_no_children(self):
"""Test rendering delete button with category and no children"""
self.project.delete()
self.login_and_redirect(self.superuser, self.url_cat)
elem = self.selenium.find_element(By.ID, 'sodar-pr-btn-delete')
self.assertIsNone(elem.get_attribute('disabled'))

def test_delete_button_remote(self):
"""Test rendering delete button with non-revoked remote project"""
self.remote_project = self.make_remote_project(
project_uuid=self.project.sodar_uuid,
site=self.remote_site,
level=REMOTE_LEVEL_READ_ROLES,
project=self.project,
)
self.login_and_redirect(self.superuser, self.url)
elem = self.selenium.find_element(By.ID, 'sodar-pr-btn-delete')
self.assertEqual(elem.get_attribute('disabled'), 'true')

def test_delete_button_remote_revoked(self):
"""Test rendering delete button with revoked remote project"""
self.remote_project = self.make_remote_project(
project_uuid=self.project.sodar_uuid,
site=self.remote_site,
level=REMOTE_LEVEL_REVOKED,
project=self.project,
)
self.login_and_redirect(self.superuser, self.url)
elem = self.selenium.find_element(By.ID, 'sodar-pr-btn-delete')
self.assertIsNone(elem.get_attribute('disabled'))

@override_settings(PROJECTROLES_SITE_MODE=SITE_MODE_TARGET)
def test_delete_button_remote_target(self):
"""Test rendering delete button with non-revoked remote project as target site"""
self.remote_site.mode = SITE_MODE_SOURCE
self.remote_site.save()
self.remote_project = self.make_remote_project(
project_uuid=self.project.sodar_uuid,
site=self.remote_site,
level=REMOTE_LEVEL_READ_ROLES,
project=self.project,
)
self.login_and_redirect(self.superuser, self.url)
elem = self.selenium.find_element(By.ID, 'sodar-pr-btn-delete')
self.assertEqual(elem.get_attribute('disabled'), 'true')

@override_settings(PROJECTROLES_SITE_MODE=SITE_MODE_TARGET)
def test_delete_button_remote_revoked_target(self):
"""Test rendering delete button with non-revoked remote project as target site"""
self.remote_site.mode = SITE_MODE_SOURCE
self.remote_site.save()
self.remote_project = self.make_remote_project(
project_uuid=self.project.sodar_uuid,
site=self.remote_site,
level=REMOTE_LEVEL_REVOKED,
project=self.project,
)
self.login_and_redirect(self.superuser, self.url)
elem = self.selenium.find_element(By.ID, 'sodar-pr-btn-delete')
self.assertIsNone(elem.get_attribute('disabled'))

def test_fields_project(self):
"""Test field visibility for project update"""
self.login_and_redirect(self.superuser, self.url)
Expand Down
50 changes: 47 additions & 3 deletions projectroles/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@
LOGIN_MSG,
TARGET_CREATE_DISABLED_MSG,
SITE_SETTING_UPDATE_MSG,
PROJECT_DELETE_CAT_ERR_MSG,
PROJECT_DELETE_SOURCE_ERR_MSG,
PROJECT_DELETE_TARGET_ERR_MSG,
)
from projectroles.context_processors import (
SIDEBAR_ICON_MIN_SIZE,
Expand Down Expand Up @@ -1168,6 +1171,8 @@ def test_get_project(self):
with self.login(self.user):
response = self.client.get(self.url)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context['project_delete_access'], True)
self.assertEqual(response.context['project_delete_msg'], '')
form = response.context['form']
self.assertIsNotNone(form)
self.assertIsInstance(form.fields['type'].widget, HiddenInput)
Expand Down Expand Up @@ -1195,7 +1200,7 @@ def test_get_remote_site_owner_modifiable_disabled(self):
form = response.context['form']
self.assertNotIn(REMOTE_SITE_FIELD, form.fields)

def test_get_remote_project(self):
def test_get_remote(self):
"""Test GET with remote target project and READ_ROLES perm"""
self.make_remote_project(
project_uuid=self.project.sodar_uuid,
Expand All @@ -1206,10 +1211,15 @@ def test_get_remote_project(self):
with self.login(self.user):
response = self.client.get(self.url)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context['project_delete_access'], False)
self.assertEqual(
response.context['project_delete_msg'],
PROJECT_DELETE_SOURCE_ERR_MSG.format(project_type='project'),
)
form = response.context['form']
self.assertEqual(form.fields[REMOTE_SITE_FIELD].initial, True)

def test_get_remote_projcet_revoked(self):
def test_get_remote_revoked(self):
"""Test GET with remote target project and REVOKED perm"""
self.make_remote_project(
project_uuid=self.project.sodar_uuid,
Expand All @@ -1220,10 +1230,12 @@ def test_get_remote_projcet_revoked(self):
with self.login(self.user):
response = self.client.get(self.url)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context['project_delete_access'], True)
self.assertEqual(response.context['project_delete_msg'], '')
form = response.context['form']
self.assertEqual(form.fields[REMOTE_SITE_FIELD].initial, False)

def test_get_remote_project_read_info(self):
def test_get_remote_read_info(self):
"""Test GET with remote target project and READ_INFO perm"""
self.make_remote_project(
project_uuid=self.project.sodar_uuid,
Expand Down Expand Up @@ -1262,19 +1274,38 @@ def test_get_category(self):
with self.login(self.user):
response = self.client.get(self.url_cat)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context['project_delete_access'], False)
self.assertEqual(
response.context['project_delete_msg'],
PROJECT_DELETE_CAT_ERR_MSG.format(project_type='category'),
)
form = response.context['form']
self.assertIsInstance(form.fields['type'].widget, HiddenInput)
self.assertNotIsInstance(form.fields['parent'].widget, HiddenInput)
self.assertIsInstance(form.fields['owner'].widget, HiddenInput)
self.assertNotIn(REMOTE_SITE_FIELD, form.fields)

def test_get_category_no_children(self):
"""Test GET with category and no children"""
self.project.delete()
with self.login(self.user):
response = self.client.get(self.url_cat)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context['project_delete_access'], True)
self.assertEqual(response.context['project_delete_msg'], '')

@override_settings(PROJECTROLES_SITE_MODE=SITE_MODE_TARGET)
def test_get_remote_as_target(self):
"""Test GET with remote project as target"""
self.set_up_as_target(projects=[self.category, self.project])
with self.login(self.user):
response = self.client.get(self.url)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context['project_delete_access'], False)
self.assertEqual(
response.context['project_delete_msg'],
PROJECT_DELETE_TARGET_ERR_MSG.format(project_type='project'),
)
form = response.context['form']
self.assertIsInstance(form.fields['title'].widget, HiddenInput)
self.assertIsInstance(form.fields['type'].widget, HiddenInput)
Expand Down Expand Up @@ -1319,6 +1350,19 @@ def test_get_remote_as_target(self):
form.fields['settings.projectroles.ip_allowlist'].disabled
)

@override_settings(PROJECTROLES_SITE_MODE=SITE_MODE_TARGET)
def test_get_remote_as_target_revoked(self):
"""Test GET with revoked remote project as target"""
self.set_up_as_target(projects=[self.category, self.project])
rp = RemoteProject.objects.get(project=self.project)
rp.level = REMOTE_LEVEL_REVOKED
rp.save()
with self.login(self.user):
response = self.client.get(self.url)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context['project_delete_access'], True)
self.assertEqual(response.context['project_delete_msg'], '')

def test_get_not_found(self):
"""Test GET with invalid project UUID"""
with self.login(self.user):
Expand Down
Loading

0 comments on commit ba70721

Please sign in to comment.