Skip to content

Commit

Permalink
add sheet version create tag (#1296), add templatetag tests (#1723)
Browse files Browse the repository at this point in the history
  • Loading branch information
gromdimon authored Aug 15, 2023
1 parent 9e5f2d9 commit f7cfd4b
Show file tree
Hide file tree
Showing 7 changed files with 235 additions and 4 deletions.
2 changes: 2 additions & 0 deletions docs_manual/source/app_samplesheets_version.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ Most Recent
The most recently updated version.
Import
Version imported into SODAR from existing ISA-Tab files.
Create
Version created from Template.
Edit
Version edited within the Sample Sheets app of SODAR.
Restore
Expand Down
1 change: 1 addition & 0 deletions samplesheets/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ def save(self):
project=self.project,
archive_name=None,
user=self.current_user,
from_template=True,
)


Expand Down
4 changes: 3 additions & 1 deletion samplesheets/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,7 @@ def import_isa(
replace=False,
replace_uuid=None,
save_isa=True,
from_template=False,
):
"""
Import ISA investigation and its studies/assays from a dictionary of
Expand All @@ -530,6 +531,7 @@ def import_isa(
:param replace: Whether replacing an existing sheet (bool)
:param replace_uuid: Investigation UUID if replacing (UUID or string)
:param save_isa: Save ISA-Tab as backup after importing (bool)
:param from_template: Whether importing from a template (bool)
:return: Investigation
:raise: SampleSheetExportException if critical warnings are raised
"""
Expand Down Expand Up @@ -820,7 +822,7 @@ def import_isa(
# Save original ISA-Tab data
# TODO: TBD: Prevent saving if previous data matches current one?
if save_isa:
tags = ['IMPORT']
tags = ['CREATE'] if from_template else ['IMPORT']
if replace:
tags.append('REPLACE')
self.save_isa(
Expand Down
1 change: 1 addition & 0 deletions samplesheets/templatetags/samplesheets_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

# Local constants
TAG_COLORS = {
'CREATE': 'info',
'IMPORT': 'info',
'EDIT': 'warning',
'REPLACE': 'danger',
Expand Down
218 changes: 218 additions & 0 deletions samplesheets/tests/test_templatetags.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
"""Tests for template tags in the samplesheets app"""

from django.conf import settings
from django.urls import reverse

from test_plus.test import TestCase

from projectroles.models import SODAR_CONSTANTS
from projectroles.plugins import get_backend_api
from projectroles.tests.test_models import (
ProjectMixin,
RoleMixin,
RoleAssignmentMixin,
)

from samplesheets.models import GENERIC_MATERIAL_TYPES
from samplesheets.templatetags import samplesheets_tags as s_tags
from samplesheets.tests.test_models import (
SampleSheetModelMixin,
INV_IDENTIFIER,
INV_FILE_NAME,
INV_TITLE,
DEFAULT_DESCRIPTION,
DEFAULT_COMMENTS,
INV_ARCHIVE_NAME,
STUDY_IDENTIFIER,
STUDY_FILE_NAME,
STUDY_TITLE,
ASSAY_FILE_NAME,
ASSAY_TECH_PLATFORM,
ASSAY_TECH_TYPE,
ASSAY_MEASURE_TYPE,
)

# Local constants
IRODS_SAMPLE_COLL = settings.IRODS_SAMPLE_COLL
DEFAULT_TAG_COLOR = s_tags.DEFAULT_TAG_COLOR
TAG_COLORS = s_tags.TAG_COLORS
REQUEST_STATUS_CLASSES = s_tags.REQUEST_STATUS_CLASSES


class TestSamplesheetsTemplateTags(
ProjectMixin,
RoleMixin,
RoleAssignmentMixin,
SampleSheetModelMixin,
TestCase,
):
"""Tests for template tags in the samplesheets app"""

def setUp(self):
# Init roles
self.init_roles()
# Make owner user
self.user_owner = self.make_user('owner')
# Init project and assignment
self.project = self.make_project(
'TestProject', SODAR_CONSTANTS['PROJECT_TYPE_PROJECT'], None
)
self.owner_as = self.make_assignment(
self.project, self.user_owner, self.role_owner
)
# Set up Investigation
self.investigation = self.make_investigation(
identifier=INV_IDENTIFIER,
file_name=INV_FILE_NAME,
project=self.project,
title=INV_TITLE,
description=DEFAULT_DESCRIPTION,
comments=DEFAULT_COMMENTS,
archive_name=INV_ARCHIVE_NAME,
)
# Set up Study
self.study = self.make_study(
identifier=STUDY_IDENTIFIER,
file_name=STUDY_FILE_NAME,
investigation=self.investigation,
title=STUDY_TITLE,
description=DEFAULT_DESCRIPTION,
comments=DEFAULT_COMMENTS,
)
# Set up Assay
self.assay = self.make_assay(
file_name=ASSAY_FILE_NAME,
study=self.study,
tech_platform=ASSAY_TECH_PLATFORM,
tech_type=ASSAY_TECH_TYPE,
measurement_type=ASSAY_MEASURE_TYPE,
arcs=[],
comments=DEFAULT_COMMENTS,
)
# Setup iRODS backend for the test
self.irods_backend = get_backend_api('omics_irods')

def test_get_investigation(self):
"""Test get_investigation()"""
self.assertEqual(
s_tags.get_investigation(self.project), self.investigation
)

def test_get_investigation_no_investigation(self):
"""Test get_investigation() without investigation"""
self.investigation.delete()
self.assertEqual(s_tags.get_investigation(self.project), None)

def test_get_search_item_type_with_material_types(self):
"""Test get_search_item_type() with material types"""
for material_type in GENERIC_MATERIAL_TYPES:
item = {'type': material_type}
expected = GENERIC_MATERIAL_TYPES[material_type]
self.assertEqual(s_tags.get_search_item_type(item), expected)

def test_get_search_item_type_with_file(self):
"""Test get_search_item_type() with special case 'file'"""
item = {'type': 'file'}
self.assertEqual(s_tags.get_search_item_type(item), 'Data File')

def test_get_irods_tree(self):
"""Test get_irods_tree()"""
ret = s_tags.get_irods_tree(self.investigation)
# Assert that IRODS_SAMPLE_COLL exists in the returned string
self.assertIn(IRODS_SAMPLE_COLL, ret)
# Assert that study path exists in the returned string
self.assertIn(self.irods_backend.get_sub_path(self.study), ret)
# Assert that assay path exists in the returned string
study_path, assay_path = self.irods_backend.get_sub_path(
self.assay
).split('/')
self.assertIn(study_path, ret)
self.assertIn(assay_path, ret)

def test_get_material_search_url(self):
"""Test get_material_search_url()"""
item = {'study': self.study, 'name': 'Sample1'}
url = s_tags.get_material_search_url(item)
expected = reverse(
'samplesheets:project_sheets',
kwargs={'project': self.project.sodar_uuid},
)
expected += '#/study/{}/filter/Sample1'.format(self.study.sodar_uuid)
self.assertEqual(url, expected)

def test_get_irods_path_with_project(self):
"""Test get_irods_path() with project"""
expected = self.irods_backend.get_path(self.project)
self.assertEqual(s_tags.get_irods_path(self.project), expected)

def test_get_irods_path_with_assay(self):
"""Test get_irods_path() with assay"""
expected = self.irods_backend.get_path(self.assay)
self.assertEqual(s_tags.get_irods_path(self.assay), expected)

def test_get_irods_path_with_project_and_sub_path(self):
"""Test get_irods_path() with project and sub_path"""
project_path = self.irods_backend.get_path(self.project)
sub_path = 'subfolder1/subfolder2'
expected = project_path + '/' + sub_path
self.assertEqual(
s_tags.get_irods_path(self.project, sub_path), expected
)

def test_get_irods_path_with_assay_and_sub_path(self):
"""Test get_irods_path() with assay and sub_path"""
assay_path = self.irods_backend.get_path(self.assay)
sub_path = 'subfolder1/subfolder2'
expected = assay_path + '/' + sub_path
self.assertEqual(s_tags.get_irods_path(self.assay, sub_path), expected)

def test_get_icon_study(self):
"""Test get_icon() with Study"""
icon_html = s_tags.get_icon(self.study)
self.assertIn('text-info', icon_html)
self.assertIn('mdi:folder-table', icon_html)

def test_get_icon_assay(self):
"""Test get_icon() with Assay"""
icon_html = s_tags.get_icon(self.assay)
self.assertIn('text-danger', icon_html)
self.assertIn('mdi:table-large', icon_html)

def test_get_isatab_tag_html_with_tags_in_tag_colors(self):
"""Test get_isatab_tag_html() with tags in TAG_COLORS"""
isatab = type('MockISATab', (object,), {'tags': TAG_COLORS.keys()})
tag_html = s_tags.get_isatab_tag_html(isatab)
for tag, color in TAG_COLORS.items():
self.assertIn(color, tag_html)

def test_get_isatab_tag_html_with_unknown_tag(self):
"""Test get_isatab_tag_html() with an unknown tag"""
isatab = type('MockISATab', (object,), {'tags': ['UNKNOWN_TAG']})
tag_html = s_tags.get_isatab_tag_html(isatab)
self.assertIn(DEFAULT_TAG_COLOR, tag_html)

def test_get_request_status_class_with_valid_status(self):
"""
Test get_request_status_class() with values in REQUEST_STATUS_CLASSES
"""
for status, css_class in REQUEST_STATUS_CLASSES.items():
irods_request = type(
'MockIrodsRequest', (object,), {'status': status}
)
self.assertEqual(
s_tags.get_request_status_class(irods_request), css_class
)

def test_get_request_status_class_with_unknown_status(self):
"""Test get_request_status_class() with an unknown status"""
irods_request = type(
'MockIrodsRequest', (object,), {'status': 'UNKNOWN'}
)
self.assertEqual(s_tags.get_request_status_class(irods_request), '')

def test_trim_base_path(self):
"""Test trim_base_path() with a realistic iRODS path"""
prefix = '/base_path'
path = prefix + '/project/subfolder1/subfolder2'
expected = '/project/subfolder1/subfolder2'
self.assertEqual(s_tags.trim_base_path(path, prefix), expected)
7 changes: 6 additions & 1 deletion samplesheets/tests/test_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ def test_render_alert(self):
# NOTE: For further vue app tests, see samplesheets/vueapp/tests


class TestSheetTemplateCreateFormView(TestProjectSheetsUIBase):
class TestSheetTemplateCreateView(TestProjectSheetsUIBase):
"""Tests for the sheet template creation view UI"""

def test_render_field_visibility(self):
Expand Down Expand Up @@ -278,6 +278,11 @@ def test_list(self):
self.assert_element_exists(
[self.user_contributor], self.url, 'sodar-ss-version-alert', False
)
# Ensure badge is shown for current version
self.login_and_redirect(self.user_contributor, self.url)
self.assertIsNotNone(
self.selenium.find_element(By.CLASS_NAME, 'badge-info')
)

def test_list_no_versions(self):
"""Test UI rendering for list items with no versions"""
Expand Down
6 changes: 4 additions & 2 deletions samplesheets/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -703,8 +703,8 @@ def test_render_with_sheets(self):
)


class TestSheetTemplateCreateFormView(ViewTestBase):
"""Tests for SheetTemplateCreateFormView"""
class TestSheetTemplateCreateView(ViewTestBase):
"""Tests for SheetTemplateCreateView"""

def _get_post_data(self, tpl_name):
"""
Expand Down Expand Up @@ -798,6 +798,8 @@ def test_post_batch(self):
+ t,
data=post_data,
)
isa_tab = ISATab.objects.first()
self.assertEqual(isa_tab.tags, ['CREATE'])
self.assertEqual(response.status_code, 302, msg=t)
self.assertIsNotNone(self.project.investigations.first(), msg=t)
self.project.investigations.first().delete()
Expand Down

0 comments on commit f7cfd4b

Please sign in to comment.