diff --git a/primed/cdsa/tables.py b/primed/cdsa/tables.py index 579ce874..2571fb39 100644 --- a/primed/cdsa/tables.py +++ b/primed/cdsa/tables.py @@ -49,6 +49,7 @@ class Meta: "date_signed", "number_accessors", ) + order_by = ("cc_id",) class MemberAgreementTable(tables.Table): @@ -80,6 +81,7 @@ class Meta: "signed_agreement__date_signed", "number_accessors", ) + order_by = ("signed_agreement__cc_id",) class DataAffiliateAgreementTable(tables.Table): @@ -111,6 +113,7 @@ class Meta: "signed_agreement__date_signed", "number_accessors", ) + order_by = ("signed_agreement__cc_id",) class NonDataAffiliateAgreementTable(tables.Table): @@ -140,6 +143,7 @@ class Meta: "signed_agreement__date_signed", "number_accessors", ) + order_by = ("signed_agreement__cc_id",) class RepresentativeRecordsTable(tables.Table): @@ -154,12 +158,12 @@ class RepresentativeRecordsTable(tables.Table): class Meta: model = models.SignedAgreement fields = ( - "cc_id", "representative__name", "representative_role", "signing_institution", "signing_group", ) + order_by = ("representative__name",) def render_signing_group(self, record): if hasattr(record, "memberagreement"): @@ -179,13 +183,16 @@ class StudyRecordsTable(tables.Table): signed_agreement__representative__name = tables.Column( verbose_name="Representative" ) + # This will only order properly if the order_by value is a column in the table. + study__short_name = tables.Column(verbose_name="Study") class Meta: model = models.DataAffiliateAgreement fields = ( - "study", + "study__short_name", "signed_agreement__representative__name", ) + order_by = ("study__short_name",) class UserAccessRecordsTable(tables.Table): @@ -207,6 +214,7 @@ class Meta: "group__signedagreement__signing_institution", "group__signedagreement__representative__name", ) + order_by = ("account__user__name",) def render_signing_group(self, record): if hasattr(record.group.signedagreement, "memberagreement"): @@ -246,6 +254,7 @@ class Meta: "workspace__created", "date_shared", ) + order_by = ("workspace__name",) def render_date_shared(self, record): try: @@ -282,3 +291,4 @@ class Meta: "cdsaworkspace__data_use_permission__abbreviation", "cdsaworkspace__data_use_modifiers", ) + order_by = ("name",) diff --git a/primed/cdsa/tests/test_tables.py b/primed/cdsa/tests/test_tables.py index 37f467b6..6bf1fa68 100644 --- a/primed/cdsa/tests/test_tables.py +++ b/primed/cdsa/tests/test_tables.py @@ -8,6 +8,7 @@ from django.test import TestCase from primed.primed_anvil.tests.factories import StudyFactory, StudySiteFactory +from primed.users.tests.factories import UserFactory from .. import models, tables from . import factories @@ -49,6 +50,14 @@ def test_number_accessors(self): self.assertEqual(table.rows[1].get_cell("number_accessors"), 1) self.assertEqual(table.rows[2].get_cell("number_accessors"), 2) + def test_ordering(self): + """Instances are ordered alphabetically by cc_id.""" + instance_1 = factories.MemberAgreementFactory.create(signed_agreement__cc_id=2) + instance_2 = factories.MemberAgreementFactory.create(signed_agreement__cc_id=1) + table = self.table_class(self.model.objects.all()) + self.assertEqual(table.data[0], instance_2.signed_agreement) + self.assertEqual(table.data[1], instance_1.signed_agreement) + class MemberAgreementTableTest(TestCase): model = models.MemberAgreement @@ -85,6 +94,14 @@ def test_number_accessors(self): self.assertEqual(table.rows[1].get_cell("number_accessors"), 1) self.assertEqual(table.rows[2].get_cell("number_accessors"), 2) + def test_ordering(self): + """Instances are ordered alphabetically by cc_id.""" + instance_1 = self.model_factory.create(signed_agreement__cc_id=2) + instance_2 = self.model_factory.create(signed_agreement__cc_id=1) + table = self.table_class(self.model.objects.all()) + self.assertEqual(table.data[0], instance_2) + self.assertEqual(table.data[1], instance_1) + class DataAffiliateAgreementTableTest(TestCase): model = models.DataAffiliateAgreement @@ -121,6 +138,14 @@ def test_number_accessors(self): self.assertEqual(table.rows[1].get_cell("number_accessors"), 1) self.assertEqual(table.rows[2].get_cell("number_accessors"), 2) + def test_ordering(self): + """Instances are ordered alphabetically by cc_id.""" + instance_1 = self.model_factory.create(signed_agreement__cc_id=2) + instance_2 = self.model_factory.create(signed_agreement__cc_id=1) + table = self.table_class(self.model.objects.all()) + self.assertEqual(table.data[0], instance_2) + self.assertEqual(table.data[1], instance_1) + class NonDataAffiliateAgreementTableTest(TestCase): model = models.NonDataAffiliateAgreement @@ -157,6 +182,14 @@ def test_number_accessors(self): self.assertEqual(table.rows[1].get_cell("number_accessors"), 1) self.assertEqual(table.rows[2].get_cell("number_accessors"), 2) + def test_ordering(self): + """Instances are ordered alphabetically by cc_id.""" + instance_1 = self.model_factory.create(signed_agreement__cc_id=2) + instance_2 = self.model_factory.create(signed_agreement__cc_id=1) + table = self.table_class(self.model.objects.all()) + self.assertEqual(table.data[0], instance_2) + self.assertEqual(table.data[1], instance_1) + class RepresentativeRecordsTableTest(TestCase): """Tests for the RepresentativeRecordsTable class.""" @@ -203,6 +236,18 @@ def test_render_signing_group(self): record = factories.SignedAgreementFactory() self.assertIsNone(table.render_signing_group(record)) + def test_ordering(self): + """Instances are ordered alphabetically by representative name.""" + instance_1 = factories.MemberAgreementFactory.create( + signed_agreement__representative__name="zzz" + ) + instance_2 = factories.MemberAgreementFactory.create( + signed_agreement__representative__name="aaa" + ) + table = self.table_class(self.model.objects.all()) + self.assertEqual(table.data[0], instance_2.signed_agreement) + self.assertEqual(table.data[1], instance_1.signed_agreement) + class StudyRecordsTableTest(TestCase): """Tests for the StudyRecordsTable class.""" @@ -225,6 +270,14 @@ def test_row_count_with_two_objects(self): table = self.table_class(self.model.objects.all()) self.assertEqual(len(table.rows), 2) + def test_ordering(self): + """Instances are ordered alphabetically by study short name.""" + instance_1 = self.model_factory.create(study__short_name="zzz") + instance_2 = self.model_factory.create(study__short_name="aaa") + table = self.table_class(self.model.objects.all()) + self.assertEqual(table.data[0], instance_2) + self.assertEqual(table.data[1], instance_1) + class UserAccessRecordsTableTest(TestCase): """Tests for the UserAccessRecordsTable class.""" @@ -308,6 +361,23 @@ def test_render_signing_group(self): record = GroupAccountMembershipFactory.create(group__signedagreement=agreement) self.assertIsNone(table.render_signing_group(record)) + def test_ordering(self): + """Instances are ordered alphabetically by user name.""" + agreement = factories.MemberAgreementFactory.create() + user_1 = UserFactory.create(name="zzz") + instance_1 = GroupAccountMembershipFactory.create( + group__signedagreement=agreement.signed_agreement, + account__user=user_1, + ) + user_2 = UserFactory.create(name="aaa") + instance_2 = GroupAccountMembershipFactory.create( + group__signedagreement=agreement.signed_agreement, + account__user=user_2, + ) + table = self.table_class(self.model.objects.all()) + self.assertEqual(table.data[0], instance_2) + self.assertEqual(table.data[1], instance_1) + class CDSAWorkspaceRecordsTableTest(TestCase): """Tests for the CDSAWorkspaceRecordsTable class.""" @@ -343,6 +413,19 @@ def test_render_date_shared(self): ) self.assertNotEqual(table.render_date_shared(cdsa_workspace), "—") + def test_ordering(self): + """Instances are ordered alphabetically by user name.""" + agreement = factories.DataAffiliateAgreementFactory.create() + instance_1 = factories.CDSAWorkspaceFactory.create( + study=agreement.study, workspace__name="zzz" + ) + instance_2 = factories.CDSAWorkspaceFactory.create( + study=agreement.study, workspace__name="aaa" + ) + table = self.table_class(self.model.objects.all()) + self.assertEqual(table.data[0], instance_2) + self.assertEqual(table.data[1], instance_1) + class CDSAWorkspaceTableTest(TestCase): """Tests for the CDSAWorkspaceTable class.""" @@ -392,3 +475,11 @@ def test_render_is_shared_shared_with_different_group(self): ) table = self.table_class(self.model.objects.all()) self.assertEqual("", table.rows[0].get_cell_value("is_shared")) + + def test_ordering(self): + """Instances are ordered alphabetically by user name.""" + instance_1 = factories.CDSAWorkspaceFactory.create(workspace__name="zzz") + instance_2 = factories.CDSAWorkspaceFactory.create(workspace__name="aaa") + table = self.table_class(self.model.objects.all()) + self.assertEqual(table.data[0], instance_2.workspace) + self.assertEqual(table.data[1], instance_1.workspace) diff --git a/primed/dbgap/tables.py b/primed/dbgap/tables.py index aa1be4a2..622bbad2 100644 --- a/primed/dbgap/tables.py +++ b/primed/dbgap/tables.py @@ -27,6 +27,7 @@ class Meta: "dbgap_phs", "studies", ) + order_by = ("dbgap_phs",) def render_dbgap_phs(self, value): return "phs{0:06d}".format(value) @@ -140,6 +141,7 @@ class Meta: "dbgap_project_id", "principal_investigator", ) + order_by = ("dbgap_project_id",) class dbGaPDataAccessSnapshotTable(tables.Table): @@ -151,6 +153,7 @@ class Meta: "pk", "created", ) + order_by = ("-created",) pk = tables.Column(linkify=True, verbose_name="Details", orderable=False) number_approved_dars = tables.columns.Column( @@ -169,11 +172,11 @@ class Meta: def render_pk(self, record): return "See details" - def render_number_approved_dars(self, value, record): + def render_number_approved_dars(self, record): n_dars = record.dbgapdataaccessrequest_set.approved().count() return n_dars - def render_number_requested_dars(self, value, record): + def render_number_requested_dars(self, record): n_dars = record.dbgapdataaccessrequest_set.count() return n_dars @@ -235,6 +238,7 @@ class Meta: "dbgap_consent_abbreviation", "dbgap_current_status", ) + order_by = ("dbgap_dar_id",) class dbGaPDataAccessRequestSummaryTable(tables.Table): diff --git a/primed/dbgap/tests/test_tables.py b/primed/dbgap/tests/test_tables.py index 1ce53ab3..01d8b538 100644 --- a/primed/dbgap/tests/test_tables.py +++ b/primed/dbgap/tests/test_tables.py @@ -10,6 +10,7 @@ from django.db.models import Count from django.test import TestCase from django.utils import timezone +from freezegun import freeze_time from .. import models, tables from . import factories @@ -50,6 +51,14 @@ def test_number_workspaces(self): self.assertEqual(table.rows[1].get_cell("number_workspaces"), 1) self.assertEqual(table.rows[2].get_cell("number_workspaces"), 2) + def test_ordering(self): + """Instances are ordered alphabetically by dbgap_phs.""" + instance_1 = self.model_factory.create(dbgap_phs=2) + instance_2 = self.model_factory.create(dbgap_phs=1) + table = self.table_class(self.model.objects.all()) + self.assertEqual(table.data[0], instance_2) + self.assertEqual(table.data[1], instance_1) + class dbGaPWorkspaceTableTest(TestCase): model = acm_models.Workspace @@ -380,6 +389,14 @@ def test_last_update_two_snapshots(self): latest_snapshot.get_absolute_url(), table.rows[0].get_cell("last_update") ) + def test_ordering(self): + """Instances are ordered alphabetically by dbgap_project_id.""" + instance_1 = self.model_factory.create(dbgap_project_id=2) + instance_2 = self.model_factory.create(dbgap_project_id=1) + table = self.table_class(self.model.objects.all()) + self.assertEqual(table.data[0], instance_2) + self.assertEqual(table.data[1], instance_1) + class dbGaPDataAccessSnapshotTableTest(TestCase): model = models.dbGaPDataAccessSnapshot @@ -401,40 +418,86 @@ def test_row_count_with_two_objects(self): self.assertEqual(len(table.rows), 2) def test_number_approved_dars(self): - snapshot = self.model_factory.create() + snapshot_1 = self.model_factory.create() + factories.dbGaPDataAccessRequestFactory.create( + dbgap_data_access_snapshot=snapshot_1, + dbgap_current_status=models.dbGaPDataAccessRequest.APPROVED, + ) + factories.dbGaPDataAccessRequestFactory.create_batch( + 2, + dbgap_data_access_snapshot=snapshot_1, + dbgap_current_status=models.dbGaPDataAccessRequest.CLOSED, + ) + factories.dbGaPDataAccessRequestFactory.create_batch( + 2, + dbgap_data_access_snapshot=snapshot_1, + dbgap_current_status=models.dbGaPDataAccessRequest.REJECTED, + ) + factories.dbGaPDataAccessRequestFactory.create_batch( + 2, + dbgap_data_access_snapshot=snapshot_1, + dbgap_current_status=models.dbGaPDataAccessRequest.EXPIRED, + ) + factories.dbGaPDataAccessRequestFactory.create_batch( + 2, + dbgap_data_access_snapshot=snapshot_1, + dbgap_current_status=models.dbGaPDataAccessRequest.NEW, + ) + snapshot_2 = self.model_factory.create() + factories.dbGaPDataAccessRequestFactory.create_batch( + 2, + dbgap_data_access_snapshot=snapshot_2, + dbgap_current_status=models.dbGaPDataAccessRequest.APPROVED, + ) + table = self.table_class(self.model.objects.all()) + self.assertEqual(table.render_number_approved_dars(snapshot_1), 1) + self.assertEqual(table.render_number_approved_dars(snapshot_2), 2) + + def test_number_requested_dars(self): + snapshot_1 = self.model_factory.create() factories.dbGaPDataAccessRequestFactory.create( - dbgap_data_access_snapshot=snapshot, + dbgap_data_access_snapshot=snapshot_1, dbgap_current_status=models.dbGaPDataAccessRequest.APPROVED, ) factories.dbGaPDataAccessRequestFactory.create_batch( 2, - dbgap_data_access_snapshot=snapshot, + dbgap_data_access_snapshot=snapshot_1, dbgap_current_status=models.dbGaPDataAccessRequest.CLOSED, ) factories.dbGaPDataAccessRequestFactory.create_batch( 2, - dbgap_data_access_snapshot=snapshot, + dbgap_data_access_snapshot=snapshot_1, dbgap_current_status=models.dbGaPDataAccessRequest.REJECTED, ) factories.dbGaPDataAccessRequestFactory.create_batch( 2, - dbgap_data_access_snapshot=snapshot, + dbgap_data_access_snapshot=snapshot_1, dbgap_current_status=models.dbGaPDataAccessRequest.EXPIRED, ) factories.dbGaPDataAccessRequestFactory.create_batch( 2, - dbgap_data_access_snapshot=snapshot, + dbgap_data_access_snapshot=snapshot_1, dbgap_current_status=models.dbGaPDataAccessRequest.NEW, ) - other_snapshot = self.model_factory.create() + snapshot_2 = self.model_factory.create() factories.dbGaPDataAccessRequestFactory.create_batch( 2, - dbgap_data_access_snapshot=other_snapshot, + dbgap_data_access_snapshot=snapshot_2, dbgap_current_status=models.dbGaPDataAccessRequest.APPROVED, ) table = self.table_class(self.model.objects.all()) - self.assertEqual(table.rows[0].get_cell_value("number_approved_dars"), 1) - self.assertEqual(table.rows[1].get_cell_value("number_approved_dars"), 2) + self.assertEqual(table.render_number_requested_dars(snapshot_1), 9) + self.assertEqual(table.render_number_requested_dars(snapshot_2), 2) + + def test_ordering(self): + """Instances are ordered by decreasing snapshot date.""" + with freeze_time("2020-01-01"): + instance_1 = self.model_factory.create() + with freeze_time("2021-12-12"): + instance_2 = self.model_factory.create() + table = self.table_class(self.model.objects.all()) + self.assertEqual(table.data[0], instance_2) + self.assertEqual(table.data[1], instance_1) class dbGaPDataAccessRequestTableTest(TestCase): @@ -508,6 +571,14 @@ def test_two_matching_workspaces(self): self.assertIn(str(workspace_1), value) self.assertIn(str(workspace_2), value) + def test_ordering(self): + """Instances are ordered alphabetically by dbgap_dar_id.""" + instance_1 = self.model_factory.create(dbgap_dar_id=2) + instance_2 = self.model_factory.create(dbgap_dar_id=1) + table = self.table_class(self.model.objects.all()) + self.assertEqual(table.data[0], instance_2) + self.assertEqual(table.data[1], instance_1) + class dbGaPDataAccessRequestSummaryTable(TestCase): diff --git a/primed/primed_anvil/tables.py b/primed/primed_anvil/tables.py index cfda4c5e..e58d5a68 100644 --- a/primed/primed_anvil/tables.py +++ b/primed/primed_anvil/tables.py @@ -80,6 +80,7 @@ class StudyTable(tables.Table): class Meta: model = models.Study fields = ("short_name", "full_name") + order_by = ("short_name",) class StudySiteTable(tables.Table): @@ -90,6 +91,7 @@ class StudySiteTable(tables.Table): class Meta: model = models.StudySite fields = ("short_name", "full_name") + order_by = ("short_name",) class AccountTable(tables.Table): @@ -116,6 +118,7 @@ class AvailableDataTable(tables.Table): class Meta: model = models.AvailableData fields = ("name", "description") + order_by = ("name",) class DataSummaryTable(tables.Table): diff --git a/primed/primed_anvil/tests/test_tables.py b/primed/primed_anvil/tests/test_tables.py index 0345e773..4d41ec6d 100644 --- a/primed/primed_anvil/tests/test_tables.py +++ b/primed/primed_anvil/tests/test_tables.py @@ -30,6 +30,14 @@ def test_row_count_with_two_objects(self): table = self.table_class(self.model.objects.all()) self.assertEqual(len(table.rows), 2) + def test_ordering(self): + """Studies are ordered alphabetically by short name""" + study_foo = self.model_factory.create(short_name="foo", full_name="AAA") + study_bar = self.model_factory.create(short_name="bar", full_name="BBB") + table = self.table_class(self.model.objects.all()) + self.assertEqual(table.data[0], study_bar) + self.assertEqual(table.data[1], study_foo) + class StudySiteTableTest(TestCase): model = models.StudySite @@ -50,6 +58,14 @@ def test_row_count_with_two_objects(self): table = self.table_class(self.model.objects.all()) self.assertEqual(len(table.rows), 2) + def test_ordering(self): + """Studies are ordered alphabetically by short name""" + foo = self.model_factory.create(short_name="foo", full_name="AAA") + bar = self.model_factory.create(short_name="bar", full_name="BBB") + table = self.table_class(self.model.objects.all()) + self.assertEqual(table.data[0], bar) + self.assertEqual(table.data[1], foo) + class AccountTableTest(TestCase): """Tests for the custom AccountTable.""" @@ -116,6 +132,14 @@ def test_row_count_with_two_objects(self): table = self.table_class(self.model.objects.all()) self.assertEqual(len(table.rows), 2) + def test_ordering(self): + """Instances are ordered alphabetically name.""" + foo = self.model_factory.create(name="foo", description="AAA") + bar = self.model_factory.create(name="bar", description="BBB") + table = self.table_class(self.model.objects.all()) + self.assertEqual(table.data[0], bar) + self.assertEqual(table.data[1], foo) + class DataSummaryTableTest(TestCase): diff --git a/requirements/local.txt b/requirements/local.txt index bfb8f45f..6d5831f0 100644 --- a/requirements/local.txt +++ b/requirements/local.txt @@ -37,3 +37,8 @@ setuptools==65.5.1 # https://github.com/pypa/setuptools django-debug-toolbar==3.4.0 # https://github.com/jazzband/django-debug-toolbar django-coverage-plugin==2.0.3 # https://github.com/nedbat/django_coverage_plugin pytest-django==4.5.2 # https://github.com/pytest-dev/pytest-django + +# My additions +# ------------------------------------------------------------------------------ +# For setting time when running tests. +freezegun==1.2.2 # https://github.com/spulec/freezegun