diff --git a/add_dbgap_example_data.py b/add_dbgap_example_data.py index 4075ad82..20a1054b 100644 --- a/add_dbgap_example_data.py +++ b/add_dbgap_example_data.py @@ -94,6 +94,10 @@ dbgap_dac="NHLBI", dbgap_current_status=models.dbGaPDataAccessRequest.REJECTED, ) +dar_1_5 = factories.dbGaPDataAccessRequestFactory( + dbgap_data_access_snapshot=dar_snapshot_1, + dbgap_current_status=models.dbGaPDataAccessRequest.APPROVED, +) dbgap_application_2 = factories.dbGaPApplicationFactory.create( principal_investigator=UserFactory.create(name="Alisa", username="Alisa"), diff --git a/primed/dbgap/models.py b/primed/dbgap/models.py index 7749d577..21f22a0c 100644 --- a/primed/dbgap/models.py +++ b/primed/dbgap/models.py @@ -473,3 +473,9 @@ def get_dbgap_workspaces(self): dbgap_consent_code=self.dbgap_consent_code, ).order_by("dbgap_version") return dbgap_workspaces + + def get_matching_studies(self): + """Get the list of studies matching dbGaP study accession phs associated with this data access request.""" + + study_list = Study.objects.filter(dbgapstudyaccession__dbgap_phs=self.dbgap_phs) + return study_list diff --git a/primed/dbgap/tables.py b/primed/dbgap/tables.py index 717a9e77..0eaf685c 100644 --- a/primed/dbgap/tables.py +++ b/primed/dbgap/tables.py @@ -261,6 +261,11 @@ class dbGaPDataAccessRequestBySnapshotTable(dbGaPDataAccessRequestTable): dbgap_data_access_snapshot__dbgap_application__dbgap_project_id = None dbgap_data_access_snapshot__created = None matching_workspaces = tables.columns.Column(accessor="get_dbgap_workspaces", orderable=False, default=" ") + matching_studies = tables.columns.ManyToManyColumn( + accessor="get_matching_studies", + verbose_name="Studies", + linkify_item=True, + ) class Meta: model = models.dbGaPDataAccessRequest @@ -273,6 +278,11 @@ class Meta: ) order_by = ("dbgap_dar_id",) attrs = {"class": "table table-sm"} + sequence = ( + "dbgap_dar_id", + "dbgap_dac", + "matching_studies", + ) def render_matching_workspaces(self, value, record): template_code = """ diff --git a/primed/dbgap/tests/factories.py b/primed/dbgap/tests/factories.py index 78e43981..84dc46db 100644 --- a/primed/dbgap/tests/factories.py +++ b/primed/dbgap/tests/factories.py @@ -151,18 +151,14 @@ class Meta: model = models.dbGaPDataAccessRequest -class dbGaPDataAccessRequestForWorkspaceFactory(DjangoModelFactory): +class dbGaPDataAccessRequestForWorkspaceFactory(dbGaPDataAccessRequestFactory): """A factory for the dbGaPApplication model to match a workspace.""" - dbgap_data_access_snapshot = SubFactory(dbGaPDataAccessSnapshotFactory) dbgap_phs = LazyAttribute(lambda o: o.dbgap_workspace.dbgap_study_accession.dbgap_phs) - dbgap_dar_id = Sequence(lambda n: n + 1) original_version = LazyAttribute(lambda o: o.dbgap_workspace.dbgap_version) original_participant_set = LazyAttribute(lambda o: o.dbgap_workspace.dbgap_participant_set) dbgap_consent_code = LazyAttribute(lambda o: o.dbgap_workspace.dbgap_consent_code) dbgap_consent_abbreviation = LazyAttribute(lambda o: o.dbgap_workspace.dbgap_consent_abbreviation) - dbgap_current_status = models.dbGaPDataAccessRequest.APPROVED - dbgap_dac = Faker("word") class Params: dbgap_workspace = None diff --git a/primed/dbgap/tests/test_models.py b/primed/dbgap/tests/test_models.py index 96377228..fac53f3c 100644 --- a/primed/dbgap/tests/test_models.py +++ b/primed/dbgap/tests/test_models.py @@ -1525,3 +1525,31 @@ def test_get_dbgap_link(self): """`get_dbgab_link` returns a link.""" instance = factories.dbGaPDataAccessRequestFactory.create() self.assertIsInstance(instance.get_dbgap_link(), str) + + def test_get_studies_no_matches(self): + """Returns an empty queryset when there is no matching studies.""" + factories.dbGaPStudyAccessionFactory.create() + dar = factories.dbGaPDataAccessRequestFactory.create() + self.assertEqual(dar.get_matching_studies().count(), 0) + + def test_get_studies_one_match(self): + """Returns the correct study when there is one match.""" + test_study = StudyFactory.create(short_name="Test", full_name="Test Study") + dbgap_study_accession = factories.dbGaPStudyAccessionFactory.create(dbgap_phs=1, studies=[test_study]) + dar = factories.dbGaPDataAccessRequestFactory.create(dbgap_phs=dbgap_study_accession.dbgap_phs) + qs = dar.get_matching_studies() + self.assertEqual(qs.count(), 1) + self.assertEqual(qs[0], test_study) + + def test_get_studies_two_match(self): + """Returns the correct studies when there are 2 match.""" + test_study_1 = StudyFactory.create(short_name="Test 1", full_name="Test Study 1") + test_study_2 = StudyFactory.create(short_name="Test 2", full_name="Test Study 2") + dbgap_study_accession = factories.dbGaPStudyAccessionFactory.create( + dbgap_phs=1, studies=[test_study_1, test_study_2] + ) + dar = factories.dbGaPDataAccessRequestFactory.create(dbgap_phs=dbgap_study_accession.dbgap_phs) + qs = dar.get_matching_studies() + self.assertEqual(qs.count(), 2) + self.assertEqual(qs[0], test_study_1) + self.assertEqual(qs[1], test_study_2) diff --git a/primed/dbgap/tests/test_tables.py b/primed/dbgap/tests/test_tables.py index 8aeda44b..b6e66d8e 100644 --- a/primed/dbgap/tests/test_tables.py +++ b/primed/dbgap/tests/test_tables.py @@ -694,6 +694,26 @@ def test_ordering(self): self.assertEqual(table.data[0], instance_2) self.assertEqual(table.data[1], instance_1) + def test_one_matching_study(self): + """Table works if there is a matching study""" + test_study = factories.StudyFactory.create(short_name="Test", full_name="Test Study") + dbgap_study_accession = factories.dbGaPStudyAccessionFactory.create(dbgap_phs=1, studies=[test_study]) + dar = factories.dbGaPDataAccessRequestFactory.create(dbgap_phs=dbgap_study_accession.dbgap_phs) + table = self.table_class([dar]) + self.assertIn(test_study.short_name, table.rows[0].get_cell("matching_studies")) + + def test_two_matching_studies(self): + """Table works if there is are two matching studies""" + test_study_1 = factories.StudyFactory.create(short_name="Test 1", full_name="Test Study 1") + test_study_2 = factories.StudyFactory.create(short_name="Test 2", full_name="Test Study 2") + dbgap_study_accession = factories.dbGaPStudyAccessionFactory.create( + dbgap_phs=1, studies=[test_study_1, test_study_2] + ) + dar = factories.dbGaPDataAccessRequestFactory.create(dbgap_phs=dbgap_study_accession.dbgap_phs) + table = self.table_class([dar]) + self.assertIn(test_study_1.short_name, table.rows[0].get_cell("matching_studies")) + self.assertIn(test_study_2.short_name, table.rows[0].get_cell("matching_studies")) + class dbGaPDataAccessRequestSummaryTable(TestCase): model = models.dbGaPDataAccessRequest diff --git a/primed/dbgap/tests/test_views.py b/primed/dbgap/tests/test_views.py index e668b5f0..dac703a4 100644 --- a/primed/dbgap/tests/test_views.py +++ b/primed/dbgap/tests/test_views.py @@ -2141,17 +2141,17 @@ def test_error_missing_json(self): def test_get_dbgap_application_pk_does_not_exist(self): """Raises a 404 error with an invalid object dbgap_application_pk.""" - request = self.factory.get(self.get_url(self.dbgap_application.pk + 1)) + request = self.factory.get(self.get_url(self.dbgap_application.pk + 999)) request.user = self.user with self.assertRaises(Http404): - self.get_view()(request, dbgap_project_id=self.dbgap_application.pk + 1) + self.get_view()(request, dbgap_project_id=self.dbgap_application.pk + 999) def test_post_dbgap_application_pk_does_not_exist(self): """Raises a 404 error with an invalid object dbgap_application_pk.""" - request = self.factory.post(self.get_url(self.dbgap_application.pk + 1), {}) + request = self.factory.post(self.get_url(self.dbgap_application.pk + 999), {}) request.user = self.user with self.assertRaises(Http404): - self.get_view()(request, dbgap_project_id=self.dbgap_application.pk + 1) + self.get_view()(request, dbgap_project_id=self.dbgap_application.pk + 999) def test_has_form_when_one_snapshot_exists(self): phs_int = fake.random_int()