diff --git a/primed/dbgap/tables.py b/primed/dbgap/tables.py index 522388bd..84cd7687 100644 --- a/primed/dbgap/tables.py +++ b/primed/dbgap/tables.py @@ -33,24 +33,63 @@ def render_dbgap_phs(self, value): class dbGaPWorkspaceTable(tables.Table): """Class to render a table of Workspace objects with dbGaPWorkspace workspace data.""" - name = tables.columns.Column(linkify=True) - - class Meta: - model = Workspace - fields = ( - "name", - "dbgapworkspace__dbgap_study_accession__studies", + workspace = tables.columns.Column( + linkify=True, accessor="pk", order_by=("billing_project__name", "name") + ) + dbgap_accession = tables.columns.Column( + verbose_name="dbGaP accession", + accessor="pk", + order_by=( "dbgapworkspace__dbgap_study_accession__dbgap_phs", "dbgapworkspace__dbgap_version", "dbgapworkspace__dbgap_participant_set", - "dbgapworkspace__dbgap_consent_abbreviation", - ) + ), + ) + dbgapworkspace__dbgap_consent_abbreviation = tables.columns.Column( + verbose_name="Consent" + ) + number_approved_dars = tables.columns.Column( + accessor="pk", + verbose_name="Approved DARs", + orderable=False, + ) + is_shared = tables.columns.Column( + accessor="pk", + verbose_name="Shared with PRIMED?", + orderable=False, + ) - def render_dbgapworkspace__dbgap_phs(self, value): - return "phs{0:06d}".format(value) + class Meta: + model = Workspace + fields = () + + def render_workspace(self, record): + return str(record) - def render_dbgapworkspace__version(self, value): - return "v{}".format(value) + def render_dbgap_accession(self, record): + return record.dbgapworkspace.get_dbgap_accession() + + def render_number_approved_dars(self, record): + n = ( + record.dbgapworkspace.get_data_access_requests(most_recent=True) + .filter(dbgap_current_status=models.dbGaPDataAccessRequest.APPROVED) + .count() + ) + return n + + def render_is_shared(self, record): + is_shared = record.workspacegroupsharing_set.filter( + group__name="PRIMED_ALL" + ).exists() + if is_shared: + icon = "check-circle-fill" + color = "green" + value = format_html( + """""".format(icon, color) + ) + else: + value = "" + return value class ManyToManyDateTimeColumn(tables.columns.ManyToManyColumn): diff --git a/primed/dbgap/tests/test_tables.py b/primed/dbgap/tests/test_tables.py index 7c656327..ba39ad9d 100644 --- a/primed/dbgap/tests/test_tables.py +++ b/primed/dbgap/tests/test_tables.py @@ -70,6 +70,99 @@ def test_row_count_with_two_objects(self): table = self.table_class(self.model.objects.all()) self.assertEqual(len(table.rows), 2) + def test_render_workspace(self): + """render_workspace returns the correct value.""" + instance = self.model_factory.create( + workspace__billing_project__name="bp", workspace__name="ws" + ) + table = self.table_class(self.model.objects.all()) + self.assertEqual(table.render_workspace(instance.workspace), "bp/ws") + self.assertEqual(table.rows[0].get_cell_value("workspace"), "bp/ws") + + def test_render_dbgap_accession(self): + """render_workspace returns the correct value.""" + instance = self.model_factory.create( + dbgap_study_accession__dbgap_phs=1, + dbgap_version=2, + dbgap_participant_set=3, + ) + table = self.table_class(self.model.objects.all()) + self.assertEqual( + table.render_dbgap_accession(instance.workspace), "phs000001.v2.p3" + ) + self.assertEqual( + table.rows[0].get_cell_value("dbgap_accession"), "phs000001.v2.p3" + ) + + def test_render_number_approved_dars_no_dars(self): + instance = self.model_factory.create() + table = self.table_class(self.model.objects.all()) + self.assertEqual(table.render_number_approved_dars(instance.workspace), 0) + + def test_render_number_approved_dars_one_dar(self): + instance = self.model_factory.create() + factories.dbGaPDataAccessRequestForWorkspaceFactory(dbgap_workspace=instance) + table = self.table_class(self.model.objects.all()) + self.assertEqual(table.render_number_approved_dars(instance.workspace), 1) + + def test_render_number_approved_dars_one_dar_does_not_match(self): + instance = self.model_factory.create() + factories.dbGaPDataAccessRequestFactory() + table = self.table_class(self.model.objects.all()) + self.assertEqual(table.render_number_approved_dars(instance.workspace), 0) + + def test_render_number_approved_dars_two_dars(self): + instance = self.model_factory.create() + factories.dbGaPDataAccessRequestForWorkspaceFactory(dbgap_workspace=instance) + factories.dbGaPDataAccessRequestForWorkspaceFactory(dbgap_workspace=instance) + table = self.table_class(self.model.objects.all()) + self.assertEqual(table.render_number_approved_dars(instance.workspace), 2) + + def test_render_number_approved_dars_not_approved(self): + instance = self.model_factory.create() + factories.dbGaPDataAccessRequestForWorkspaceFactory( + dbgap_workspace=instance, + dbgap_current_status=models.dbGaPDataAccessRequest.REJECTED, + ) + table = self.table_class(self.model.objects.all()) + self.assertEqual(table.render_number_approved_dars(instance.workspace), 0) + + def test_render_number_approved_dars_only_most_recent(self): + instance = self.model_factory.create() + factories.dbGaPDataAccessRequestForWorkspaceFactory( + dbgap_workspace=instance, dbgap_data_access_snapshot__is_most_recent=False + ) + table = self.table_class(self.model.objects.all()) + self.assertEqual(table.render_number_approved_dars(instance.workspace), 0) + + def test_render_is_shared_not_shared(self): + """render_is_shared works correctly when the workspace is not shared with anyone.""" + factories.ManagedGroupFactory.create(name="PRIMED_ALL") + factories.dbGaPWorkspaceFactory.create() + table = self.table_class(self.model.objects.all()) + self.assertEqual("", table.rows[0].get_cell_value("is_shared")) + + def test_render_is_shared_true(self): + """render_is_shared works correctly when the workspace is shared with PRIMED_ALL.""" + group = factories.ManagedGroupFactory.create(name="PRIMED_ALL") + dbgap_workspace = factories.dbGaPWorkspaceFactory.create() + WorkspaceGroupSharingFactory.create( + group=group, workspace=dbgap_workspace.workspace + ) + table = self.table_class(self.model.objects.all()) + self.assertIn("circle-fill", table.rows[0].get_cell_value("is_shared")) + + def test_render_is_shared_shared_with_different_group(self): + """render_is_shared works correctly when the workspace is shared with a group other PRIMED_ALL.""" + factories.ManagedGroupFactory.create(name="PRIMED_ALL") + group = factories.ManagedGroupFactory.create() + dbgap_workspace = factories.dbGaPWorkspaceFactory.create() + WorkspaceGroupSharingFactory.create( + group=group, workspace=dbgap_workspace.workspace + ) + table = self.table_class(self.model.objects.all()) + self.assertEqual("", table.rows[0].get_cell_value("is_shared")) + class dbGaPApplicationTableTest(TestCase): model = models.dbGaPApplication