From 2f8c5c0620751e7c23ba94d8e5d2dc6f930205ff Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Mon, 29 Apr 2024 15:05:15 -0700 Subject: [PATCH 1/6] Add ruff to requirements file --- requirements/dev-requirements.in | 1 + requirements/dev-requirements.txt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/requirements/dev-requirements.in b/requirements/dev-requirements.in index 54932d32..37e02e6e 100644 --- a/requirements/dev-requirements.in +++ b/requirements/dev-requirements.in @@ -22,6 +22,7 @@ flake8-isort # https://github.com/gforcada/flake8-isort black # https://github.com/psf/black pylint-django # https://github.com/PyCQA/pylint-django pre-commit # https://github.com/pre-commit/pre-commit +ruff # https://github.com/astral-sh/ruff # Django # ------------------------------------------------------------------------------ diff --git a/requirements/dev-requirements.txt b/requirements/dev-requirements.txt index c906820f..133d6577 100644 --- a/requirements/dev-requirements.txt +++ b/requirements/dev-requirements.txt @@ -179,6 +179,8 @@ requests==2.31.0 # -c requirements.txt # -c test-requirements.txt # sphinx +ruff==0.4.2 + # via -r requirements/dev-requirements.in six==1.16.0 # via # -c requirements.txt From 34653daf7ccebaa4df3972dec259718f7ba50cc7 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Mon, 29 Apr 2024 15:18:47 -0700 Subject: [PATCH 2/6] Run ruff check --fix on all files --- primed/cdsa/tests/test_migrations.py | 4 ---- primed/miscellaneous_workspaces/tests/test_migrations.py | 9 +-------- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/primed/cdsa/tests/test_migrations.py b/primed/cdsa/tests/test_migrations.py index d355392c..02351d33 100644 --- a/primed/cdsa/tests/test_migrations.py +++ b/primed/cdsa/tests/test_migrations.py @@ -1,11 +1,7 @@ """Tests for data migrations in the app.""" -from datetime import date -from anvil_consortium_manager.tests.factories import BillingProjectFactory, WorkspaceFactory from django_test_migrations.contrib.unittest_case import MigratorTestCase -import factory -from primed.primed_anvil.tests.factories import StudySiteFactory class AgreementMajorVersionMigrationsTest(MigratorTestCase): diff --git a/primed/miscellaneous_workspaces/tests/test_migrations.py b/primed/miscellaneous_workspaces/tests/test_migrations.py index 51a1afa5..e5c4d2df 100644 --- a/primed/miscellaneous_workspaces/tests/test_migrations.py +++ b/primed/miscellaneous_workspaces/tests/test_migrations.py @@ -1,11 +1,7 @@ """Tests for migrations in the miscellaneous_workspaces app.""" -from anvil_consortium_manager.tests.factories import BillingProjectFactory, WorkspaceFactory from django_test_migrations.contrib.unittest_case import MigratorTestCase -from primed.users.tests.factories import UserFactory -import factory -from . import factories class ExampleToResourceWorkspaceForwardMigrationTest(MigratorTestCase): """Tests for the migrations associated with renaming the ExampleWorkspace to ResourceWorkspace.""" @@ -53,7 +49,7 @@ def prepare(self): def test_workspace_updates(self): """Test updates to the workspace model.""" Workspace = self.new_state.apps.get_model("anvil_consortium_manager", "Workspace") - ResourceWorkspace = self.new_state.apps.get_model("miscellaneous_workspaces", "ResourceWorkspace") + self.new_state.apps.get_model("miscellaneous_workspaces", "ResourceWorkspace") workspace = Workspace.objects.get(pk=self.workspace_1.pk) self.assertEqual(workspace.workspace_type, "resource") workspace.full_clean() @@ -66,7 +62,6 @@ def test_workspace_updates(self): def test_resource_workspace_updates(self): """Test updates to the ResourceWorkspace model.""" - Workspace = self.new_state.apps.get_model("anvil_consortium_manager", "Workspace") ResourceWorkspace = self.new_state.apps.get_model("miscellaneous_workspaces", "ResourceWorkspace") resource_workspace = ResourceWorkspace.objects.get(pk=self.example_workspace_1.pk) resource_workspace.full_clean() @@ -135,7 +130,6 @@ def prepare(self): def test_workspace_updates(self): """Test updates to the workspace model.""" Workspace = self.new_state.apps.get_model("anvil_consortium_manager", "Workspace") - ExampleWorkspace = self.new_state.apps.get_model("miscellaneous_workspaces", "ExampleWorkspace") workspace = Workspace.objects.get(pk=self.workspace_1.pk) self.assertEqual(workspace.workspace_type, "example") workspace.full_clean() @@ -148,7 +142,6 @@ def test_workspace_updates(self): def test_resource_workspace_updates(self): """Test updates to the ResourceWorkspace model.""" - Workspace = self.new_state.apps.get_model("anvil_consortium_manager", "Workspace") ExampleWorkspace = self.new_state.apps.get_model("miscellaneous_workspaces", "ExampleWorkspace") example_workspace = ExampleWorkspace.objects.get(pk=self.resource_workspace_1.pk) example_workspace.full_clean() From 0f2ae44a9e5005ef1b30c5739cf5dedd47d5ed9e Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Mon, 29 Apr 2024 15:30:38 -0700 Subject: [PATCH 3/6] Add ruff configuration and rerun ruff check --- .ruff.toml | 20 +++++++++++ ...ter_cdsaworkspace_disease_term_and_more.py | 35 +++++++++++++++++++ primed/cdsa/models.py | 6 ++-- primed/cdsa/tests/test_migrations.py | 1 - ...er_dbgapworkspace_disease_term_and_more.py | 35 +++++++++++++++++++ primed/dbgap/models.py | 18 +++++----- primed/duo/models.py | 2 +- 7 files changed, 103 insertions(+), 14 deletions(-) create mode 100644 .ruff.toml create mode 100644 primed/cdsa/migrations/0023_alter_cdsaworkspace_disease_term_and_more.py create mode 100644 primed/dbgap/migrations/0012_alter_dbgapworkspace_disease_term_and_more.py diff --git a/.ruff.toml b/.ruff.toml new file mode 100644 index 00000000..78a87d59 --- /dev/null +++ b/.ruff.toml @@ -0,0 +1,20 @@ +line-length = 120 +exclude = [ + "**/migrations/**", + "*/static/CACHE/*", + "venv", + "docs", +] + +[lint] +extend-select = [ + "E", + "F", + "W", # pycodestyle warnings + "I", # isort + "DJ", # flake8-django + "E501", # line-too-long +] + +[lint.isort] +known-first-party = ["primed", "config", ] diff --git a/primed/cdsa/migrations/0023_alter_cdsaworkspace_disease_term_and_more.py b/primed/cdsa/migrations/0023_alter_cdsaworkspace_disease_term_and_more.py new file mode 100644 index 00000000..88e103b5 --- /dev/null +++ b/primed/cdsa/migrations/0023_alter_cdsaworkspace_disease_term_and_more.py @@ -0,0 +1,35 @@ +# Generated by Django 4.2.11 on 2024-04-29 22:20 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("cdsa", "0022_remove_signedagreement_is_primary"), + ] + + operations = [ + migrations.AlterField( + model_name="cdsaworkspace", + name="disease_term", + field=models.CharField( + blank=True, + default="", + help_text="The disease term if required by data_use_permission.", + max_length=255, + verbose_name="DUO disease term", + ), + ), + migrations.AlterField( + model_name="historicalcdsaworkspace", + name="disease_term", + field=models.CharField( + blank=True, + default="", + help_text="The disease term if required by data_use_permission.", + max_length=255, + verbose_name="DUO disease term", + ), + ), + ] diff --git a/primed/cdsa/models.py b/primed/cdsa/models.py index 4ba3cdec..6c66ed23 100644 --- a/primed/cdsa/models.py +++ b/primed/cdsa/models.py @@ -175,6 +175,9 @@ class SignedAgreement( def __str__(self): return "{}".format(self.cc_id) + def get_absolute_url(self): + return self.get_agreement_type().get_absolute_url() + @property def combined_type(self): combined_type = self.get_type_display() @@ -187,9 +190,6 @@ def combined_type(self): combined_type = combined_type + " component" return combined_type - def get_absolute_url(self): - return self.get_agreement_type().get_absolute_url() - def get_agreement_type(self): if self.type == self.MEMBER: return self.memberagreement diff --git a/primed/cdsa/tests/test_migrations.py b/primed/cdsa/tests/test_migrations.py index 02351d33..7a609516 100644 --- a/primed/cdsa/tests/test_migrations.py +++ b/primed/cdsa/tests/test_migrations.py @@ -3,7 +3,6 @@ from django_test_migrations.contrib.unittest_case import MigratorTestCase - class AgreementMajorVersionMigrationsTest(MigratorTestCase): """Tests for the migrations associated with creating the new AgreementMajorVersion model.""" diff --git a/primed/dbgap/migrations/0012_alter_dbgapworkspace_disease_term_and_more.py b/primed/dbgap/migrations/0012_alter_dbgapworkspace_disease_term_and_more.py new file mode 100644 index 00000000..2ea3c8da --- /dev/null +++ b/primed/dbgap/migrations/0012_alter_dbgapworkspace_disease_term_and_more.py @@ -0,0 +1,35 @@ +# Generated by Django 4.2.11 on 2024-04-29 22:20 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("dbgap", "0011_gsr_restricted_help_and_verbose"), + ] + + operations = [ + migrations.AlterField( + model_name="dbgapworkspace", + name="disease_term", + field=models.CharField( + blank=True, + default="", + help_text="The disease term if required by data_use_permission.", + max_length=255, + verbose_name="DUO disease term", + ), + ), + migrations.AlterField( + model_name="historicaldbgapworkspace", + name="disease_term", + field=models.CharField( + blank=True, + default="", + help_text="The disease term if required by data_use_permission.", + max_length=255, + verbose_name="DUO disease term", + ), + ), + ] diff --git a/primed/dbgap/models.py b/primed/dbgap/models.py index d9c1d560..0260a9ce 100644 --- a/primed/dbgap/models.py +++ b/primed/dbgap/models.py @@ -226,6 +226,15 @@ def __str__(self): """String method.""" return "{}".format(self.created) + def get_absolute_url(self): + return reverse( + "dbgap:dbgap_applications:dbgap_data_access_snapshots:detail", + kwargs={ + "dbgap_project_id": self.dbgap_application.dbgap_project_id, + "dbgap_data_access_snapshot_pk": self.pk, + }, + ) + def clean(self): """Perform custom model cleaning. @@ -248,15 +257,6 @@ def clean(self): "Project_id in JSON does not match dbgap_application.dbgap_project_id." ) - def get_absolute_url(self): - return reverse( - "dbgap:dbgap_applications:dbgap_data_access_snapshots:detail", - kwargs={ - "dbgap_project_id": self.dbgap_application.dbgap_project_id, - "dbgap_data_access_snapshot_pk": self.pk, - }, - ) - def create_dars_from_json(self): """Add DARs for this application from the dbGaP json for this project snapshot. diff --git a/primed/duo/models.py b/primed/duo/models.py index 7c6efb25..9b3414e9 100644 --- a/primed/duo/models.py +++ b/primed/duo/models.py @@ -90,7 +90,7 @@ class DataUseOntologyModel(models.Model): verbose_name="DUO disease term", max_length=255, blank=True, - null=True, + default="", help_text="The disease term if required by data_use_permission.", ) From 5f2e9b8cecac416960c14c3e09d809e82f4b7a9a Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Mon, 29 Apr 2024 15:38:10 -0700 Subject: [PATCH 4/6] Run ruff format on all files --- add_cdsa_example_data.py | 44 +- add_collaborative_analysis_example_data.py | 32 +- add_dbgap_example_data.py | 28 +- add_phenotype_inventory_input_example_data.py | 12 +- config/settings/base.py | 20 +- config/settings/local.py | 12 +- config/settings/production.py | 19 +- config/urls.py | 12 +- config/wsgi.py | 1 + primed/__init__.py | 7 +- primed/cdsa/adapters.py | 16 +- primed/cdsa/audit/signed_agreement_audit.py | 28 +- primed/cdsa/audit/workspace_audit.py | 27 +- primed/cdsa/forms.py | 4 +- .../cdsa/management/commands/cdsa_records.py | 6 +- .../management/commands/run_cdsa_audit.py | 20 +- primed/cdsa/models.py | 34 +- primed/cdsa/tables.py | 30 +- primed/cdsa/tests/factories.py | 24 +- primed/cdsa/tests/test_audit.py | 172 +-- primed/cdsa/tests/test_commands.py | 82 +- primed/cdsa/tests/test_forms.py | 32 +- primed/cdsa/tests/test_migrations.py | 12 +- primed/cdsa/tests/test_models.py | 140 +- primed/cdsa/tests/test_tables.py | 104 +- primed/cdsa/tests/test_views.py | 1309 +++++------------ primed/cdsa/urls.py | 4 +- primed/cdsa/views.py | 170 +-- primed/collaborative_analysis/adapters.py | 4 +- primed/collaborative_analysis/audit.py | 33 +- .../run_collaborative_analysis_audit.py | 12 +- primed/collaborative_analysis/models.py | 1 - .../collaborative_analysis/tests/factories.py | 8 +- .../tests/test_audit.py | 192 +-- .../tests/test_commands.py | 28 +- .../tests/test_tables.py | 16 +- .../tests/test_views.py | 332 ++--- primed/collaborative_analysis/views.py | 50 +- primed/dbgap/adapters.py | 12 +- primed/dbgap/audit.py | 40 +- primed/dbgap/constants.py | 4 +- primed/dbgap/forms.py | 16 +- .../management/commands/run_dbgap_audit.py | 12 +- primed/dbgap/models.py | 48 +- primed/dbgap/tables.py | 18 +- primed/dbgap/tests/factories.py | 20 +- primed/dbgap/tests/test_audit.py | 72 +- primed/dbgap/tests/test_commands.py | 28 +- primed/dbgap/tests/test_forms.py | 40 +- primed/dbgap/tests/test_models.py | 132 +- primed/dbgap/tests/test_tables.py | 97 +- primed/dbgap/tests/test_views.py | 1245 ++++------------ primed/dbgap/urls.py | 4 +- primed/dbgap/views.py | 156 +- primed/drupal_oauth_provider/provider.py | 5 +- primed/drupal_oauth_provider/views.py | 17 +- primed/duo/management/commands/load_duo.py | 21 +- primed/duo/models.py | 7 +- primed/duo/tests/test_commands.py | 8 +- primed/duo/tests/test_models.py | 60 +- primed/duo/tests/test_views.py | 16 +- primed/duo/views.py | 10 +- primed/miscellaneous_workspaces/adapters.py | 16 +- primed/miscellaneous_workspaces/models.py | 12 +- primed/miscellaneous_workspaces/tables.py | 8 +- .../tests/test_forms.py | 12 +- .../tests/test_models.py | 50 +- .../tests/test_views.py | 240 +-- primed/primed_anvil/adapters.py | 4 +- primed/primed_anvil/audit.py | 12 +- primed/primed_anvil/helpers.py | 4 +- primed/primed_anvil/models.py | 8 +- primed/primed_anvil/tables.py | 18 +- primed/primed_anvil/tests/test_adapters.py | 28 +- primed/primed_anvil/tests/test_audit.py | 2 +- primed/primed_anvil/tests/test_helpers.py | 96 +- primed/primed_anvil/tests/test_models.py | 8 +- primed/primed_anvil/tests/test_tables.py | 5 +- primed/primed_anvil/tests/test_views.py | 321 +--- primed/primed_anvil/views.py | 42 +- primed/users/adapters.py | 16 +- primed/users/admin.py | 1 - primed/users/audit.py | 82 +- primed/users/forms.py | 4 +- primed/users/tests/factories.py | 1 - primed/users/tests/test_adapters.py | 25 +- primed/users/tests/test_audit.py | 75 +- primed/users/tests/test_forms.py | 2 +- primed/users/tests/test_urls.py | 5 +- primed/users/tests/test_views.py | 91 +- primed/users/views.py | 3 - 91 files changed, 1558 insertions(+), 4798 deletions(-) diff --git a/add_cdsa_example_data.py b/add_cdsa_example_data.py index da5c0058..905c3165 100644 --- a/add_cdsa_example_data.py +++ b/add_cdsa_example_data.py @@ -29,12 +29,8 @@ major_version = factories.AgreementMajorVersionFactory.create(version=1) # Create some agreement versions -v10 = factories.AgreementVersionFactory.create( - major_version=major_version, minor_version=0 -) -v11 = factories.AgreementVersionFactory.create( - major_version=major_version, minor_version=1 -) +v10 = factories.AgreementVersionFactory.create(major_version=major_version, minor_version=0) +v11 = factories.AgreementVersionFactory.create(major_version=major_version, minor_version=1) # Create a couple signed CDSAs. dup = DataUsePermission.objects.get(abbreviation="GRU") @@ -57,9 +53,7 @@ signed_agreement__version=v10, study_site=StudySite.objects.get(short_name="CC"), ) -GroupGroupMembershipFactory.create( - parent_group=cdsa_group, child_group=cdsa_1001.signed_agreement.anvil_access_group -) +GroupGroupMembershipFactory.create(parent_group=cdsa_group, child_group=cdsa_1001.signed_agreement.anvil_access_group) cdsa_1002 = factories.MemberAgreementFactory.create( signed_agreement__cc_id=1002, @@ -70,9 +64,7 @@ signed_agreement__version=v10, study_site=StudySite.objects.get(short_name="CARDINAL"), ) -GroupGroupMembershipFactory.create( - parent_group=cdsa_group, child_group=cdsa_1002.signed_agreement.anvil_access_group -) +GroupGroupMembershipFactory.create(parent_group=cdsa_group, child_group=cdsa_1002.signed_agreement.anvil_access_group) cdsa_1003 = factories.MemberAgreementFactory.create( signed_agreement__cc_id=1003, @@ -83,9 +75,7 @@ signed_agreement__version=v10, study_site=StudySite.objects.get(short_name="CARDINAL"), ) -GroupGroupMembershipFactory.create( - parent_group=cdsa_group, child_group=cdsa_1003.signed_agreement.anvil_access_group -) +GroupGroupMembershipFactory.create(parent_group=cdsa_group, child_group=cdsa_1003.signed_agreement.anvil_access_group) cdsa_1004 = factories.MemberAgreementFactory.create( signed_agreement__cc_id=1004, @@ -96,9 +86,7 @@ signed_agreement__version=v11, study_site=StudySite.objects.get(short_name="CARDINAL"), ) -GroupGroupMembershipFactory.create( - parent_group=cdsa_group, child_group=cdsa_1004.signed_agreement.anvil_access_group -) +GroupGroupMembershipFactory.create(parent_group=cdsa_group, child_group=cdsa_1004.signed_agreement.anvil_access_group) cdsa_1005 = factories.DataAffiliateAgreementFactory.create( signed_agreement__cc_id=1005, @@ -108,9 +96,7 @@ study=Study.objects.get(short_name="Amish"), signed_agreement__version=v10, ) -GroupGroupMembershipFactory.create( - parent_group=cdsa_group, child_group=cdsa_1005.signed_agreement.anvil_access_group -) +GroupGroupMembershipFactory.create(parent_group=cdsa_group, child_group=cdsa_1005.signed_agreement.anvil_access_group) cdsa_1006 = factories.DataAffiliateAgreementFactory.create( signed_agreement__cc_id=1006, @@ -122,9 +108,7 @@ additional_limitations="This data can only be used for testing the app.", requires_study_review=True, ) -GroupGroupMembershipFactory.create( - parent_group=cdsa_group, child_group=cdsa_1006.signed_agreement.anvil_access_group -) +GroupGroupMembershipFactory.create(parent_group=cdsa_group, child_group=cdsa_1006.signed_agreement.anvil_access_group) cdsa_1007 = factories.DataAffiliateAgreementFactory.create( signed_agreement__cc_id=1007, @@ -135,9 +119,7 @@ study=Study.objects.get(short_name="MESA"), signed_agreement__version=v10, ) -GroupGroupMembershipFactory.create( - parent_group=cdsa_group, child_group=cdsa_1007.signed_agreement.anvil_access_group -) +GroupGroupMembershipFactory.create(parent_group=cdsa_group, child_group=cdsa_1007.signed_agreement.anvil_access_group) cdsa_1008 = factories.DataAffiliateAgreementFactory.create( signed_agreement__cc_id=1008, @@ -148,9 +130,7 @@ study=Study.objects.get(short_name="MESA"), signed_agreement__version=v10, ) -GroupGroupMembershipFactory.create( - parent_group=cdsa_group, child_group=cdsa_1008.signed_agreement.anvil_access_group -) +GroupGroupMembershipFactory.create(parent_group=cdsa_group, child_group=cdsa_1008.signed_agreement.anvil_access_group) cdsa_1009 = factories.NonDataAffiliateAgreementFactory.create( signed_agreement__cc_id=1009, @@ -236,8 +216,6 @@ cdsa_workspace_3 = factories.CDSAWorkspaceFactory.create( workspace__billing_project__name="demo-primed-cdsa", workspace__name="DEMO_PRIMED_CDSA_ARIC_1", - study=Study.objects.create( - short_name="ARIC", full_name="Atherosclerosis Risk in Communities" - ), + study=Study.objects.create(short_name="ARIC", full_name="Atherosclerosis Risk in Communities"), data_use_permission=dup, ) diff --git a/add_collaborative_analysis_example_data.py b/add_collaborative_analysis_example_data.py index 550e9317..39583776 100644 --- a/add_collaborative_analysis_example_data.py +++ b/add_collaborative_analysis_example_data.py @@ -55,27 +55,15 @@ # Add accounts to the auth domains. -account_1 = AccountFactory.create( - user__name="Adrienne", verified=True, email="adrienne@example.com" -) -account_2 = AccountFactory.create( - user__name="Ben", verified=True, email="ben@example.com" -) -account_3 = AccountFactory.create( - user__name="Matt", verified=True, email="matt@example.com" -) -account_4 = AccountFactory.create( - user__name="Stephanie", verified=True, email="stephanie@example.com" -) +account_1 = AccountFactory.create(user__name="Adrienne", verified=True, email="adrienne@example.com") +account_2 = AccountFactory.create(user__name="Ben", verified=True, email="ben@example.com") +account_3 = AccountFactory.create(user__name="Matt", verified=True, email="matt@example.com") +account_4 = AccountFactory.create(user__name="Stephanie", verified=True, email="stephanie@example.com") # Set up collab analysis workspace one # analyst group -GroupAccountMembershipFactory.create( - account=account_1, group=collaborative_analysis_workspace_1.analyst_group -) -GroupAccountMembershipFactory.create( - account=account_2, group=collaborative_analysis_workspace_1.analyst_group -) +GroupAccountMembershipFactory.create(account=account_1, group=collaborative_analysis_workspace_1.analyst_group) +GroupAccountMembershipFactory.create(account=account_2, group=collaborative_analysis_workspace_1.analyst_group) # auth domains GroupAccountMembershipFactory.create( account=account_1, @@ -84,12 +72,8 @@ # Set up collab analysis workspace two # analyst group -GroupAccountMembershipFactory.create( - account=account_3, group=collaborative_analysis_workspace_2.analyst_group -) -GroupAccountMembershipFactory.create( - account=account_4, group=collaborative_analysis_workspace_2.analyst_group -) +GroupAccountMembershipFactory.create(account=account_3, group=collaborative_analysis_workspace_2.analyst_group) +GroupAccountMembershipFactory.create(account=account_4, group=collaborative_analysis_workspace_2.analyst_group) # auth domains GroupAccountMembershipFactory.create( account=account_3, diff --git a/add_dbgap_example_data.py b/add_dbgap_example_data.py index 03b91535..4075ad82 100644 --- a/add_dbgap_example_data.py +++ b/add_dbgap_example_data.py @@ -10,23 +10,13 @@ # Studies fhs = StudyFactory.create(short_name="FHS", full_name="Framingham Heart Study") -mesa = StudyFactory.create( - short_name="MESA", full_name="Multi-Ethnic Study of Atherosclerosis" -) -aric = StudyFactory.create( - short_name="ARIC", full_name="Atherosclerosis Risk in Communities" -) +mesa = StudyFactory.create(short_name="MESA", full_name="Multi-Ethnic Study of Atherosclerosis") +aric = StudyFactory.create(short_name="ARIC", full_name="Atherosclerosis Risk in Communities") # dbGaP study accessions -dbgap_study_accession_fhs = factories.dbGaPStudyAccessionFactory.create( - dbgap_phs=7, studies=[fhs] -) -dbgap_study_accession_mesa = factories.dbGaPStudyAccessionFactory.create( - dbgap_phs=209, studies=[mesa] -) -dbgap_study_accession_aric = factories.dbGaPStudyAccessionFactory.create( - dbgap_phs=280, studies=[aric] -) +dbgap_study_accession_fhs = factories.dbGaPStudyAccessionFactory.create(dbgap_phs=7, studies=[fhs]) +dbgap_study_accession_mesa = factories.dbGaPStudyAccessionFactory.create(dbgap_phs=209, studies=[mesa]) +dbgap_study_accession_aric = factories.dbGaPStudyAccessionFactory.create(dbgap_phs=280, studies=[aric]) # Create some dbGaP workspaces. @@ -78,9 +68,7 @@ dbgap_project_id=33119, ) # Add a snapshot -dar_snapshot_1 = factories.dbGaPDataAccessSnapshotFactory.create( - dbgap_application=dbgap_application_1 -) +dar_snapshot_1 = factories.dbGaPDataAccessSnapshotFactory.create(dbgap_application=dbgap_application_1) # Add some data access requests. dar_1_1 = factories.dbGaPDataAccessRequestForWorkspaceFactory.create( dbgap_workspace=workspace_fhs_1, @@ -112,9 +100,7 @@ dbgap_project_id=33371, ) # Add a snapshot -dar_snapshot_2 = factories.dbGaPDataAccessSnapshotFactory.create( - dbgap_application=dbgap_application_2 -) +dar_snapshot_2 = factories.dbGaPDataAccessSnapshotFactory.create(dbgap_application=dbgap_application_2) # Add some data access requests, only for FHS. dar_1_1 = factories.dbGaPDataAccessRequestForWorkspaceFactory.create( dbgap_workspace=workspace_fhs_1, diff --git a/add_phenotype_inventory_input_example_data.py b/add_phenotype_inventory_input_example_data.py index 427c6477..fad9de8d 100644 --- a/add_phenotype_inventory_input_example_data.py +++ b/add_phenotype_inventory_input_example_data.py @@ -39,12 +39,6 @@ # Share workspaces with PRIMED_ALL primed_all = ManagedGroupFactory.create(name="PRIMED_ALL") -WorkspaceGroupSharingFactory.create( - workspace=workspace_dbgap.workspace, group=primed_all -) -WorkspaceGroupSharingFactory.create( - workspace=workspace_cdsa.workspace, group=primed_all -) -WorkspaceGroupSharingFactory.create( - workspace=workspace_open_access.workspace, group=primed_all -) +WorkspaceGroupSharingFactory.create(workspace=workspace_dbgap.workspace, group=primed_all) +WorkspaceGroupSharingFactory.create(workspace=workspace_cdsa.workspace, group=primed_all) +WorkspaceGroupSharingFactory.create(workspace=workspace_open_access.workspace, group=primed_all) diff --git a/config/settings/base.py b/config/settings/base.py index 01092f24..26b16d38 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -1,6 +1,7 @@ """ Base settings to build other settings files upon. """ + from pathlib import Path import environ @@ -135,9 +136,7 @@ ] # https://docs.djangoproject.com/en/dev/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ - { - "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator" - }, + {"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"}, {"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"}, {"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"}, {"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"}, @@ -264,12 +263,7 @@ LOGGING = { "version": 1, "disable_existing_loggers": False, - "formatters": { - "verbose": { - "format": "%(levelname)s %(asctime)s %(module)s " - "%(process)d %(thread)d %(message)s" - } - }, + "formatters": {"verbose": {"format": "%(levelname)s %(asctime)s %(module)s " "%(process)d %(thread)d %(message)s"}}, "handlers": { "console": { "level": "DEBUG", @@ -407,9 +401,5 @@ DRUPAL_API_CLIENT_ID = env("DRUPAL_API_CLIENT_ID", default="") DRUPAL_API_CLIENT_SECRET = env("DRUPAL_API_CLIENT_SECRET", default="") DRUPAL_API_REL_PATH = env("DRUPAL_API_REL_PATH", default="mockapi") -DRUPAL_DATA_AUDIT_DEACTIVATE_USERS = env( - "DRUPAL_DATA_AUDIT_DEACTIVATE_USERS", default=False -) -DRUPAL_DATA_AUDIT_REMOVE_USER_SITES = env( - "DRUPAL_DATA_AUDIT_REMOVE_USER_SITES", default=False -) +DRUPAL_DATA_AUDIT_DEACTIVATE_USERS = env("DRUPAL_DATA_AUDIT_DEACTIVATE_USERS", default=False) +DRUPAL_DATA_AUDIT_REMOVE_USER_SITES = env("DRUPAL_DATA_AUDIT_REMOVE_USER_SITES", default=False) diff --git a/config/settings/local.py b/config/settings/local.py index 789b1f6d..fe675bdc 100644 --- a/config/settings/local.py +++ b/config/settings/local.py @@ -26,9 +26,7 @@ # EMAIL # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#email-backend -EMAIL_BACKEND = env( - "DJANGO_EMAIL_BACKEND", default="django.core.mail.backends.console.EmailBackend" -) +EMAIL_BACKEND = env("DJANGO_EMAIL_BACKEND", default="django.core.mail.backends.console.EmailBackend") # WhiteNoise # ------------------------------------------------------------------------------ @@ -73,10 +71,6 @@ # ANVIL_CDSA_GROUP_PREFIX = env( # "ANVIL_CDSA_GROUP_PREFIX", default="DEV_PRIMED_CDSA_ACCESS" # ) -ANVIL_DATA_ACCESS_GROUP_PREFIX = env( - "ANVIL_DATA_ACCESS_GROUP_PREFIX", default="DEV_PRIMED" -) +ANVIL_DATA_ACCESS_GROUP_PREFIX = env("ANVIL_DATA_ACCESS_GROUP_PREFIX", default="DEV_PRIMED") ANVIL_CDSA_GROUP_NAME = env("ANVIL_CDSA_GROUP_NAME", default="DEV_PRIMED_CDSA") -ANVIL_CC_ADMINS_GROUP_NAME = env( - "ANVIL_CC_ADMINS_GROUP_NAME", default="DEV_PRIMED_CC_ADMINS" -) +ANVIL_CC_ADMINS_GROUP_NAME = env("ANVIL_CC_ADMINS_GROUP_NAME", default="DEV_PRIMED_CC_ADMINS") diff --git a/config/settings/production.py b/config/settings/production.py index 311aa3e8..d325df2e 100644 --- a/config/settings/production.py +++ b/config/settings/production.py @@ -57,15 +57,11 @@ # in our apache configuration. Having in both places causes duplicate header SECURE_HSTS_SECONDS = 0 # https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-include-subdomains -SECURE_HSTS_INCLUDE_SUBDOMAINS = env.bool( - "DJANGO_SECURE_HSTS_INCLUDE_SUBDOMAINS", default=True -) +SECURE_HSTS_INCLUDE_SUBDOMAINS = env.bool("DJANGO_SECURE_HSTS_INCLUDE_SUBDOMAINS", default=True) # https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-preload SECURE_HSTS_PRELOAD = env.bool("DJANGO_SECURE_HSTS_PRELOAD", default=True) # https://docs.djangoproject.com/en/dev/ref/middleware/#x-content-type-options-nosniff -SECURE_CONTENT_TYPE_NOSNIFF = env.bool( - "DJANGO_SECURE_CONTENT_TYPE_NOSNIFF", default=True -) +SECURE_CONTENT_TYPE_NOSNIFF = env.bool("DJANGO_SECURE_CONTENT_TYPE_NOSNIFF", default=True) # Since we have disabled HSTS above we get a warning when running check --deploy # we are manually silencing this as we have verified apache is enforcing # https://docs.djangoproject.com/en/dev/ref/checks/#security @@ -79,9 +75,7 @@ # EMAIL # ------------------------------------------------------------------------------ # https://docs.djangoproject.com/en/dev/ref/settings/#default-from-email -DEFAULT_FROM_EMAIL = env( - "DJANGO_DEFAULT_FROM_EMAIL", default="gac-django " -) +DEFAULT_FROM_EMAIL = env("DJANGO_DEFAULT_FROM_EMAIL", default="gac-django ") # https://docs.djangoproject.com/en/dev/ref/settings/#server-email SERVER_EMAIL = env("DJANGO_SERVER_EMAIL", default=DEFAULT_FROM_EMAIL) # https://docs.djangoproject.com/en/dev/ref/settings/#email-subject-prefix @@ -130,12 +124,7 @@ "()": "maintenance_mode.logging.RequireNotMaintenanceMode503", }, }, - "formatters": { - "verbose": { - "format": "%(levelname)s %(asctime)s %(module)s " - "%(process)d %(thread)d %(message)s" - } - }, + "formatters": {"verbose": {"format": "%(levelname)s %(asctime)s %(module)s " "%(process)d %(thread)d %(message)s"}}, "handlers": { "mail_admins": { "level": "ERROR", diff --git a/config/urls.py b/config/urls.py index 139e04ec..9b091d3f 100644 --- a/config/urls.py +++ b/config/urls.py @@ -7,9 +7,7 @@ urlpatterns = [ path("", TemplateView.as_view(template_name="pages/home.html"), name="home"), - path( - "about/", TemplateView.as_view(template_name="pages/about.html"), name="about" - ), + path("about/", TemplateView.as_view(template_name="pages/about.html"), name="about"), # Django Admin, use {% url 'admin:index' %} path(settings.ADMIN_URL, admin.site.urls), # User management @@ -20,17 +18,13 @@ "anvil/", include("anvil_consortium_manager.urls", namespace="anvil_consortium_manager"), ), - path( - "primed_anvil/", include("primed.primed_anvil.urls", namespace="primed_anvil") - ), + path("primed_anvil/", include("primed.primed_anvil.urls", namespace="primed_anvil")), path("dbgap/", include("primed.dbgap.urls", namespace="dbgap")), path("duo/", include("primed.duo.urls", namespace="duo")), path("cdsa/", include("primed.cdsa.urls", namespace="cdsa")), path( "collaborative_analysis/", - include( - "primed.collaborative_analysis.urls", namespace="collaborative_analysis" - ), + include("primed.collaborative_analysis.urls", namespace="collaborative_analysis"), ), ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/config/wsgi.py b/config/wsgi.py index b1f3c94e..f2af68ea 100644 --- a/config/wsgi.py +++ b/config/wsgi.py @@ -13,6 +13,7 @@ framework. """ + import os import sys from pathlib import Path diff --git a/primed/__init__.py b/primed/__init__.py index e1d86152..eed836da 100644 --- a/primed/__init__.py +++ b/primed/__init__.py @@ -1,7 +1,2 @@ __version__ = "0.1.0" -__version_info__ = tuple( - [ - int(num) if num.isdigit() else num - for num in __version__.replace("-", ".", 1).split(".") - ] -) +__version_info__ = tuple([int(num) if num.isdigit() else num for num in __version__.replace("-", ".", 1).split(".")]) diff --git a/primed/cdsa/adapters.py b/primed/cdsa/adapters.py index a4767906..78e6f169 100644 --- a/primed/cdsa/adapters.py +++ b/primed/cdsa/adapters.py @@ -12,9 +12,7 @@ class CDSAWorkspaceAdapter(BaseWorkspaceAdapter): type = "cdsa" name = "CDSA workspace" - description = ( - "Workspaces containing data from the Consortium Data Sharing Agreement" - ) + description = "Workspaces containing data from the Consortium Data Sharing Agreement" list_table_class_staff_view = tables.CDSAWorkspaceStaffTable list_table_class_view = tables.CDSAWorkspaceUserTable workspace_form_class = WorkspaceForm @@ -24,15 +22,9 @@ class CDSAWorkspaceAdapter(BaseWorkspaceAdapter): def get_extra_detail_context_data(self, workspace, request): extra_context = {} - associated_data_prep = Workspace.objects.filter( - dataprepworkspace__target_workspace=workspace - ) - extra_context["associated_data_prep_workspaces"] = DataPrepWorkspaceUserTable( - associated_data_prep - ) - extra_context["data_prep_active"] = associated_data_prep.filter( - dataprepworkspace__is_active=True - ).exists() + associated_data_prep = Workspace.objects.filter(dataprepworkspace__target_workspace=workspace) + extra_context["associated_data_prep_workspaces"] = DataPrepWorkspaceUserTable(associated_data_prep) + extra_context["data_prep_active"] = associated_data_prep.filter(dataprepworkspace__is_active=True).exists() # Get the primary CDSA for this study, assuming it exists. try: extra_context["primary_cdsa"] = workspace.cdsaworkspace.get_primary_cdsa() diff --git a/primed/cdsa/audit/signed_agreement_audit.py b/primed/cdsa/audit/signed_agreement_audit.py index 669df722..24c09365 100644 --- a/primed/cdsa/audit/signed_agreement_audit.py +++ b/primed/cdsa/audit/signed_agreement_audit.py @@ -22,9 +22,7 @@ class AccessAuditResult(PRIMEDAuditResult): action: str = None def __post_init__(self): - self.anvil_cdsa_group = ManagedGroup.objects.get( - name=settings.ANVIL_CDSA_GROUP_NAME - ) + self.anvil_cdsa_group = ManagedGroup.objects.get(name=settings.ANVIL_CDSA_GROUP_NAME) def get_action_url(self): """The URL that handles the action needed.""" @@ -97,9 +95,7 @@ class SignedAgreementAccessAuditTable(tables.Table): agreement_type = tables.Column(accessor="signed_agreement__combined_type") agreement_version = tables.Column(accessor="signed_agreement__version") note = tables.Column() - action = tables.TemplateColumn( - template_name="cdsa/snippets/cdsa_signedagreement_audit_action_button.html" - ) + action = tables.TemplateColumn(template_name="cdsa/snippets/cdsa_signedagreement_audit_action_button.html") class Meta: attrs = {"class": "table align-middle"} @@ -132,9 +128,7 @@ def __init__(self, signed_agreement_queryset=None): isinstance(signed_agreement_queryset, QuerySet) and signed_agreement_queryset.model is models.SignedAgreement ): - raise ValueError( - "signed_agreement_queryset must be a queryset of SignedAgreement objects." - ) + raise ValueError("signed_agreement_queryset must be a queryset of SignedAgreement objects.") self.signed_agreement_queryset = signed_agreement_queryset def _audit_primary_agreement(self, signed_agreement): @@ -147,9 +141,7 @@ def _audit_primary_agreement(self, signed_agreement): This audit does *not* check if the AgreementMajorVersion associated with the SignedAgreement is valid. """ in_cdsa_group = signed_agreement.is_in_cdsa_group() - is_active = ( - signed_agreement.status == models.SignedAgreement.StatusChoices.ACTIVE - ) + is_active = signed_agreement.status == models.SignedAgreement.StatusChoices.ACTIVE if is_active: if in_cdsa_group: @@ -189,9 +181,7 @@ def _audit_primary_agreement(self, signed_agreement): # If we made it this far in audit, some other case happened - log it as an error. # Haven't figured out a test for this because it is unexpected. self.errors.append( # pragma: no cover - OtherError( - signed_agreement=signed_agreement, note=self.ERROR_OTHER_CASE - ) # pragma: no cover + OtherError(signed_agreement=signed_agreement, note=self.ERROR_OTHER_CASE) # pragma: no cover ) # pragma: no cover def _audit_component_agreement(self, signed_agreement): @@ -207,9 +197,7 @@ def _audit_component_agreement(self, signed_agreement): SignedAgreement or its component is valid. """ in_cdsa_group = signed_agreement.is_in_cdsa_group() - is_active = ( - signed_agreement.status == models.SignedAgreement.StatusChoices.ACTIVE - ) + is_active = signed_agreement.status == models.SignedAgreement.StatusChoices.ACTIVE # Get the set of potential primary agreements for this component. if hasattr(signed_agreement, "memberagreement"): @@ -303,9 +291,7 @@ def _audit_component_agreement(self, signed_agreement): # If we made it this far in audit, some other case happened - log it as an error. # Haven't figured out a test for this because it is unexpected. self.errors.append( # pragma: no cover - OtherError( - signed_agreement=signed_agreement, note=self.ERROR_OTHER_CASE - ) # pragma: no cover + OtherError(signed_agreement=signed_agreement, note=self.ERROR_OTHER_CASE) # pragma: no cover ) # pragma: no cover def _audit_signed_agreement(self, signed_agreement): diff --git a/primed/cdsa/audit/workspace_audit.py b/primed/cdsa/audit/workspace_audit.py index e81d8287..9c0bff96 100644 --- a/primed/cdsa/audit/workspace_audit.py +++ b/primed/cdsa/audit/workspace_audit.py @@ -22,9 +22,7 @@ class AccessAuditResult(PRIMEDAuditResult): action: str = None def __post_init__(self): - self.anvil_cdsa_group = ManagedGroup.objects.get( - name=settings.ANVIL_CDSA_GROUP_NAME - ) + self.anvil_cdsa_group = ManagedGroup.objects.get(name=settings.ANVIL_CDSA_GROUP_NAME) def get_action_url(self): """The URL that handles the action needed.""" @@ -96,13 +94,9 @@ class WorkspaceAccessAuditTable(tables.Table): workspace = tables.Column(linkify=True) data_affiliate_agreement = tables.Column(linkify=True) - agreement_version = tables.Column( - accessor="data_affiliate_agreement__signed_agreement__version" - ) + agreement_version = tables.Column(accessor="data_affiliate_agreement__signed_agreement__version") note = tables.Column() - action = tables.TemplateColumn( - template_name="cdsa/snippets/cdsa_workspace_audit_action_button.html" - ) + action = tables.TemplateColumn(template_name="cdsa/snippets/cdsa_workspace_audit_action_button.html") class Meta: attrs = {"class": "table align-middle"} @@ -125,9 +119,7 @@ class WorkspaceAccessAudit(PRIMEDAudit): def __init__(self, cdsa_workspace_queryset=None): # Store the CDSA group for auditing membership. - self.anvil_cdsa_group = ManagedGroup.objects.get( - name=settings.ANVIL_CDSA_GROUP_NAME - ) + self.anvil_cdsa_group = ManagedGroup.objects.get(name=settings.ANVIL_CDSA_GROUP_NAME) self.completed = False # Set up lists to hold audit results. self.verified = [] @@ -137,12 +129,9 @@ def __init__(self, cdsa_workspace_queryset=None): if cdsa_workspace_queryset is None: cdsa_workspace_queryset = models.CDSAWorkspace.objects.all() if not ( - isinstance(cdsa_workspace_queryset, QuerySet) - and cdsa_workspace_queryset.model is models.CDSAWorkspace + isinstance(cdsa_workspace_queryset, QuerySet) and cdsa_workspace_queryset.model is models.CDSAWorkspace ): - raise ValueError( - "cdsa_workspace_queryset must be a queryset of CDSAWorkspace objects." - ) + raise ValueError("cdsa_workspace_queryset must be a queryset of CDSAWorkspace objects.") self.cdsa_workspace_queryset = cdsa_workspace_queryset def _audit_workspace(self, workspace): @@ -152,9 +141,7 @@ def _audit_workspace(self, workspace): parent_group=auth_domain, child_group=self.anvil_cdsa_group, ).exists() - primary_qs = models.DataAffiliateAgreement.objects.filter( - study=workspace.study, is_primary=True - ) + primary_qs = models.DataAffiliateAgreement.objects.filter(study=workspace.study, is_primary=True) primary_exists = primary_qs.exists() if primary_exists: diff --git a/primed/cdsa/forms.py b/primed/cdsa/forms.py index 5ec7d116..b529f9da 100644 --- a/primed/cdsa/forms.py +++ b/primed/cdsa/forms.py @@ -22,9 +22,7 @@ class Meta: class SignedAgreementForm(Bootstrap5MediaFormMixin, forms.ModelForm): """Form for a SignedAgreement object.""" - version = forms.ModelChoiceField( - queryset=models.AgreementVersion.objects.filter(major_version__is_valid=True) - ) + version = forms.ModelChoiceField(queryset=models.AgreementVersion.objects.filter(major_version__is_valid=True)) class Meta: model = models.SignedAgreement diff --git a/primed/cdsa/management/commands/cdsa_records.py b/primed/cdsa/management/commands/cdsa_records.py index 78db2704..c6d4c27b 100644 --- a/primed/cdsa/management/commands/cdsa_records.py +++ b/primed/cdsa/management/commands/cdsa_records.py @@ -7,7 +7,6 @@ class Command(BaseCommand): - help = """Management command to generate CDSA records.""" def add_arguments(self, parser): @@ -23,7 +22,6 @@ def _export_table(self, table, filename): f.write(exporter.export()) def handle(self, *args, **options): - # Create directory. outdir = options["outdir"] try: @@ -40,9 +38,7 @@ def handle(self, *args, **options): ) # Studies. - self._export_table( - helpers.get_study_records_table(), os.path.join(outdir, "study_records.tsv") - ) + self._export_table(helpers.get_study_records_table(), os.path.join(outdir, "study_records.tsv")) # CDSA workspaces. self._export_table( diff --git a/primed/cdsa/management/commands/run_cdsa_audit.py b/primed/cdsa/management/commands/run_cdsa_audit.py index 8337f91a..1acd6761 100644 --- a/primed/cdsa/management/commands/run_cdsa_audit.py +++ b/primed/cdsa/management/commands/run_cdsa_audit.py @@ -23,11 +23,7 @@ def _audit_signed_agreements(self): data_access_audit.run_audit() # Construct the url for handling errors. - url = ( - "https://" - + Site.objects.get_current().domain - + reverse("cdsa:audit:signed_agreements:all") - ) + url = "https://" + Site.objects.get_current().domain + reverse("cdsa:audit:signed_agreements:all") self._report_results(data_access_audit, url) self._send_email(data_access_audit, url) @@ -37,11 +33,7 @@ def _audit_workspaces(self): data_access_audit.run_audit() # Construct the url for handling errors. - url = ( - "https://" - + Site.objects.get_current().domain - + reverse("cdsa:audit:workspaces:all") - ) + url = "https://" + Site.objects.get_current().domain + reverse("cdsa:audit:workspaces:all") self._report_results(data_access_audit, url) self._send_email(data_access_audit, url) @@ -55,15 +47,11 @@ def _report_results(self, data_access_audit, resolve_url): # Print results self.stdout.write("* Verified: {}".format(len(data_access_audit.verified))) - self.stdout.write( - "* Needs action: {}".format(len(data_access_audit.needs_action)) - ) + self.stdout.write("* Needs action: {}".format(len(data_access_audit.needs_action))) self.stdout.write("* Errors: {}".format(len(data_access_audit.errors))) if not audit_ok: - self.stdout.write( - self.style.ERROR(f"Please visit {resolve_url} to resolve these issues.") - ) + self.stdout.write(self.style.ERROR(f"Please visit {resolve_url} to resolve these issues.")) def _send_email(self, data_access_audit, url): # Send email if requested and there are problems. diff --git a/primed/cdsa/models.py b/primed/cdsa/models.py index 6c66ed23..e146c426 100644 --- a/primed/cdsa/models.py +++ b/primed/cdsa/models.py @@ -28,9 +28,7 @@ class AgreementMajorVersion(TimeStampedModel, models.Model): validators=[MinValueValidator(1)], unique=True, ) - is_valid = models.BooleanField( - default=True, help_text="Boolean indicator of whether this version is valid." - ) + is_valid = models.BooleanField(default=True, help_text="Boolean indicator of whether this version is valid.") history = HistoricalRecords() @@ -114,9 +112,7 @@ class StatusChoices(models.TextChoices): STATUS = StatusChoices.choices -class SignedAgreement( - TimeStampedModel, SignedAgreementStatusMixin, StatusModel, models.Model -): +class SignedAgreement(TimeStampedModel, SignedAgreementStatusMixin, StatusModel, models.Model): """Model to track verified, signed consortium data sharing agreements.""" MEMBER = "member" @@ -183,10 +179,7 @@ def combined_type(self): combined_type = self.get_type_display() if self.type == self.MEMBER and not self.get_agreement_type().is_primary: combined_type = combined_type + " component" - elif ( - self.type == self.DATA_AFFILIATE - and not self.get_agreement_type().is_primary - ): + elif self.type == self.DATA_AFFILIATE and not self.get_agreement_type().is_primary: combined_type = combined_type + " component" return combined_type @@ -217,9 +210,7 @@ class AgreementTypeModel(models.Model): AGREEMENT_TYPE = None ERROR_TYPE_DOES_NOT_MATCH = "The type of the SignedAgreement does not match the expected type for this model." - signed_agreement = models.OneToOneField( - SignedAgreement, on_delete=models.CASCADE, primary_key=True - ) + signed_agreement = models.OneToOneField(SignedAgreement, on_delete=models.CASCADE, primary_key=True) history = HistoricalRecords(inherit=True) class Meta: @@ -230,10 +221,7 @@ def __str__(self): def clean(self): """Ensure that the SignedAgreement type is correct for the class.""" - if ( - hasattr(self, "signed_agreement") - and self.signed_agreement.type != self.AGREEMENT_TYPE - ): + if hasattr(self, "signed_agreement") and self.signed_agreement.type != self.AGREEMENT_TYPE: raise ValidationError({"signed_agreement": self.ERROR_TYPE_DOES_NOT_MATCH}) def get_agreement_group(self): @@ -323,9 +311,7 @@ class NonDataAffiliateAgreement(TimeStampedModel, AgreementTypeModel, models.Mod AGREEMENT_TYPE = SignedAgreement.NON_DATA_AFFILIATE - affiliation = models.CharField( - max_length=255, help_text="The affiliation of the person signing this CDSA." - ) + affiliation = models.CharField(max_length=255, help_text="The affiliation of the person signing this CDSA.") def get_absolute_url(self): return reverse( @@ -337,9 +323,7 @@ def get_agreement_group(self): return self.affiliation -class CDSAWorkspace( - TimeStampedModel, RequesterModel, DataUseOntologyModel, BaseWorkspaceData -): +class CDSAWorkspace(TimeStampedModel, RequesterModel, DataUseOntologyModel, BaseWorkspaceData): """A model to track additional data about a CDSA workspace.""" # Only one study per workspace. @@ -352,9 +336,7 @@ class CDSAWorkspace( help_text="""Additional data use limitations that cannot be captured by DUO.""", blank=True, ) - acknowledgments = models.TextField( - help_text="Acknowledgments associated with data in this workspace." - ) + acknowledgments = models.TextField(help_text="Acknowledgments associated with data in this workspace.") available_data = models.ManyToManyField( AvailableData, help_text="Data available in this accession.", diff --git a/primed/cdsa/tables.py b/primed/cdsa/tables.py index f39d6988..7d4a3550 100644 --- a/primed/cdsa/tables.py +++ b/primed/cdsa/tables.py @@ -17,14 +17,9 @@ class AgreementVersionTable(tables.Table): - major_version = tables.Column(linkify=True) - full_version = tables.Column( - linkify=True, order_by=("major_version", "minor_version") - ) - major_version__is_valid = BooleanIconColumn( - verbose_name="Valid?", show_false_icon=True - ) + full_version = tables.Column(linkify=True, order_by=("major_version", "minor_version")) + major_version__is_valid = BooleanIconColumn(verbose_name="Valid?", show_false_icon=True) class Meta: model = models.AgreementVersion @@ -37,7 +32,6 @@ class Meta: class SignedAgreementTable(tables.Table): - cc_id = tables.Column(linkify=True) representative__name = tables.Column( linkify=lambda record: record.representative.get_absolute_url(), @@ -213,9 +207,7 @@ def render_signing_group(self, record): class StudyRecordsTable(tables.Table): """Table for a list of studies that have signed the CDSA.""" - signed_agreement__representative__name = tables.Column( - verbose_name="Representative" - ) + 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") @@ -235,9 +227,7 @@ class UserAccessRecordsTable(tables.Table): group__signedagreement__representative__name = tables.Column( verbose_name="Signing representatitve", ) - signing_group = tables.Column( - verbose_name="Signing group", accessor="group__signedagreement", orderable=False - ) + signing_group = tables.Column(verbose_name="Signing group", accessor="group__signedagreement", orderable=False) class Meta: model = GroupAccountMembership @@ -267,12 +257,8 @@ class CDSAWorkspaceRecordsTable(tables.Table): workspace__name = tables.Column() workspace__billing_project = tables.Column() study = tables.Column() - data_use_permission__abbreviation = tables.Column( - verbose_name="Data use permission" - ) - data_use_modifiers = tables.ManyToManyColumn( - transform=lambda x: x.abbreviation, verbose_name="Data use modifiers" - ) + data_use_permission__abbreviation = tables.Column(verbose_name="Data use permission") + data_use_modifiers = tables.ManyToManyColumn(transform=lambda x: x.abbreviation, verbose_name="Data use modifiers") workspace__created = tables.columns.Column(verbose_name="Date created") date_shared = tables.columns.Column(accessor="pk", verbose_name="Date shared") @@ -291,9 +277,7 @@ class Meta: def render_date_shared(self, record): try: - wgs = record.workspace.workspacegroupsharing_set.get( - group__name="PRIMED_ALL" - ) + wgs = record.workspace.workspacegroupsharing_set.get(group__name="PRIMED_ALL") return wgs.created except WorkspaceGroupSharing.DoesNotExist: return "—" diff --git a/primed/cdsa/tests/factories.py b/primed/cdsa/tests/factories.py index 6d7473d9..26625f70 100644 --- a/primed/cdsa/tests/factories.py +++ b/primed/cdsa/tests/factories.py @@ -51,9 +51,7 @@ class SignedAgreementFactory(DjangoModelFactory): anvil_access_group = SubFactory( ManagedGroupFactory, name=LazyAttribute( - lambda o: settings.ANVIL_DATA_ACCESS_GROUP_PREFIX - + "_CDSA_ACCESS_" - + str(o.factory_parent.cc_id) + lambda o: settings.ANVIL_DATA_ACCESS_GROUP_PREFIX + "_CDSA_ACCESS_" + str(o.factory_parent.cc_id) ), ) @@ -62,10 +60,7 @@ class Meta: class MemberAgreementFactory(DjangoModelFactory): - - signed_agreement = SubFactory( - SignedAgreementFactory, type=models.SignedAgreement.MEMBER - ) + signed_agreement = SubFactory(SignedAgreementFactory, type=models.SignedAgreement.MEMBER) study_site = SubFactory(StudySiteFactory) is_primary = True @@ -74,10 +69,7 @@ class Meta: class DataAffiliateAgreementFactory(DjangoModelFactory): - - signed_agreement = SubFactory( - SignedAgreementFactory, type=models.SignedAgreement.DATA_AFFILIATE - ) + signed_agreement = SubFactory(SignedAgreementFactory, type=models.SignedAgreement.DATA_AFFILIATE) study = SubFactory(StudyFactory) is_primary = True anvil_upload_group = SubFactory( @@ -94,10 +86,7 @@ class Meta: class NonDataAffiliateAgreementFactory(DjangoModelFactory): - - signed_agreement = SubFactory( - SignedAgreementFactory, type=models.SignedAgreement.NON_DATA_AFFILIATE - ) + signed_agreement = SubFactory(SignedAgreementFactory, type=models.SignedAgreement.NON_DATA_AFFILIATE) affiliation = Faker("company") class Meta: @@ -105,7 +94,6 @@ class Meta: class CDSAWorkspaceFactory(DjangoModelFactory): - study = SubFactory(StudyFactory) acknowledgments = Faker("paragraph") requested_by = SubFactory(UserFactory) @@ -121,9 +109,7 @@ def authorization_domains(self, create, extracted, **kwargs): return # Create an authorization domain. - auth_domain = ManagedGroupFactory.create( - name="auth_{}".format(self.workspace.name) - ) + auth_domain = ManagedGroupFactory.create(name="auth_{}".format(self.workspace.name)) self.workspace.authorization_domains.add(auth_domain) class Meta: diff --git a/primed/cdsa/tests/test_audit.py b/primed/cdsa/tests/test_audit.py index ef5fc61c..0e7fa8d7 100644 --- a/primed/cdsa/tests/test_audit.py +++ b/primed/cdsa/tests/test_audit.py @@ -22,9 +22,7 @@ class SignedAgreementAuditResultTest(TestCase): def setUp(self): super().setUp() - self.cdsa_group = ManagedGroupFactory.create( - name=settings.ANVIL_CDSA_GROUP_NAME - ) + self.cdsa_group = ManagedGroupFactory.create(name=settings.ANVIL_CDSA_GROUP_NAME) def test_verified_access(self): signed_agreement = factories.SignedAgreementFactory.create() @@ -35,9 +33,7 @@ def test_verified_access(self): self.assertIsNone(instance.action) self.assertEqual( instance.get_action_url(), - reverse( - "cdsa:audit:signed_agreements:resolve", args=[signed_agreement.cc_id] - ), + reverse("cdsa:audit:signed_agreements:resolve", args=[signed_agreement.cc_id]), ) def test_verified_no_access(self): @@ -49,9 +45,7 @@ def test_verified_no_access(self): self.assertIsNone(instance.action) self.assertEqual( instance.get_action_url(), - reverse( - "cdsa:audit:signed_agreements:resolve", args=[signed_agreement.cc_id] - ), + reverse("cdsa:audit:signed_agreements:resolve", args=[signed_agreement.cc_id]), ) def test_grant_access(self): @@ -63,9 +57,7 @@ def test_grant_access(self): self.assertEqual(instance.action, "Grant access") self.assertEqual( instance.get_action_url(), - reverse( - "cdsa:audit:signed_agreements:resolve", args=[signed_agreement.cc_id] - ), + reverse("cdsa:audit:signed_agreements:resolve", args=[signed_agreement.cc_id]), ) def test_remove_access(self): @@ -77,9 +69,7 @@ def test_remove_access(self): self.assertEqual(instance.action, "Remove access") self.assertEqual( instance.get_action_url(), - reverse( - "cdsa:audit:signed_agreements:resolve", args=[signed_agreement.cc_id] - ), + reverse("cdsa:audit:signed_agreements:resolve", args=[signed_agreement.cc_id]), ) def test_error(self): @@ -90,9 +80,7 @@ def test_error(self): ) self.assertEqual( instance.get_action_url(), - reverse( - "cdsa:audit:signed_agreements:resolve", args=[signed_agreement.cc_id] - ), + reverse("cdsa:audit:signed_agreements:resolve", args=[signed_agreement.cc_id]), ) def test_anvil_group_name(self): @@ -119,9 +107,7 @@ class SignedAgreementAccessAuditTest(TestCase): def setUp(self): super().setUp() - self.cdsa_group = ManagedGroupFactory.create( - name=settings.ANVIL_CDSA_GROUP_NAME - ) + self.cdsa_group = ManagedGroupFactory.create(name=settings.ANVIL_CDSA_GROUP_NAME) def test_completed(self): """completed is updated properly.""" @@ -165,9 +151,7 @@ def test_signed_agreement_queryset(self): this_agreement = factories.MemberAgreementFactory.create() factories.MemberAgreementFactory.create() cdsa_audit = signed_agreement_audit.SignedAgreementAccessAudit( - signed_agreement_queryset=models.SignedAgreement.objects.filter( - pk=this_agreement.signed_agreement.pk - ) + signed_agreement_queryset=models.SignedAgreement.objects.filter(pk=this_agreement.signed_agreement.pk) ) cdsa_audit.run_audit() self.assertEqual(len(cdsa_audit.verified), 0) @@ -321,9 +305,7 @@ def test_member_component_has_primary_in_group(self): """Member component agreement, with valid version, with primary with valid version, in CDSA group.""" study_site = StudySiteFactory.create() factories.MemberAgreementFactory.create(study_site=study_site) - this_agreement = factories.MemberAgreementFactory.create( - is_primary=False, study_site=study_site - ) + this_agreement = factories.MemberAgreementFactory.create(is_primary=False, study_site=study_site) # Add the signed agreement access group to the CDSA group. GroupGroupMembershipFactory.create( parent_group=self.cdsa_group, @@ -343,9 +325,7 @@ def test_member_component_has_primary_not_in_group(self): """Member component agreement, with valid version, with primary with valid version, not in CDSA group.""" study_site = StudySiteFactory.create() factories.MemberAgreementFactory.create(study_site=study_site) - this_agreement = factories.MemberAgreementFactory.create( - is_primary=False, study_site=study_site - ) + this_agreement = factories.MemberAgreementFactory.create(is_primary=False, study_site=study_site) # # Add the signed agreement access group to the CDSA group. # GroupGroupMembershipFactory.create( # parent_group=self.cdsa_group, @@ -416,9 +396,7 @@ def test_member_component_has_primary_with_invalid_version_in_group(self): study_site=study_site, signed_agreement__version__major_version__is_valid=False, ) - this_agreement = factories.MemberAgreementFactory.create( - is_primary=False, study_site=study_site - ) + this_agreement = factories.MemberAgreementFactory.create(is_primary=False, study_site=study_site) # Add the signed agreement access group to the CDSA group. GroupGroupMembershipFactory.create( parent_group=self.cdsa_group, @@ -441,9 +419,7 @@ def test_member_component_has_primary_with_invalid_version_not_in_group(self): study_site=study_site, signed_agreement__version__major_version__is_valid=False, ) - this_agreement = factories.MemberAgreementFactory.create( - is_primary=False, study_site=study_site - ) + this_agreement = factories.MemberAgreementFactory.create(is_primary=False, study_site=study_site) # # Add the signed agreement access group to the CDSA group. # GroupGroupMembershipFactory.create( # parent_group=self.cdsa_group, @@ -466,9 +442,7 @@ def test_member_component_has_inactive_primary_in_group(self): study_site=study_site, signed_agreement__status=models.SignedAgreement.StatusChoices.WITHDRAWN, ) - this_agreement = factories.MemberAgreementFactory.create( - is_primary=False, study_site=study_site - ) + this_agreement = factories.MemberAgreementFactory.create(is_primary=False, study_site=study_site) # Add the signed agreement access group to the CDSA group. GroupGroupMembershipFactory.create( parent_group=self.cdsa_group, @@ -491,9 +465,7 @@ def test_member_component_has_inactive_primary_not_in_group(self): study_site=study_site, signed_agreement__status=models.SignedAgreement.StatusChoices.WITHDRAWN, ) - this_agreement = factories.MemberAgreementFactory.create( - is_primary=False, study_site=study_site - ) + this_agreement = factories.MemberAgreementFactory.create(is_primary=False, study_site=study_site) # # Add the signed agreement access group to the CDSA group. # GroupGroupMembershipFactory.create( # parent_group=self.cdsa_group, @@ -512,9 +484,7 @@ def test_member_component_has_inactive_primary_not_in_group(self): def test_member_component_no_primary_in_group(self): """Member component agreement, with valid version, with no primary, in CDSA group.""" study_site = StudySiteFactory.create() - this_agreement = factories.MemberAgreementFactory.create( - is_primary=False, study_site=study_site - ) + this_agreement = factories.MemberAgreementFactory.create(is_primary=False, study_site=study_site) # Add the signed agreement access group to the CDSA group. GroupGroupMembershipFactory.create( parent_group=self.cdsa_group, @@ -533,9 +503,7 @@ def test_member_component_no_primary_in_group(self): def test_member_component_no_primary_not_in_group(self): """Member component agreement, with valid version, with no primary, not in CDSA group.""" study_site = StudySiteFactory.create() - this_agreement = factories.MemberAgreementFactory.create( - is_primary=False, study_site=study_site - ) + this_agreement = factories.MemberAgreementFactory.create(is_primary=False, study_site=study_site) # # Add the signed agreement access group to the CDSA group. # GroupGroupMembershipFactory.create( # parent_group=self.cdsa_group, @@ -813,9 +781,7 @@ def test_data_affiliate_component_has_primary_in_group(self): """Member component agreement, with valid version, with primary with valid version, in CDSA group.""" study = StudyFactory.create() factories.DataAffiliateAgreementFactory.create(study=study) - this_agreement = factories.DataAffiliateAgreementFactory.create( - is_primary=False, study=study - ) + this_agreement = factories.DataAffiliateAgreementFactory.create(is_primary=False, study=study) # Add the signed agreement access group to the CDSA group. GroupGroupMembershipFactory.create( parent_group=self.cdsa_group, @@ -835,9 +801,7 @@ def test_data_affiliate_component_has_primary_not_in_group(self): """Member component agreement, with valid version, with primary with valid version, not in CDSA group.""" study = StudyFactory.create() factories.DataAffiliateAgreementFactory.create(study=study) - this_agreement = factories.DataAffiliateAgreementFactory.create( - is_primary=False, study=study - ) + this_agreement = factories.DataAffiliateAgreementFactory.create(is_primary=False, study=study) # # Add the signed agreement access group to the CDSA group. # GroupGroupMembershipFactory.create( # parent_group=self.cdsa_group, @@ -908,9 +872,7 @@ def test_data_affiliate_component_has_primary_with_invalid_version_in_group(self study=study, signed_agreement__version__major_version__is_valid=False, ) - this_agreement = factories.DataAffiliateAgreementFactory.create( - is_primary=False, study=study - ) + this_agreement = factories.DataAffiliateAgreementFactory.create(is_primary=False, study=study) # Add the signed agreement access group to the CDSA group. GroupGroupMembershipFactory.create( parent_group=self.cdsa_group, @@ -935,9 +897,7 @@ def test_data_affiliate_component_has_primary_with_invalid_version_not_in_group( study=study, signed_agreement__version__major_version__is_valid=False, ) - this_agreement = factories.DataAffiliateAgreementFactory.create( - is_primary=False, study=study - ) + this_agreement = factories.DataAffiliateAgreementFactory.create(is_primary=False, study=study) # # Add the signed agreement access group to the CDSA group. # GroupGroupMembershipFactory.create( # parent_group=self.cdsa_group, @@ -960,9 +920,7 @@ def test_data_affiliate_component_has_inactive_primary_in_group(self): study=study, signed_agreement__status=models.SignedAgreement.StatusChoices.WITHDRAWN, ) - this_agreement = factories.DataAffiliateAgreementFactory.create( - is_primary=False, study=study - ) + this_agreement = factories.DataAffiliateAgreementFactory.create(is_primary=False, study=study) # Add the signed agreement access group to the CDSA group. GroupGroupMembershipFactory.create( parent_group=self.cdsa_group, @@ -985,9 +943,7 @@ def test_data_affiliate_component_has_inactive_primary_not_in_group(self): study=study, signed_agreement__status=models.SignedAgreement.StatusChoices.WITHDRAWN, ) - this_agreement = factories.DataAffiliateAgreementFactory.create( - is_primary=False, study=study - ) + this_agreement = factories.DataAffiliateAgreementFactory.create(is_primary=False, study=study) # # Add the signed agreement access group to the CDSA group. # GroupGroupMembershipFactory.create( # parent_group=self.cdsa_group, @@ -1006,9 +962,7 @@ def test_data_affiliate_component_has_inactive_primary_not_in_group(self): def test_data_affiliate_component_no_primary_in_group(self): """Member component agreement, with valid version, with no primary, in CDSA group.""" study = StudyFactory.create() - this_agreement = factories.DataAffiliateAgreementFactory.create( - is_primary=False, study=study - ) + this_agreement = factories.DataAffiliateAgreementFactory.create(is_primary=False, study=study) # Add the signed agreement access group to the CDSA group. GroupGroupMembershipFactory.create( parent_group=self.cdsa_group, @@ -1027,9 +981,7 @@ def test_data_affiliate_component_no_primary_in_group(self): def test_data_affiliate_component_no_primary_not_in_group(self): """Member component agreement, with valid version, with no primary, not in CDSA group.""" study = StudyFactory.create() - this_agreement = factories.DataAffiliateAgreementFactory.create( - is_primary=False, study=study - ) + this_agreement = factories.DataAffiliateAgreementFactory.create(is_primary=False, study=study) # # Add the signed agreement access group to the CDSA group. # GroupGroupMembershipFactory.create( # parent_group=self.cdsa_group, @@ -1310,9 +1262,7 @@ class SignedAgreementAccessAuditTableTest(TestCase): def test_no_rows(self): """Table works with no rows.""" table = signed_agreement_audit.SignedAgreementAccessAuditTable([]) - self.assertIsInstance( - table, signed_agreement_audit.SignedAgreementAccessAuditTable - ) + self.assertIsInstance(table, signed_agreement_audit.SignedAgreementAccessAuditTable) self.assertEqual(len(table.rows), 0) def test_one_row(self): @@ -1329,9 +1279,7 @@ def test_one_row(self): } ] table = signed_agreement_audit.SignedAgreementAccessAuditTable(data) - self.assertIsInstance( - table, signed_agreement_audit.SignedAgreementAccessAuditTable - ) + self.assertIsInstance(table, signed_agreement_audit.SignedAgreementAccessAuditTable) self.assertEqual(len(table.rows), 1) self.assertIn( str(member_agreement.signed_agreement.cc_id), @@ -1362,9 +1310,7 @@ def test_two_rows(self): }, ] table = signed_agreement_audit.SignedAgreementAccessAuditTable(data) - self.assertIsInstance( - table, signed_agreement_audit.SignedAgreementAccessAuditTable - ) + self.assertIsInstance(table, signed_agreement_audit.SignedAgreementAccessAuditTable) self.assertEqual(len(table.rows), 2) self.assertIn( str(signed_agreement_1.signed_agreement.cc_id), @@ -1383,16 +1329,12 @@ class WorkspaceAuditResultTest(TestCase): def setUp(self): super().setUp() - self.cdsa_group = ManagedGroupFactory.create( - name=settings.ANVIL_CDSA_GROUP_NAME - ) + self.cdsa_group = ManagedGroupFactory.create(name=settings.ANVIL_CDSA_GROUP_NAME) self.study = StudyFactory.create() def test_verified_access(self): workspace = factories.CDSAWorkspaceFactory.create(study=self.study) - data_affiliate_agreement = factories.DataAffiliateAgreementFactory.create( - study=self.study - ) + data_affiliate_agreement = factories.DataAffiliateAgreementFactory.create(study=self.study) instance = workspace_audit.VerifiedAccess( workspace=workspace, data_affiliate_agreement=data_affiliate_agreement, @@ -1411,9 +1353,7 @@ def test_verified_access(self): def test_verified_no_access(self): workspace = factories.CDSAWorkspaceFactory.create(study=self.study) - data_affiliate_agreement = factories.DataAffiliateAgreementFactory.create( - study=self.study - ) + data_affiliate_agreement = factories.DataAffiliateAgreementFactory.create(study=self.study) instance = workspace_audit.VerifiedNoAccess( workspace=workspace, data_affiliate_agreement=data_affiliate_agreement, @@ -1432,9 +1372,7 @@ def test_verified_no_access(self): def test_grant_access(self): workspace = factories.CDSAWorkspaceFactory.create(study=self.study) - data_affiliate_agreement = factories.DataAffiliateAgreementFactory.create( - study=self.study - ) + data_affiliate_agreement = factories.DataAffiliateAgreementFactory.create(study=self.study) instance = workspace_audit.GrantAccess( workspace=workspace, data_affiliate_agreement=data_affiliate_agreement, @@ -1453,9 +1391,7 @@ def test_grant_access(self): def test_remove_access(self): workspace = factories.CDSAWorkspaceFactory.create(study=self.study) - data_affiliate_agreement = factories.DataAffiliateAgreementFactory.create( - study=self.study - ) + data_affiliate_agreement = factories.DataAffiliateAgreementFactory.create(study=self.study) instance = workspace_audit.RemoveAccess( workspace=workspace, data_affiliate_agreement=data_affiliate_agreement, @@ -1474,9 +1410,7 @@ def test_remove_access(self): def test_error(self): workspace = factories.CDSAWorkspaceFactory.create(study=self.study) - data_affiliate_agreement = factories.DataAffiliateAgreementFactory.create( - study=self.study - ) + data_affiliate_agreement = factories.DataAffiliateAgreementFactory.create(study=self.study) instance = workspace_audit.OtherError( workspace=workspace, data_affiliate_agreement=data_affiliate_agreement, @@ -1512,9 +1446,7 @@ def test_error_no_data_affiliate_agreement(self): def test_anvil_group_name(self): workspace = factories.CDSAWorkspaceFactory.create(study=self.study) - data_affiliate_agreement = factories.DataAffiliateAgreementFactory.create( - study=self.study - ) + data_affiliate_agreement = factories.DataAffiliateAgreementFactory.create(study=self.study) instance = workspace_audit.OtherError( workspace=workspace, data_affiliate_agreement=data_affiliate_agreement, @@ -1526,9 +1458,7 @@ def test_anvil_group_name(self): def test_anvil_group_name_setting(self): group = ManagedGroupFactory.create(name="FOO") workspace = factories.CDSAWorkspaceFactory.create(study=self.study) - data_affiliate_agreement = factories.DataAffiliateAgreementFactory.create( - study=self.study - ) + data_affiliate_agreement = factories.DataAffiliateAgreementFactory.create(study=self.study) instance = workspace_audit.OtherError( workspace=workspace, data_affiliate_agreement=data_affiliate_agreement, @@ -1542,9 +1472,7 @@ class WorkspaceAccessAuditTest(TestCase): def setUp(self): super().setUp() - self.cdsa_group = ManagedGroupFactory.create( - name=settings.ANVIL_CDSA_GROUP_NAME - ) + self.cdsa_group = ManagedGroupFactory.create(name=settings.ANVIL_CDSA_GROUP_NAME) def test_completed(self): """completed is updated properly.""" @@ -1558,9 +1486,7 @@ def test_cdsa_workspace_queryset(self): cdsa_workspace = factories.CDSAWorkspaceFactory.create() factories.CDSAWorkspaceFactory.create() cdsa_audit = workspace_audit.WorkspaceAccessAudit( - cdsa_workspace_queryset=models.CDSAWorkspace.objects.filter( - pk=cdsa_workspace.workspace.pk - ) + cdsa_workspace_queryset=models.CDSAWorkspace.objects.filter(pk=cdsa_workspace.workspace.pk) ) cdsa_audit.run_audit() self.assertEqual(len(cdsa_audit.verified), 1) @@ -1575,9 +1501,7 @@ def test_cdsa_workspace_queryset(self): def test_cdsa_workspace_queryset_wrong_class(self): """Audit raises error if dbgap_application_queryset has the wrong model class.""" with self.assertRaises(ValueError) as e: - workspace_audit.WorkspaceAccessAudit( - cdsa_workspace_queryset=models.SignedAgreement.objects.all() - ) + workspace_audit.WorkspaceAccessAudit(cdsa_workspace_queryset=models.SignedAgreement.objects.all()) self.assertEqual( str(e.exception), "cdsa_workspace_queryset must be a queryset of CDSAWorkspace objects.", @@ -1596,9 +1520,7 @@ def test_cdsa_workspace_queryset_not_queryset(self): def test_primary_in_auth_domain(self): study = StudyFactory.create() workspace = factories.CDSAWorkspaceFactory.create(study=study) - data_affiliate_agreement = factories.DataAffiliateAgreementFactory.create( - study=study - ) + data_affiliate_agreement = factories.DataAffiliateAgreementFactory.create(study=study) # Add the CDSA group to the auth domain. GroupGroupMembershipFactory.create( parent_group=workspace.workspace.authorization_domains.first(), @@ -1618,9 +1540,7 @@ def test_primary_in_auth_domain(self): def test_primary_not_in_auth_domain(self): study = StudyFactory.create() workspace = factories.CDSAWorkspaceFactory.create(study=study) - data_affiliate_agreement = factories.DataAffiliateAgreementFactory.create( - study=study - ) + data_affiliate_agreement = factories.DataAffiliateAgreementFactory.create(study=study) # Do not add the CDSA group to the auth domain. # GroupGroupMembershipFactory.create( # parent_group=workspace.workspace.authorization_domains.first(), @@ -1804,9 +1724,7 @@ def test_component_agreement_in_auth_domain(self): def test_two_valid_primary_agreements_in_auth_domain(self): study = StudyFactory.create() workspace = factories.CDSAWorkspaceFactory.create(study=study) - factories.DataAffiliateAgreementFactory.create( - study=study, signed_agreement__version__major_version__version=1 - ) + factories.DataAffiliateAgreementFactory.create(study=study, signed_agreement__version__major_version__version=1) data_affiliate_agreement = factories.DataAffiliateAgreementFactory.create( study=study, signed_agreement__version__major_version__version=2 ) @@ -1859,9 +1777,7 @@ def test_two_valid_primary_agreements_same_major_version_in_auth_domain(self): def test_two_valid_primary_agreements_not_in_auth_domain(self): study = StudyFactory.create() workspace = factories.CDSAWorkspaceFactory.create(study=study) - factories.DataAffiliateAgreementFactory.create( - study=study, signed_agreement__version__major_version__version=1 - ) + factories.DataAffiliateAgreementFactory.create(study=study, signed_agreement__version__major_version__version=1) data_affiliate_agreement = factories.DataAffiliateAgreementFactory.create( study=study, signed_agreement__version__major_version__version=2 ) @@ -2064,9 +1980,7 @@ def test_two_workspaces(self): study = StudyFactory.create() workspace_1 = factories.CDSAWorkspaceFactory.create(study=study) workspace_2 = factories.CDSAWorkspaceFactory.create(study=study) - data_affiliate_agreement = factories.DataAffiliateAgreementFactory.create( - study=study - ) + data_affiliate_agreement = factories.DataAffiliateAgreementFactory.create(study=study) # Add the CDSA group to the auth domain. GroupGroupMembershipFactory.create( parent_group=workspace_1.workspace.authorization_domains.first(), diff --git a/primed/cdsa/tests/test_commands.py b/primed/cdsa/tests/test_commands.py index fbef817c..ad4ccf64 100644 --- a/primed/cdsa/tests/test_commands.py +++ b/primed/cdsa/tests/test_commands.py @@ -95,9 +95,7 @@ def test_directory_exists(self): os.mkdir(self.outdir) out = StringIO() with self.assertRaises(CommandError) as e: - call_command( - "cdsa_records", "--outdir", self.outdir, "--no-color", stdout=out - ) + call_command("cdsa_records", "--outdir", self.outdir, "--no-color", stdout=out) self.assertIn("already exists", str(e.exception)) @@ -106,26 +104,18 @@ class RunCDSAAuditTest(TestCase): def setUp(self): super().setUp() - self.cdsa_group = ManagedGroupFactory.create( - name=settings.ANVIL_CDSA_GROUP_NAME - ) + self.cdsa_group = ManagedGroupFactory.create(name=settings.ANVIL_CDSA_GROUP_NAME) def test_command_output_no_records(self): """Test command output.""" out = StringIO() call_command("run_cdsa_audit", "--no-color", stdout=out) expected_output = ( - "Running SignedAgreement access audit... ok!\n" - "* Verified: 0\n" - "* Needs action: 0\n" - "* Errors: 0\n" + "Running SignedAgreement access audit... ok!\n" "* Verified: 0\n" "* Needs action: 0\n" "* Errors: 0\n" ) self.assertIn(expected_output, out.getvalue()) expected_output = ( - "Running CDSAWorkspace access audit... ok!\n" - "* Verified: 0\n" - "* Needs action: 0\n" - "* Errors: 0\n" + "Running CDSAWorkspace access audit... ok!\n" "* Verified: 0\n" "* Needs action: 0\n" "* Errors: 0\n" ) self.assertIn(expected_output, out.getvalue()) # Zero messages have been sent by default. @@ -137,17 +127,11 @@ def test_command_run_audit_one_agreement_verified(self): out = StringIO() call_command("run_cdsa_audit", "--no-color", stdout=out) expected_output = ( - "Running SignedAgreement access audit... ok!\n" - "* Verified: 1\n" - "* Needs action: 0\n" - "* Errors: 0\n" + "Running SignedAgreement access audit... ok!\n" "* Verified: 1\n" "* Needs action: 0\n" "* Errors: 0\n" ) self.assertIn(expected_output, out.getvalue()) expected_output = ( - "Running CDSAWorkspace access audit... ok!\n" - "* Verified: 0\n" - "* Needs action: 0\n" - "* Errors: 0\n" + "Running CDSAWorkspace access audit... ok!\n" "* Verified: 0\n" "* Needs action: 0\n" "* Errors: 0\n" ) self.assertIn(expected_output, out.getvalue()) # Zero messages have been sent by default. @@ -195,9 +179,7 @@ def test_command_run_audit_one_agreement_verified_email(self): """No email is sent when there are no errors.""" factories.MemberAgreementFactory.create(is_primary=False) out = StringIO() - call_command( - "run_cdsa_audit", "--no-color", email="test@example.com", stdout=out - ) + call_command("run_cdsa_audit", "--no-color", email="test@example.com", stdout=out) self.assertIn("Running CDSAWorkspace access audit... ok!", out.getvalue()) self.assertIn("Running SignedAgreement access audit... ok!", out.getvalue()) # Zero messages have been sent by default. @@ -207,9 +189,7 @@ def test_command_run_audit_one_agreement_needs_action_email(self): """Email is sent for one needs_action instance.""" factories.MemberAgreementFactory.create() out = StringIO() - call_command( - "run_cdsa_audit", "--no-color", email="test@example.com", stdout=out - ) + call_command("run_cdsa_audit", "--no-color", email="test@example.com", stdout=out) expected_output = ( "Running SignedAgreement access audit... problems found.\n" "* Verified: 0\n" @@ -223,9 +203,7 @@ def test_command_run_audit_one_agreement_needs_action_email(self): email = mail.outbox[0] self.assertEqual(email.to, ["test@example.com"]) self.assertEqual(email.subject, "CDSA SignedAgreementAccessAudit errors") - self.assertIn( - reverse("cdsa:audit:signed_agreements:all"), email.alternatives[0][0] - ) + self.assertIn(reverse("cdsa:audit:signed_agreements:all"), email.alternatives[0][0]) def test_command_run_audit_one_agreement_error_email(self): """Test command output with one error instance.""" @@ -235,9 +213,7 @@ def test_command_run_audit_one_agreement_error_email(self): child_group=agreement.signed_agreement.anvil_access_group, ) out = StringIO() - call_command( - "run_cdsa_audit", "--no-color", email="test@example.com", stdout=out - ) + call_command("run_cdsa_audit", "--no-color", email="test@example.com", stdout=out) expected_output = ( "Running SignedAgreement access audit... problems found.\n" "* Verified: 0\n" @@ -252,9 +228,7 @@ def test_command_run_audit_one_agreement_error_email(self): email = mail.outbox[0] self.assertEqual(email.to, ["test@example.com"]) self.assertEqual(email.subject, "CDSA SignedAgreementAccessAudit errors") - self.assertIn( - reverse("cdsa:audit:signed_agreements:all"), email.alternatives[0][0] - ) + self.assertIn(reverse("cdsa:audit:signed_agreements:all"), email.alternatives[0][0]) def test_command_run_audit_one_workspace_verified(self): """Test command output with one verified instance.""" @@ -262,17 +236,11 @@ def test_command_run_audit_one_workspace_verified(self): out = StringIO() call_command("run_cdsa_audit", "--no-color", stdout=out) expected_output = ( - "Running SignedAgreement access audit... ok!\n" - "* Verified: 0\n" - "* Needs action: 0\n" - "* Errors: 0\n" + "Running SignedAgreement access audit... ok!\n" "* Verified: 0\n" "* Needs action: 0\n" "* Errors: 0\n" ) self.assertIn(expected_output, out.getvalue()) expected_output = ( - "Running CDSAWorkspace access audit... ok!\n" - "* Verified: 1\n" - "* Needs action: 0\n" - "* Errors: 0\n" + "Running CDSAWorkspace access audit... ok!\n" "* Verified: 1\n" "* Needs action: 0\n" "* Errors: 0\n" ) self.assertIn(expected_output, out.getvalue()) # Zero messages have been sent by default. @@ -325,9 +293,7 @@ def test_command_run_audit_one_workspace_verified_email(self): """No email is sent when there are no errors.""" factories.CDSAWorkspaceFactory.create() out = StringIO() - call_command( - "run_cdsa_audit", "--no-color", email="test@example.com", stdout=out - ) + call_command("run_cdsa_audit", "--no-color", email="test@example.com", stdout=out) self.assertIn("Running CDSAWorkspace access audit... ok!", out.getvalue()) self.assertIn("Running SignedAgreement access audit... ok!", out.getvalue()) # Zero messages have been sent by default. @@ -342,9 +308,7 @@ def test_command_run_audit_one_workspace_needs_action_email(self): ) factories.CDSAWorkspaceFactory.create(study=agreement.study) out = StringIO() - call_command( - "run_cdsa_audit", "--no-color", email="test@example.com", stdout=out - ) + call_command("run_cdsa_audit", "--no-color", email="test@example.com", stdout=out) expected_output = ( "Running CDSAWorkspace access audit... problems found.\n" "* Verified: 0\n" @@ -368,9 +332,7 @@ def test_command_run_audit_one_workspace_error_email(self): child_group=self.cdsa_group, ) out = StringIO() - call_command( - "run_cdsa_audit", "--no-color", email="test@example.com", stdout=out - ) + call_command("run_cdsa_audit", "--no-color", email="test@example.com", stdout=out) expected_output = ( "Running CDSAWorkspace access audit... problems found.\n" "* Verified: 0\n" @@ -413,9 +375,7 @@ def test_signed_agreement_and_workspace_needs_action_email(self): agreement = factories.DataAffiliateAgreementFactory.create() factories.CDSAWorkspaceFactory.create(study=agreement.study) out = StringIO() - call_command( - "run_cdsa_audit", "--no-color", email="test@example.com", stdout=out - ) + call_command("run_cdsa_audit", "--no-color", email="test@example.com", stdout=out) expected_output = ( "Running CDSAWorkspace access audit... problems found.\n" "* Verified: 0\n" @@ -435,9 +395,7 @@ def test_signed_agreement_and_workspace_needs_action_email(self): email = mail.outbox[0] self.assertEqual(email.to, ["test@example.com"]) self.assertEqual(email.subject, "CDSA SignedAgreementAccessAudit errors") - self.assertIn( - reverse("cdsa:audit:signed_agreements:all"), email.alternatives[0][0] - ) + self.assertIn(reverse("cdsa:audit:signed_agreements:all"), email.alternatives[0][0]) email = mail.outbox[1] self.assertEqual(email.to, ["test@example.com"]) self.assertEqual(email.subject, "CDSA WorkspaceAccessAudit errors") @@ -450,9 +408,7 @@ def test_different_domain(self): factories.MemberAgreementFactory.create() with self.settings(SITE_ID=site.id): out = StringIO() - call_command( - "run_cdsa_audit", "--no-color", email="test@example.com", stdout=out - ) + call_command("run_cdsa_audit", "--no-color", email="test@example.com", stdout=out) self.assertIn( "Running SignedAgreement access audit... problems found.", out.getvalue(), diff --git a/primed/cdsa/tests/test_forms.py b/primed/cdsa/tests/test_forms.py index 1dcea0af..5b01b31e 100644 --- a/primed/cdsa/tests/test_forms.py +++ b/primed/cdsa/tests/test_forms.py @@ -244,9 +244,7 @@ class MemberAgreementFormTest(TestCase): def setUp(self): """Create related objects for use in the form.""" - self.signed_agreement = factories.SignedAgreementFactory.create( - type=models.SignedAgreement.MEMBER - ) + self.signed_agreement = factories.SignedAgreementFactory.create(type=models.SignedAgreement.MEMBER) self.study_site = StudySiteFactory.create() def test_valid(self): @@ -317,9 +315,7 @@ def test_invalid_signed_agreement_already_has_member_agreement(self): def test_invalid_signed_agreement_wrong_type(self): """Form is invalid when the signed_agreement has the wrong type.""" - obj = factories.SignedAgreementFactory.create( - type=models.SignedAgreement.DATA_AFFILIATE - ) + obj = factories.SignedAgreementFactory.create(type=models.SignedAgreement.DATA_AFFILIATE) form_data = { "signed_agreement": obj, "is_primary": True, @@ -339,9 +335,7 @@ class DataAffiliateAgreementFormTest(TestCase): def setUp(self): """Create related objects for use in the form.""" - self.signed_agreement = factories.SignedAgreementFactory.create( - type=models.SignedAgreement.DATA_AFFILIATE - ) + self.signed_agreement = factories.SignedAgreementFactory.create(type=models.SignedAgreement.DATA_AFFILIATE) self.study = StudyFactory.create() def test_valid(self): @@ -412,9 +406,7 @@ def test_invalid_signed_agreement_already_has_agreement_type(self): def test_invalid_signed_agreement_wrong_type(self): """Form is invalid when the signed_agreement has the wrong type.""" - obj = factories.SignedAgreementFactory.create( - type=models.SignedAgreement.MEMBER - ) + obj = factories.SignedAgreementFactory.create(type=models.SignedAgreement.MEMBER) form_data = { "signed_agreement": obj, "is_primary": True, @@ -449,9 +441,7 @@ def test_invalid_component_with_additional_limitations(self): self.assertFalse(form.is_valid()) self.assertIn("additional_limitations", form.errors) self.assertEqual(len(form.errors["additional_limitations"]), 1) - self.assertIn( - "only allowed for primary", form.errors["additional_limitations"][0] - ) + self.assertIn("only allowed for primary", form.errors["additional_limitations"][0]) def test_valid_primary_with_requires_study_review_true(self): """Form is valid with necessary input.""" @@ -476,9 +466,7 @@ def test_invalid_component_with_requires_study_review_true(self): self.assertFalse(form.is_valid()) self.assertIn("requires_study_review", form.errors) self.assertEqual(len(form.errors["requires_study_review"]), 1) - self.assertIn( - "can only be True for primary", form.errors["requires_study_review"][0] - ) + self.assertIn("can only be True for primary", form.errors["requires_study_review"][0]) class NonDataAffiliateAgreementFormTest(TestCase): @@ -488,9 +476,7 @@ class NonDataAffiliateAgreementFormTest(TestCase): def setUp(self): """Create related objects for use in the form.""" - self.signed_agreement = factories.SignedAgreementFactory.create( - type=models.SignedAgreement.NON_DATA_AFFILIATE - ) + self.signed_agreement = factories.SignedAgreementFactory.create(type=models.SignedAgreement.NON_DATA_AFFILIATE) def test_valid(self): """Form is valid with necessary input.""" @@ -542,9 +528,7 @@ def test_invalid_signed_agreement_already_has_agreement_type(self): def test_invalid_signed_agreement_wrong_type(self): """Form is invalid when the signed_agreement has the wrong type.""" - obj = factories.SignedAgreementFactory.create( - type=models.SignedAgreement.MEMBER - ) + obj = factories.SignedAgreementFactory.create(type=models.SignedAgreement.MEMBER) form_data = { "signed_agreement": obj, "affiliation": "Foo Bar", diff --git a/primed/cdsa/tests/test_migrations.py b/primed/cdsa/tests/test_migrations.py index 7a609516..9446ac25 100644 --- a/primed/cdsa/tests/test_migrations.py +++ b/primed/cdsa/tests/test_migrations.py @@ -130,7 +130,7 @@ def prepare(self): type="member", version=agreement_version, anvil_access_group=ManagedGroup.objects.create(name="testaccess1", email="testaccess1@example.com"), - is_primary=True + is_primary=True, ) self.member_agreement_1 = MemberAgreement.objects.create( signed_agreement=tmp, @@ -144,7 +144,7 @@ def prepare(self): type="member", version=agreement_version, anvil_access_group=ManagedGroup.objects.create(name="testaccess2", email="testaccess2@example.com"), - is_primary=False + is_primary=False, ) self.member_agreement_2 = MemberAgreement.objects.create( signed_agreement=tmp, @@ -158,7 +158,7 @@ def prepare(self): type="data_affiliate", version=agreement_version, anvil_access_group=ManagedGroup.objects.create(name="testaccess3", email="testaccess3@example.com"), - is_primary=True + is_primary=True, ) self.data_affiliate_agreement_1 = DataAffiliateAgreement.objects.create( signed_agreement=tmp, @@ -173,7 +173,7 @@ def prepare(self): type="data_affiliate", version=agreement_version, anvil_access_group=ManagedGroup.objects.create(name="testaccess4", email="testaccess4@example.com"), - is_primary=False + is_primary=False, ) self.data_affiliate_agreement_2 = DataAffiliateAgreement.objects.create( signed_agreement=tmp, @@ -188,14 +188,14 @@ def prepare(self): type="non_data_affiliate", version=agreement_version, anvil_access_group=ManagedGroup.objects.create(name="testaccess5", email="testaccess5@example.com"), - is_primary=False + is_primary=False, ) self.non_data_affiliate_agreement = NonDataAffiliateAgreement.objects.create( signed_agreement=tmp, ) def test_is_primary_correctly_populated(self): -# import ipdb; ipdb.set_trace() + # import ipdb; ipdb.set_trace() MemberAgreement = self.new_state.apps.get_model("cdsa", "MemberAgreement") DataAffiliateAgreement = self.new_state.apps.get_model("cdsa", "DataAffiliateAgreement") NonDataAffiliateAgreement = self.new_state.apps.get_model("cdsa", "NonDataAffiliateAgreement") diff --git a/primed/cdsa/tests/test_models.py b/primed/cdsa/tests/test_models.py index eb9fbe66..d6b98d3c 100644 --- a/primed/cdsa/tests/test_models.py +++ b/primed/cdsa/tests/test_models.py @@ -53,9 +53,7 @@ def test_version_zero(self): self.assertEqual(len(e.exception.message_dict), 1) self.assertIn("version", e.exception.message_dict) self.assertEqual(len(e.exception.message_dict["version"]), 1) - self.assertIn( - "greater than or equal to", e.exception.message_dict["version"][0] - ) + self.assertIn("greater than or equal to", e.exception.message_dict["version"][0]) def test_version_negative(self): """ValidationError raised when version is negative.""" @@ -65,9 +63,7 @@ def test_version_negative(self): self.assertEqual(len(e.exception.message_dict), 1) self.assertIn("version", e.exception.message_dict) self.assertEqual(len(e.exception.message_dict["version"]), 1) - self.assertIn( - "greater than or equal to", e.exception.message_dict["version"][0] - ) + self.assertIn("greater than or equal to", e.exception.message_dict["version"][0]) def test_str(self): """__str__ method works as expected.""" @@ -85,20 +81,14 @@ class AgreementVersionTest(TestCase): def test_model_saving(self): major_version = factories.AgreementMajorVersionFactory.create() - instance = models.AgreementVersion( - major_version=major_version, minor_version=0, date_approved=datetime.today() - ) + instance = models.AgreementVersion(major_version=major_version, minor_version=0, date_approved=datetime.today()) instance.save() self.assertIsInstance(instance, models.AgreementVersion) def test_unique(self): major_version = factories.AgreementMajorVersionFactory.create() - factories.AgreementVersionFactory.create( - major_version=major_version, minor_version=0 - ) - instance = factories.AgreementVersionFactory.build( - major_version=major_version, minor_version=0 - ) + factories.AgreementVersionFactory.create(major_version=major_version, minor_version=0) + instance = factories.AgreementVersionFactory.build(major_version=major_version, minor_version=0) with self.assertRaisesMessage(ValidationError, "already exists"): instance.full_clean() with self.assertRaises(IntegrityError): @@ -107,50 +97,36 @@ def test_unique(self): def test_minor_version_zero(self): """full_clean raises no exception when minor_version is zero.""" major_version = factories.AgreementMajorVersionFactory.create() - instance = factories.AgreementVersionFactory.build( - major_version=major_version, minor_version=0 - ) + instance = factories.AgreementVersionFactory.build(major_version=major_version, minor_version=0) instance.full_clean() def test_minor_version_negative(self): """ValidationError raised when minor_version is negative.""" major_version = factories.AgreementMajorVersionFactory.create() - instance = factories.AgreementVersionFactory.build( - major_version=major_version, minor_version=-1 - ) + instance = factories.AgreementVersionFactory.build(major_version=major_version, minor_version=-1) with self.assertRaises(ValidationError) as e: instance.full_clean() self.assertEqual(len(e.exception.message_dict), 1) self.assertIn("minor_version", e.exception.message_dict) self.assertEqual(len(e.exception.message_dict["minor_version"]), 1) - self.assertIn( - "greater than or equal to", e.exception.message_dict["minor_version"][0] - ) + self.assertIn("greater than or equal to", e.exception.message_dict["minor_version"][0]) def test_full_version(self): """full_version property works as expected.""" self.assertEqual( - factories.AgreementVersionFactory( - major_version__version=1, minor_version=0 - ).full_version, + factories.AgreementVersionFactory(major_version__version=1, minor_version=0).full_version, "v1.0", ) self.assertEqual( - factories.AgreementVersionFactory( - major_version__version=1, minor_version=5 - ).full_version, + factories.AgreementVersionFactory(major_version__version=1, minor_version=5).full_version, "v1.5", ) self.assertEqual( - factories.AgreementVersionFactory( - major_version__version=1, minor_version=10 - ).full_version, + factories.AgreementVersionFactory(major_version__version=1, minor_version=10).full_version, "v1.10", ) self.assertEqual( - factories.AgreementVersionFactory( - major_version__version=2, minor_version=3 - ).full_version, + factories.AgreementVersionFactory(major_version__version=2, minor_version=3).full_version, "v2.3", ) @@ -196,31 +172,19 @@ def test_str_method(self): def test_get_absolute_url(self): """get_absolute_url method works correctly.""" instance = factories.MemberAgreementFactory.create() - self.assertEqual( - instance.signed_agreement.get_absolute_url(), instance.get_absolute_url() - ) + self.assertEqual(instance.signed_agreement.get_absolute_url(), instance.get_absolute_url()) instance = factories.DataAffiliateAgreementFactory.create() - self.assertEqual( - instance.signed_agreement.get_absolute_url(), instance.get_absolute_url() - ) + self.assertEqual(instance.signed_agreement.get_absolute_url(), instance.get_absolute_url()) instance = factories.NonDataAffiliateAgreementFactory.create() - self.assertEqual( - instance.signed_agreement.get_absolute_url(), instance.get_absolute_url() - ) + self.assertEqual(instance.signed_agreement.get_absolute_url(), instance.get_absolute_url()) def test_member_choices(self): """Can create instances with all of the member choices.""" - instance = factories.SignedAgreementFactory.create( - type=models.SignedAgreement.MEMBER - ) + instance = factories.SignedAgreementFactory.create(type=models.SignedAgreement.MEMBER) self.assertEqual(instance.type, models.SignedAgreement.MEMBER) - instance = factories.SignedAgreementFactory.create( - type=models.SignedAgreement.DATA_AFFILIATE - ) + instance = factories.SignedAgreementFactory.create(type=models.SignedAgreement.DATA_AFFILIATE) self.assertEqual(instance.type, models.SignedAgreement.DATA_AFFILIATE) - instance = factories.SignedAgreementFactory.create( - type=models.SignedAgreement.NON_DATA_AFFILIATE - ) + instance = factories.SignedAgreementFactory.create(type=models.SignedAgreement.NON_DATA_AFFILIATE) self.assertEqual(instance.type, models.SignedAgreement.NON_DATA_AFFILIATE) def test_unique_cc_id(self): @@ -293,19 +257,13 @@ def test_status_field(self): self.assertEqual(instance.status, instance.StatusChoices.ACTIVE) instance.full_clean() # other choices - instance = factories.SignedAgreementFactory.create( - status=models.SignedAgreement.StatusChoices.WITHDRAWN - ) + instance = factories.SignedAgreementFactory.create(status=models.SignedAgreement.StatusChoices.WITHDRAWN) self.assertEqual(instance.status, instance.StatusChoices.WITHDRAWN) instance.full_clean() - instance = factories.SignedAgreementFactory.create( - status=models.SignedAgreement.StatusChoices.LAPSED - ) + instance = factories.SignedAgreementFactory.create(status=models.SignedAgreement.StatusChoices.LAPSED) self.assertEqual(instance.status, instance.StatusChoices.LAPSED) instance.full_clean() - instance = factories.SignedAgreementFactory.create( - status=models.SignedAgreement.StatusChoices.REPLACED - ) + instance = factories.SignedAgreementFactory.create(status=models.SignedAgreement.StatusChoices.REPLACED) self.assertEqual(instance.status, instance.StatusChoices.REPLACED) instance.full_clean() @@ -352,9 +310,7 @@ def test_is_in_cdsa_group(self): cdsa_group = ManagedGroupFactory.create(name="TEST_PRIMED_CDSA") self.assertFalse(obj.is_in_cdsa_group()) # Add agreement and check again, - GroupGroupMembershipFactory.create( - parent_group=cdsa_group, child_group=obj.anvil_access_group - ) + GroupGroupMembershipFactory.create(parent_group=cdsa_group, child_group=obj.anvil_access_group) self.assertTrue(obj.is_in_cdsa_group()) @override_settings(ANVIL_CDSA_GROUP_NAME="FOO") @@ -368,9 +324,7 @@ def test_is_in_cdsa_group_different_group_name(self): cdsa_group = ManagedGroupFactory.create(name="FOO") self.assertFalse(obj.is_in_cdsa_group()) # Add agreement and check again, - GroupGroupMembershipFactory.create( - parent_group=cdsa_group, child_group=obj.anvil_access_group - ) + GroupGroupMembershipFactory.create(parent_group=cdsa_group, child_group=obj.anvil_access_group) self.assertTrue(obj.is_in_cdsa_group()) @@ -379,9 +333,7 @@ class MemberAgreementTest(TestCase): def test_model_saving(self): """Creation using the model constructor and .save() works.""" - signed_agreement = factories.SignedAgreementFactory.create( - type=models.SignedAgreement.MEMBER - ) + signed_agreement = factories.SignedAgreementFactory.create(type=models.SignedAgreement.MEMBER) study_site = StudySiteFactory.create() instance = models.MemberAgreement( signed_agreement=signed_agreement, @@ -399,12 +351,8 @@ def test_is_primary(self): self.assertEqual(instance.is_primary, False) def test_clean_incorrect_type(self): - signed_agreement = factories.SignedAgreementFactory.create( - type=models.SignedAgreement.DATA_AFFILIATE - ) - instance = factories.MemberAgreementFactory.build( - signed_agreement=signed_agreement - ) + signed_agreement = factories.SignedAgreementFactory.create(type=models.SignedAgreement.DATA_AFFILIATE) + instance = factories.MemberAgreementFactory.build(signed_agreement=signed_agreement) with self.assertRaises(ValidationError) as e: instance.full_clean() self.assertIn("signed_agreement", e.exception.error_dict) @@ -437,9 +385,7 @@ def test_error_duplicate_signed_agreement(self): instance_2.full_clean() self.assertIn("signed_agreement", e.exception.error_dict) self.assertEqual(len(e.exception.error_dict["signed_agreement"]), 1) - self.assertIn( - "already exists", e.exception.error_dict["signed_agreement"][0].messages[0] - ) + self.assertIn("already exists", e.exception.error_dict["signed_agreement"][0].messages[0]) with self.assertRaises(IntegrityError): instance_2.save() @@ -453,9 +399,7 @@ class DataAffiliateAgreementTest(TestCase): def test_defaults(self): upload_group = ManagedGroupFactory.create() - signed_agreement = factories.SignedAgreementFactory.create( - type=models.SignedAgreement.DATA_AFFILIATE - ) + signed_agreement = factories.SignedAgreementFactory.create(type=models.SignedAgreement.DATA_AFFILIATE) study = StudyFactory.create() instance = models.DataAffiliateAgreement( signed_agreement=signed_agreement, @@ -468,9 +412,7 @@ def test_defaults(self): def test_model_saving(self): """Creation using the model constructor and .save() works.""" upload_group = ManagedGroupFactory.create() - signed_agreement = factories.SignedAgreementFactory.create( - type=models.SignedAgreement.DATA_AFFILIATE - ) + signed_agreement = factories.SignedAgreementFactory.create(type=models.SignedAgreement.DATA_AFFILIATE) study = StudyFactory.create() instance = models.DataAffiliateAgreement( signed_agreement=signed_agreement, @@ -489,9 +431,7 @@ def test_is_primary(self): self.assertEqual(instance.is_primary, False) def test_clean_incorrect_type(self): - signed_agreement = factories.SignedAgreementFactory.create( - type=models.SignedAgreement.MEMBER - ) + signed_agreement = factories.SignedAgreementFactory.create(type=models.SignedAgreement.MEMBER) study = StudyFactory.create() upload_group = ManagedGroupFactory.create() instance = factories.DataAffiliateAgreementFactory.build( @@ -555,9 +495,7 @@ def test_error_duplicate_signed_agreement(self): instance_2.full_clean() self.assertIn("signed_agreement", e.exception.error_dict) self.assertEqual(len(e.exception.error_dict["signed_agreement"]), 1) - self.assertIn( - "already exists", e.exception.error_dict["signed_agreement"][0].messages[0] - ) + self.assertIn("already exists", e.exception.error_dict["signed_agreement"][0].messages[0]) with self.assertRaises(IntegrityError): instance_2.save() @@ -567,9 +505,7 @@ def test_get_agreement_group(self): def test_requires_study_review_primary(self): """Can set requires_study_review""" - instance = factories.DataAffiliateAgreementFactory.create( - requires_study_review=True - ) + instance = factories.DataAffiliateAgreementFactory.create(requires_study_review=True) self.assertTrue(instance.requires_study_review) def test_requires_study_review_not_primary(self): @@ -594,9 +530,7 @@ class NonDataAffiliateAgreementTest(TestCase): def test_model_saving(self): """Creation using the model constructor and .save() works.""" - signed_agreement = factories.SignedAgreementFactory.create( - type=models.SignedAgreement.NON_DATA_AFFILIATE - ) + signed_agreement = factories.SignedAgreementFactory.create(type=models.SignedAgreement.NON_DATA_AFFILIATE) instance = models.NonDataAffiliateAgreement( signed_agreement=signed_agreement, affiliation="Foo", @@ -605,9 +539,7 @@ def test_model_saving(self): self.assertIsInstance(instance, models.NonDataAffiliateAgreement) def test_clean_incorrect_type(self): - signed_agreement = factories.SignedAgreementFactory.create( - type=models.SignedAgreement.MEMBER - ) + signed_agreement = factories.SignedAgreementFactory.create(type=models.SignedAgreement.MEMBER) instance = factories.NonDataAffiliateAgreementFactory.build( signed_agreement=signed_agreement, affiliation="Foo Bar", @@ -642,9 +574,7 @@ def test_error_duplicate_signed_agreement(self): instance_2.full_clean() self.assertIn("signed_agreement", e.exception.error_dict) self.assertEqual(len(e.exception.error_dict["signed_agreement"]), 1) - self.assertIn( - "already exists", e.exception.error_dict["signed_agreement"][0].messages[0] - ) + self.assertIn("already exists", e.exception.error_dict["signed_agreement"][0].messages[0]) with self.assertRaises(IntegrityError): instance_2.save() diff --git a/primed/cdsa/tests/test_tables.py b/primed/cdsa/tests/test_tables.py index 83f6bf55..2339a4fa 100644 --- a/primed/cdsa/tests/test_tables.py +++ b/primed/cdsa/tests/test_tables.py @@ -58,13 +58,9 @@ def test_number_accessors(self): """Table shows correct count for number of accessors.""" factories.MemberAgreementFactory.create() obj = factories.MemberAgreementFactory.create() - GroupAccountMembershipFactory.create( - group=obj.signed_agreement.anvil_access_group - ) + GroupAccountMembershipFactory.create(group=obj.signed_agreement.anvil_access_group) obj_2 = factories.MemberAgreementFactory.create() - GroupAccountMembershipFactory.create_batch( - 2, group=obj_2.signed_agreement.anvil_access_group - ) + GroupAccountMembershipFactory.create_batch(2, group=obj_2.signed_agreement.anvil_access_group) table = self.table_class(self.model.objects.all()) self.assertEqual(table.rows[0].get_cell("number_accessors"), 0) self.assertEqual(table.rows[1].get_cell("number_accessors"), 1) @@ -102,13 +98,9 @@ def test_number_accessors(self): """Table shows correct count for number of accessors.""" self.model_factory.create() obj = self.model_factory.create() - GroupAccountMembershipFactory.create( - group=obj.signed_agreement.anvil_access_group - ) + GroupAccountMembershipFactory.create(group=obj.signed_agreement.anvil_access_group) obj_2 = self.model_factory.create() - GroupAccountMembershipFactory.create_batch( - 2, group=obj_2.signed_agreement.anvil_access_group - ) + GroupAccountMembershipFactory.create_batch(2, group=obj_2.signed_agreement.anvil_access_group) table = self.table_class(self.model.objects.all()) self.assertEqual(table.rows[0].get_cell("number_accessors"), 0) self.assertEqual(table.rows[1].get_cell("number_accessors"), 1) @@ -146,13 +138,9 @@ def test_number_accessors(self): """Table shows correct count for number of accessors.""" self.model_factory.create() obj = self.model_factory.create() - GroupAccountMembershipFactory.create( - group=obj.signed_agreement.anvil_access_group - ) + GroupAccountMembershipFactory.create(group=obj.signed_agreement.anvil_access_group) obj_2 = self.model_factory.create() - GroupAccountMembershipFactory.create_batch( - 2, group=obj_2.signed_agreement.anvil_access_group - ) + GroupAccountMembershipFactory.create_batch(2, group=obj_2.signed_agreement.anvil_access_group) table = self.table_class(self.model.objects.all()) self.assertEqual(table.rows[0].get_cell("number_accessors"), 0) self.assertEqual(table.rows[1].get_cell("number_accessors"), 1) @@ -190,13 +178,9 @@ def test_number_accessors(self): """Table shows correct count for number of accessors.""" self.model_factory.create() obj = self.model_factory.create() - GroupAccountMembershipFactory.create( - group=obj.signed_agreement.anvil_access_group - ) + GroupAccountMembershipFactory.create(group=obj.signed_agreement.anvil_access_group) obj_2 = self.model_factory.create() - GroupAccountMembershipFactory.create_batch( - 2, group=obj_2.signed_agreement.anvil_access_group - ) + GroupAccountMembershipFactory.create_batch(2, group=obj_2.signed_agreement.anvil_access_group) table = self.table_class(self.model.objects.all()) self.assertEqual(table.rows[0].get_cell("number_accessors"), 0) self.assertEqual(table.rows[1].get_cell("number_accessors"), 1) @@ -238,32 +222,22 @@ def test_render_signing_group(self): # Members. study_site = StudySiteFactory.create(short_name="Test Site") record = factories.MemberAgreementFactory(study_site=study_site) - self.assertEqual( - table.render_signing_group(record.signed_agreement), "Test Site" - ) + self.assertEqual(table.render_signing_group(record.signed_agreement), "Test Site") # Data affiliates. study = StudyFactory.create(short_name="Test Study") record = factories.DataAffiliateAgreementFactory(study=study) - self.assertEqual( - table.render_signing_group(record.signed_agreement), "Test Study" - ) + self.assertEqual(table.render_signing_group(record.signed_agreement), "Test Study") # Non-data affiliates. record = factories.NonDataAffiliateAgreementFactory(affiliation="Test Affil") - self.assertEqual( - table.render_signing_group(record.signed_agreement), "Test Affil" - ) + self.assertEqual(table.render_signing_group(record.signed_agreement), "Test Affil") # Other catch-all case that shouldn't happen. 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" - ) + 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) @@ -312,41 +286,29 @@ def test_row_count_with_no_objects(self): def test_row_count_with_one_agreement(self): member_agreement = factories.MemberAgreementFactory.create() - GroupAccountMembershipFactory.create( - group__signedagreement=member_agreement.signed_agreement - ) + GroupAccountMembershipFactory.create(group__signedagreement=member_agreement.signed_agreement) table = self.table_class(self.model.objects.all()) self.assertEqual(len(table.rows), 1) def test_row_count_with_one_agreement_multiple_members(self): member_agreement = factories.MemberAgreementFactory.create() - GroupAccountMembershipFactory.create_batch( - 5, group__signedagreement=member_agreement.signed_agreement - ) + GroupAccountMembershipFactory.create_batch(5, group__signedagreement=member_agreement.signed_agreement) table = self.table_class(self.model.objects.all()) self.assertEqual(len(table.rows), 5) def test_row_count_with_two_agreements_multiple_members(self): member_agreement_1 = factories.MemberAgreementFactory.create() - GroupAccountMembershipFactory.create_batch( - 2, group__signedagreement=member_agreement_1.signed_agreement - ) + GroupAccountMembershipFactory.create_batch(2, group__signedagreement=member_agreement_1.signed_agreement) member_agreement_2 = factories.MemberAgreementFactory.create() - GroupAccountMembershipFactory.create_batch( - 3, group__signedagreement=member_agreement_2.signed_agreement - ) + GroupAccountMembershipFactory.create_batch(3, group__signedagreement=member_agreement_2.signed_agreement) table = self.table_class(self.model.objects.all()) self.assertEqual(len(table.rows), 5) def test_includes_components(self): agreement_1 = factories.MemberAgreementFactory.create(is_primary=True) - GroupAccountMembershipFactory.create( - group__signedagreement=agreement_1.signed_agreement - ) + GroupAccountMembershipFactory.create(group__signedagreement=agreement_1.signed_agreement) agreement_2 = factories.MemberAgreementFactory.create(is_primary=False) - GroupAccountMembershipFactory.create( - group__signedagreement=agreement_2.signed_agreement - ) + GroupAccountMembershipFactory.create(group__signedagreement=agreement_2.signed_agreement) table = self.table_class(self.model.objects.all()) self.assertEqual(len(table.rows), 2) @@ -354,23 +316,15 @@ def test_render_signing_group(self): table = self.table_class(self.model.objects.all()) # Members. agreement = factories.MemberAgreementFactory(study_site__short_name="Test Site") - record = GroupAccountMembershipFactory.create( - group__signedagreement=agreement.signed_agreement - ) + record = GroupAccountMembershipFactory.create(group__signedagreement=agreement.signed_agreement) self.assertEqual(table.render_signing_group(record), "Test Site") # Data affiliates. - agreement = factories.DataAffiliateAgreementFactory( - study__short_name="Test Study" - ) - record = GroupAccountMembershipFactory.create( - group__signedagreement=agreement.signed_agreement - ) + agreement = factories.DataAffiliateAgreementFactory(study__short_name="Test Study") + record = GroupAccountMembershipFactory.create(group__signedagreement=agreement.signed_agreement) self.assertEqual(table.render_signing_group(record), "Test Study") # Non-data affiliates. agreement = factories.NonDataAffiliateAgreementFactory(affiliation="Test affil") - record = GroupAccountMembershipFactory.create( - group__signedagreement=agreement.signed_agreement - ) + record = GroupAccountMembershipFactory.create(group__signedagreement=agreement.signed_agreement) self.assertEqual(table.render_signing_group(record), "Test affil") # Other catch-all case that shouldn't happen. agreement = factories.SignedAgreementFactory() @@ -424,20 +378,14 @@ def test_render_date_shared(self): cdsa_workspace = factories.CDSAWorkspaceFactory.create() self.assertEqual(table.render_date_shared(cdsa_workspace), "—") # Shared. - WorkspaceGroupSharingFactory.create( - workspace=cdsa_workspace.workspace, group__name="PRIMED_ALL" - ) + WorkspaceGroupSharingFactory.create(workspace=cdsa_workspace.workspace, group__name="PRIMED_ALL") 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" - ) + 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) diff --git a/primed/cdsa/tests/test_views.py b/primed/cdsa/tests/test_views.py index ab203d0a..e772d1f2 100644 --- a/primed/cdsa/tests/test_views.py +++ b/primed/cdsa/tests/test_views.py @@ -62,9 +62,7 @@ def test_links_for_staff_view(self): """Returns successful response code.""" user = User.objects.create_user(username="test", password="test") user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.client.force_login(user) response = self.client.get(self.get_url()) @@ -74,25 +72,17 @@ def test_links_for_staff_view(self): self.assertContains(response, reverse("cdsa:records:index")) # Links to add CDSAs. self.assertNotContains(response, reverse("cdsa:signed_agreements:members:new")) - self.assertNotContains( - response, reverse("cdsa:signed_agreements:data_affiliates:new") - ) - self.assertNotContains( - response, reverse("cdsa:signed_agreements:non_data_affiliates:new") - ) + self.assertNotContains(response, reverse("cdsa:signed_agreements:data_affiliates:new")) + self.assertNotContains(response, reverse("cdsa:signed_agreements:non_data_affiliates:new")) def test_links_for_staff_edit(self): """Returns successful response code.""" user = User.objects.create_user(username="test", password="test") user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) self.client.force_login(user) response = self.client.get(self.get_url()) @@ -102,12 +92,8 @@ def test_links_for_staff_edit(self): self.assertContains(response, reverse("cdsa:records:index")) # Links to add CDSAs. self.assertContains(response, reverse("cdsa:signed_agreements:members:new")) - self.assertContains( - response, reverse("cdsa:signed_agreements:data_affiliates:new") - ) - self.assertContains( - response, reverse("cdsa:signed_agreements:non_data_affiliates:new") - ) + self.assertContains(response, reverse("cdsa:signed_agreements:data_affiliates:new")) + self.assertContains(response, reverse("cdsa:signed_agreements:non_data_affiliates:new")) class AgreementVersionListTest(TestCase): @@ -119,9 +105,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -149,9 +133,7 @@ def test_status_code_with_user_permission(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url()) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -162,9 +144,7 @@ def test_table_class(self): self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertIn("table", response.context_data) - self.assertIsInstance( - response.context_data["table"], tables.AgreementVersionTable - ) + self.assertIsInstance(response.context_data["table"], tables.AgreementVersionTable) def test_workspace_table_none(self): """No rows are shown if there are no AgreementVersion objects.""" @@ -191,9 +171,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) # Create an object test this with. self.obj = factories.AgreementMajorVersionFactory.create() @@ -223,9 +201,7 @@ def test_status_code_with_user_permission(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url(2)) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -254,12 +230,8 @@ def test_context_table_classes(self): self.assertEqual(response.status_code, 200) self.assertIn("tables", response.context_data) self.assertEqual(len(response.context_data["tables"]), 2) - self.assertIsInstance( - response.context_data["tables"][0], tables.AgreementVersionTable - ) - self.assertIsInstance( - response.context_data["tables"][1], tables.SignedAgreementTable - ) + self.assertIsInstance(response.context_data["tables"][0], tables.AgreementVersionTable) + self.assertIsInstance(response.context_data["tables"][1], tables.SignedAgreementTable) def test_response_includes_agreement_version_table(self): """agreement_version_table includes agreement_versions with this major version.""" @@ -270,9 +242,7 @@ def test_response_includes_agreement_version_table(self): def test_response_includes_agreement_version_table_other_major_version(self): """agreement_version_table includes only agreement_versions with this major version.""" - other_agreement = factories.AgreementVersionFactory.create( - major_version__version=self.obj.version + 1 - ) + other_agreement = factories.AgreementVersionFactory.create(major_version__version=self.obj.version + 1) self.client.force_login(self.user) response = self.client.get(self.get_url(self.obj.version)) self.assertEqual(len(response.context_data["tables"][0].rows), 0) @@ -280,9 +250,7 @@ def test_response_includes_agreement_version_table_other_major_version(self): def test_response_signed_agreement_table_three_agreements(self): """signed_agreement_table includes all types of agreements.""" - factories.MemberAgreementFactory.create( - signed_agreement__version__major_version__version=self.obj.version - ) + factories.MemberAgreementFactory.create(signed_agreement__version__major_version__version=self.obj.version) factories.DataAffiliateAgreementFactory.create( signed_agreement__version__major_version__version=self.obj.version ) @@ -328,14 +296,10 @@ def test_invalidate_button_valid_user_has_edit_perm(self): """Invalidate button appears when the user has edit permission and the instance is valid.""" user = User.objects.create_user(username="test_edit", password="test_edit") user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) self.client.force_login(user) response = self.client.get(self.get_url(self.obj.version)) @@ -365,14 +329,10 @@ def test_invalidate_button_invalid_user_has_edit_perm(self): self.obj.save() user = User.objects.create_user(username="test_edit", password="test_edit") user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) self.client.force_login(user) response = self.client.get(self.get_url(self.obj.version)) @@ -409,14 +369,10 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -431,9 +387,7 @@ def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." # Need a client for redirects. response = self.client.get(self.get_url(1)) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(1) - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(1)) def test_status_code_with_user_permission_edit(self): """Returns successful response code.""" @@ -444,9 +398,7 @@ def test_status_code_with_user_permission_edit(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url(1)) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -455,13 +407,9 @@ def test_access_without_user_permission(self): def test_access_without_user_permission_view(self): """Raises permission denied if user has only view permission.""" instance = factories.AgreementMajorVersionFactory.create() - user_view_perm = User.objects.create_user( - username="test-none", password="test-none" - ) + user_view_perm = User.objects.create_user(username="test-none", password="test-none") user_view_perm.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url(instance.version)) request.user = user_view_perm @@ -494,9 +442,7 @@ def test_form_class(self): instance = factories.AgreementMajorVersionFactory.create() self.client.force_login(self.user) response = self.client.get(self.get_url(instance.version)) - self.assertIsInstance( - response.context_data["form"], forms.AgreementMajorVersionIsValidForm - ) + self.assertIsInstance(response.context_data["form"], forms.AgreementMajorVersionIsValidForm) def test_invalidates_instance(self): """Can invalidate the instance.""" @@ -510,37 +456,25 @@ def test_invalidates_instance(self): def test_sets_one_signed_agreement_to_lapsed(self): """Sets SignedAgreements associated with this major version to LAPSED.""" instance = factories.AgreementMajorVersionFactory.create() - signed_agreement = factories.SignedAgreementFactory.create( - version__major_version=instance - ) + signed_agreement = factories.SignedAgreementFactory.create(version__major_version=instance) self.client.force_login(self.user) response = self.client.post(self.get_url(instance.version), {}) self.assertEqual(response.status_code, 302) signed_agreement.refresh_from_db() - self.assertEqual( - signed_agreement.status, models.SignedAgreement.StatusChoices.LAPSED - ) + self.assertEqual(signed_agreement.status, models.SignedAgreement.StatusChoices.LAPSED) def test_sets_two_signed_agreements_to_lapsed(self): """Sets SignedAgreements associated with this major version to LAPSED.""" instance = factories.AgreementMajorVersionFactory.create() - signed_agreement_1 = factories.SignedAgreementFactory.create( - version__major_version=instance - ) - signed_agreement_2 = factories.SignedAgreementFactory.create( - version__major_version=instance - ) + signed_agreement_1 = factories.SignedAgreementFactory.create(version__major_version=instance) + signed_agreement_2 = factories.SignedAgreementFactory.create(version__major_version=instance) self.client.force_login(self.user) response = self.client.post(self.get_url(instance.version), {}) self.assertEqual(response.status_code, 302) signed_agreement_1.refresh_from_db() - self.assertEqual( - signed_agreement_1.status, models.SignedAgreement.StatusChoices.LAPSED - ) + self.assertEqual(signed_agreement_1.status, models.SignedAgreement.StatusChoices.LAPSED) signed_agreement_2.refresh_from_db() - self.assertEqual( - signed_agreement_2.status, models.SignedAgreement.StatusChoices.LAPSED - ) + self.assertEqual(signed_agreement_2.status, models.SignedAgreement.StatusChoices.LAPSED) def test_only_sets_active_signed_agreements_to_lapsed(self): """Does not set SignedAgreements with a different status to LAPSED.""" @@ -561,17 +495,11 @@ def test_only_sets_active_signed_agreements_to_lapsed(self): response = self.client.post(self.get_url(instance.version), {}) self.assertEqual(response.status_code, 302) lapsed_agreement.refresh_from_db() - self.assertEqual( - lapsed_agreement.status, models.SignedAgreement.StatusChoices.LAPSED - ) + self.assertEqual(lapsed_agreement.status, models.SignedAgreement.StatusChoices.LAPSED) withdrawn_agreement.refresh_from_db() - self.assertEqual( - withdrawn_agreement.status, models.SignedAgreement.StatusChoices.WITHDRAWN - ) + self.assertEqual(withdrawn_agreement.status, models.SignedAgreement.StatusChoices.WITHDRAWN) replaced_agreement.refresh_from_db() - self.assertEqual( - replaced_agreement.status, models.SignedAgreement.StatusChoices.REPLACED - ) + self.assertEqual(replaced_agreement.status, models.SignedAgreement.StatusChoices.REPLACED) def test_only_sets_associated_signed_agreements_to_lapsed(self): """Does not set SignedAgreements associated with a different version to LAPSED.""" @@ -581,9 +509,7 @@ def test_only_sets_associated_signed_agreements_to_lapsed(self): response = self.client.post(self.get_url(instance.version), {}) self.assertEqual(response.status_code, 302) signed_agreement.refresh_from_db() - self.assertEqual( - signed_agreement.status, models.SignedAgreement.StatusChoices.ACTIVE - ) + self.assertEqual(signed_agreement.status, models.SignedAgreement.StatusChoices.ACTIVE) def test_redirect_url(self): """Redirects to successful url.""" @@ -599,9 +525,7 @@ def test_success_message(self): response = self.client.post(self.get_url(instance.version), {}) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.AgreementMajorVersionInvalidate.success_message, str(messages[0]) - ) + self.assertEqual(views.AgreementMajorVersionInvalidate.success_message, str(messages[0])) def test_version_already_invalid_get(self): instance = factories.AgreementMajorVersionFactory.create(is_valid=False) @@ -635,9 +559,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) # Create an object test this with. self.obj = factories.AgreementVersionFactory.create() @@ -662,16 +584,12 @@ def test_view_redirect_not_logged_in(self): def test_status_code_with_user_permission(self): """Returns successful response code.""" self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.obj.major_version.version, self.obj.minor_version) - ) + response = self.client.get(self.get_url(self.obj.major_version.version, self.obj.minor_version)) self.assertEqual(response.status_code, 200) def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url(2, 5)) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -681,16 +599,12 @@ def test_view_status_code_with_existing_object(self): """Returns a successful status code for an existing object pk.""" # Only clients load the template. self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.obj.major_version.version, self.obj.minor_version) - ) + response = self.client.get(self.get_url(self.obj.major_version.version, self.obj.minor_version)) self.assertEqual(response.status_code, 200) def test_view_status_code_with_invalid_version(self): """Raises a 404 error with an invalid major and minor version.""" - request = self.factory.get( - self.get_url(self.obj.major_version.version + 1, self.obj.minor_version + 1) - ) + request = self.factory.get(self.get_url(self.obj.major_version.version + 1, self.obj.minor_version + 1)) request.user = self.user with self.assertRaises(Http404): self.get_view()( @@ -701,9 +615,7 @@ def test_view_status_code_with_invalid_version(self): def test_view_status_code_with_other_major_version(self): """Raises a 404 error with an invalid object major version.""" - request = self.factory.get( - self.get_url(self.obj.major_version.version + 1, self.obj.minor_version) - ) + request = self.factory.get(self.get_url(self.obj.major_version.version + 1, self.obj.minor_version)) request.user = self.user with self.assertRaises(Http404): self.get_view()( @@ -714,9 +626,7 @@ def test_view_status_code_with_other_major_version(self): def test_view_status_code_with_other_minor_version(self): """Raises a 404 error with an invalid object minor version.""" - request = self.factory.get( - self.get_url(self.obj.major_version.version, self.obj.minor_version + 1) - ) + request = self.factory.get(self.get_url(self.obj.major_version.version, self.obj.minor_version + 1)) request.user = self.user with self.assertRaises(Http404): self.get_view()( @@ -736,30 +646,18 @@ def test_view_status_code_with_other_minor_version(self): def test_response_includes_signed_agreement_table(self): """Response includes a table of SignedAgreements.""" self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.obj.major_version.version, self.obj.minor_version) - ) + response = self.client.get(self.get_url(self.obj.major_version.version, self.obj.minor_version)) self.assertEqual(response.status_code, 200) self.assertIn("signed_agreement_table", response.context_data) - self.assertIsInstance( - response.context_data["signed_agreement_table"], tables.SignedAgreementTable - ) + self.assertIsInstance(response.context_data["signed_agreement_table"], tables.SignedAgreementTable) def test_response_signed_agreement_table_three_agreements(self): """signed_agreement_table includes all types of agreements.""" - member_agreement = factories.MemberAgreementFactory.create( - signed_agreement__version=self.obj - ) - da_agreement = factories.DataAffiliateAgreementFactory.create( - signed_agreement__version=self.obj - ) - nda_agreement = factories.NonDataAffiliateAgreementFactory.create( - signed_agreement__version=self.obj - ) + member_agreement = factories.MemberAgreementFactory.create(signed_agreement__version=self.obj) + da_agreement = factories.DataAffiliateAgreementFactory.create(signed_agreement__version=self.obj) + nda_agreement = factories.NonDataAffiliateAgreementFactory.create(signed_agreement__version=self.obj) self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.obj.major_version.version, self.obj.minor_version) - ) + response = self.client.get(self.get_url(self.obj.major_version.version, self.obj.minor_version)) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.context_data["signed_agreement_table"].rows), 3) self.assertIn( @@ -781,9 +679,7 @@ def test_response_signed_agreement_table_other_version(self): da_agreement = factories.DataAffiliateAgreementFactory.create() nda_agreement = factories.NonDataAffiliateAgreementFactory.create() self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.obj.major_version.version, self.obj.minor_version) - ) + response = self.client.get(self.get_url(self.obj.major_version.version, self.obj.minor_version)) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.context_data["signed_agreement_table"].rows), 0) self.assertNotIn( @@ -802,9 +698,7 @@ def test_response_signed_agreement_table_other_version(self): def test_response_show_deprecation_message_valid(self): """response context does not show a deprecation warning when AgreementMajorVersion is valid.""" self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.obj.major_version.version, self.obj.minor_version) - ) + response = self.client.get(self.get_url(self.obj.major_version.version, self.obj.minor_version)) self.assertEqual(response.status_code, 200) self.assertIn("show_deprecation_message", response.context_data) self.assertFalse(response.context_data["show_deprecation_message"]) @@ -815,9 +709,7 @@ def test_response_show_deprecation_message_not_valid(self): self.obj.major_version.is_valid = False self.obj.major_version.save() self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.obj.major_version.version, self.obj.minor_version) - ) + response = self.client.get(self.get_url(self.obj.major_version.version, self.obj.minor_version)) self.assertEqual(response.status_code, 200) self.assertIn("show_deprecation_message", response.context_data) self.assertTrue(response.context_data["show_deprecation_message"]) @@ -833,9 +725,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -863,9 +753,7 @@ def test_status_code_with_user_permission(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url()) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -876,9 +764,7 @@ def test_table_class(self): self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertIn("table", response.context_data) - self.assertIsInstance( - response.context_data["table"], tables.SignedAgreementTable - ) + self.assertIsInstance(response.context_data["table"], tables.SignedAgreementTable) def test_workspace_table_none(self): """No rows are shown if there are no SignedAgreement objects.""" @@ -908,14 +794,10 @@ def setUp(self): # Create a user with both view and edit permissions. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -930,9 +812,7 @@ def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." # Need a client for redirects. response = self.client.get(self.get_url(1)) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(1) - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(1)) def test_status_code_with_user_permission(self): """Returns successful response code.""" @@ -943,13 +823,9 @@ def test_status_code_with_user_permission(self): def test_access_with_view_permission(self): """Raises permission denied if user has only view permission.""" - user_with_view_perm = User.objects.create_user( - username="test-other", password="test-other" - ) + user_with_view_perm = User.objects.create_user(username="test-other", password="test-other") user_with_view_perm.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url(1)) request.user = user_with_view_perm @@ -958,9 +834,7 @@ def test_access_with_view_permission(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url(1)) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -987,9 +861,7 @@ def test_has_form_in_context(self): self.client.force_login(self.user) response = self.client.get(self.get_url(instance.signed_agreement.cc_id)) self.assertTrue("form" in response.context_data) - self.assertIsInstance( - response.context_data["form"], forms.SignedAgreementStatusForm - ) + self.assertIsInstance(response.context_data["form"], forms.SignedAgreementStatusForm) def test_can_modify_status(self): """Can change the status.""" @@ -1014,9 +886,7 @@ def test_invalid_status(self): signed_agreement__status=models.SignedAgreement.StatusChoices.ACTIVE ) self.client.force_login(self.user) - response = self.client.post( - self.get_url(instance.signed_agreement.cc_id), {"status": "foo"} - ) + response = self.client.post(self.get_url(instance.signed_agreement.cc_id), {"status": "foo"}) self.assertEqual(response.status_code, 200) self.assertIn("form", response.context) form = response.context_data["form"] @@ -1042,9 +912,7 @@ def test_success_message(self): ) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.SignedAgreementStatusUpdate.success_message, str(messages[0]) - ) + self.assertEqual(views.SignedAgreementStatusUpdate.success_message, str(messages[0])) def test_redirects_to_object_detail(self): """After successfully creating an object, view redirects to the object's detail page.""" @@ -1068,14 +936,10 @@ def setUp(self): # Create a user with both view and edit permissions. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -1090,9 +954,7 @@ def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." # Need a client for redirects. response = self.client.get(self.get_url(1)) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(1) - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(1)) def test_status_code_with_user_permission(self): """Returns successful response code.""" @@ -1103,13 +965,9 @@ def test_status_code_with_user_permission(self): def test_access_with_view_permission(self): """Raises permission denied if user has only view permission.""" - user_with_view_perm = User.objects.create_user( - username="test-other", password="test-other" - ) + user_with_view_perm = User.objects.create_user(username="test-other", password="test-other") user_with_view_perm.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url(1)) request.user = user_with_view_perm @@ -1118,9 +976,7 @@ def test_access_with_view_permission(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url(1)) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -1147,9 +1003,7 @@ def test_has_form_in_context(self): self.client.force_login(self.user) response = self.client.get(self.get_url(instance.signed_agreement.cc_id)) self.assertTrue("form" in response.context_data) - self.assertIsInstance( - response.context_data["form"], forms.SignedAgreementStatusForm - ) + self.assertIsInstance(response.context_data["form"], forms.SignedAgreementStatusForm) def test_can_modify_status(self): """Can change the status.""" @@ -1174,9 +1028,7 @@ def test_invalid_status(self): signed_agreement__status=models.SignedAgreement.StatusChoices.ACTIVE ) self.client.force_login(self.user) - response = self.client.post( - self.get_url(instance.signed_agreement.cc_id), {"status": "foo"} - ) + response = self.client.post(self.get_url(instance.signed_agreement.cc_id), {"status": "foo"}) self.assertEqual(response.status_code, 200) self.assertIn("form", response.context) form = response.context_data["form"] @@ -1202,9 +1054,7 @@ def test_success_message(self): ) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.SignedAgreementStatusUpdate.success_message, str(messages[0]) - ) + self.assertEqual(views.SignedAgreementStatusUpdate.success_message, str(messages[0])) def test_redirects_to_object_detail(self): """After successfully creating an object, view redirects to the object's detail page.""" @@ -1228,14 +1078,10 @@ def setUp(self): # Create a user with both view and edit permissions. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -1250,9 +1096,7 @@ def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." # Need a client for redirects. response = self.client.get(self.get_url(1)) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(1) - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(1)) def test_status_code_with_user_permission(self): """Returns successful response code.""" @@ -1263,13 +1107,9 @@ def test_status_code_with_user_permission(self): def test_access_with_view_permission(self): """Raises permission denied if user has only view permission.""" - user_with_view_perm = User.objects.create_user( - username="test-other", password="test-other" - ) + user_with_view_perm = User.objects.create_user(username="test-other", password="test-other") user_with_view_perm.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url(1)) request.user = user_with_view_perm @@ -1278,9 +1118,7 @@ def test_access_with_view_permission(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url(1)) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -1307,9 +1145,7 @@ def test_has_form_in_context(self): self.client.force_login(self.user) response = self.client.get(self.get_url(instance.signed_agreement.cc_id)) self.assertTrue("form" in response.context_data) - self.assertIsInstance( - response.context_data["form"], forms.SignedAgreementStatusForm - ) + self.assertIsInstance(response.context_data["form"], forms.SignedAgreementStatusForm) def test_can_modify_status(self): """Can change the status.""" @@ -1334,9 +1170,7 @@ def test_invalid_status(self): signed_agreement__status=models.SignedAgreement.StatusChoices.ACTIVE ) self.client.force_login(self.user) - response = self.client.post( - self.get_url(instance.signed_agreement.cc_id), {"status": "foo"} - ) + response = self.client.post(self.get_url(instance.signed_agreement.cc_id), {"status": "foo"}) self.assertEqual(response.status_code, 200) self.assertIn("form", response.context) form = response.context_data["form"] @@ -1362,9 +1196,7 @@ def test_success_message(self): ) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.SignedAgreementStatusUpdate.success_message, str(messages[0]) - ) + self.assertEqual(views.SignedAgreementStatusUpdate.success_message, str(messages[0])) def test_redirects_to_object_detail(self): """After successfully creating an object, view redirects to the object's detail page.""" @@ -1388,14 +1220,10 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) # Create the admins group. self.cc_admins_group = ManagedGroupFactory.create(name="TEST_PRIMED_CC_ADMINS") @@ -1412,9 +1240,7 @@ def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." # Need a client for redirects. response = self.client.get(self.get_url()) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url() - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url()) def test_status_code_with_user_permission_edit(self): """Returns successful response code.""" @@ -1424,9 +1250,7 @@ def test_status_code_with_user_permission_edit(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url()) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -1434,13 +1258,9 @@ def test_access_without_user_permission(self): def test_access_without_user_permission_view(self): """Raises permission denied if user has only view permission.""" - user_view_perm = User.objects.create_user( - username="test-none", password="test-none" - ) + user_view_perm = User.objects.create_user(username="test-none", password="test-none") user_view_perm.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user_view_perm @@ -1460,9 +1280,7 @@ def test_form_classes(self): response = self.client.get(self.get_url()) self.assertIsInstance(response.context_data["form"], forms.SignedAgreementForm) self.assertEqual(len(response.context_data["formset"].forms), 1) - self.assertIsInstance( - response.context_data["formset"].forms[0], forms.MemberAgreementForm - ) + self.assertIsInstance(response.context_data["formset"].forms[0], forms.MemberAgreementForm) def test_can_create_object(self): """Can create an object.""" @@ -1471,13 +1289,8 @@ def test_can_create_object(self): agreement_version = factories.AgreementVersionFactory.create() study_site = StudySiteFactory.create() # API response to create the associated anvil_access_group. - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1234" - ) - self.anvil_response_mock.add( - responses.POST, api_url, status=201, json={"message": "mock message"} - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1234" + self.anvil_response_mock.add(responses.POST, api_url, status=201, json={"message": "mock message"}) # CC admins group membership. self.anvil_response_mock.add( responses.PUT, @@ -1515,12 +1328,8 @@ def test_can_create_object(self): self.assertEqual(new_agreement.type, new_agreement.MEMBER) # AnVIL group was set correctly. self.assertIsInstance(new_agreement.anvil_access_group, ManagedGroup) - self.assertEqual( - new_agreement.anvil_access_group.name, "TEST_PRIMED_CDSA_ACCESS_1234" - ) - self.assertEqual( - new_agreement.status, models.SignedAgreement.StatusChoices.ACTIVE - ) + self.assertEqual(new_agreement.anvil_access_group.name, "TEST_PRIMED_CDSA_ACCESS_1234") + self.assertEqual(new_agreement.status, models.SignedAgreement.StatusChoices.ACTIVE) # Check the agreement type. self.assertEqual(models.MemberAgreement.objects.count(), 1) new_agreement_type = models.MemberAgreement.objects.latest("pk") @@ -1535,13 +1344,8 @@ def test_redirect_url(self): agreement_version = factories.AgreementVersionFactory.create() study_site = StudySiteFactory.create() # API response to create the associated anvil_access_group. - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1234" - ) - self.anvil_response_mock.add( - responses.POST, api_url, status=201, json={"message": "mock message"} - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1234" + self.anvil_response_mock.add(responses.POST, api_url, status=201, json={"message": "mock message"}) # CC admins group membership. self.anvil_response_mock.add( responses.PUT, @@ -1576,13 +1380,8 @@ def test_success_message(self): agreement_version = factories.AgreementVersionFactory.create() study_site = StudySiteFactory.create() # API response to create the associated anvil_access_group. - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1234" - ) - self.anvil_response_mock.add( - responses.POST, api_url, status=201, json={"message": "mock message"} - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1234" + self.anvil_response_mock.add(responses.POST, api_url, status=201, json={"message": "mock message"}) # CC admins group membership. self.anvil_response_mock.add( responses.PUT, @@ -2068,12 +1867,8 @@ def test_error_duplicate_project_id(self): ) self.assertEqual(response.status_code, 200) # No new objects were created. - self.assertEqual( - models.SignedAgreement.objects.count(), 1 - ) # One already existed. - self.assertEqual( - models.MemberAgreement.objects.count(), 1 - ) # One already existed. + self.assertEqual(models.SignedAgreement.objects.count(), 1) # One already existed. + self.assertEqual(models.MemberAgreement.objects.count(), 1) # One already existed. # Form has errors in the correct field. form = response.context_data["form"] self.assertFalse(form.is_valid()) @@ -2096,13 +1891,8 @@ def test_creates_anvil_access_group(self): representative = UserFactory.create() agreement_version = factories.AgreementVersionFactory.create() study_site = StudySiteFactory.create() - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_2345" - ) - self.anvil_response_mock.add( - responses.POST, api_url, status=201, json={"message": "mock message"} - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_2345" + self.anvil_response_mock.add(responses.POST, api_url, status=201, json={"message": "mock message"}) # CC admins group membership. self.anvil_response_mock.add( responses.PUT, @@ -2148,12 +1938,8 @@ def test_creates_anvil_groups_different_setting_access_group_prefix(self): representative = UserFactory.create() agreement_version = factories.AgreementVersionFactory.create() study_site = StudySiteFactory.create() - api_url = ( - self.api_client.sam_entry_point + "/api/groups/v1/foo_CDSA_ACCESS_2345" - ) - self.anvil_response_mock.add( - responses.POST, api_url, status=201, json={"message": "mock message"} - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/foo_CDSA_ACCESS_2345" + self.anvil_response_mock.add(responses.POST, api_url, status=201, json={"message": "mock message"}) # CC admins group membership. self.anvil_response_mock.add( responses.PUT, @@ -2195,18 +1981,12 @@ def test_creates_anvil_groups_different_setting_cc_admins_group_name(self): representative = UserFactory.create() agreement_version = factories.AgreementVersionFactory.create() study_site = StudySiteFactory.create() - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_2345" - ) - self.anvil_response_mock.add( - responses.POST, api_url, status=201, json={"message": "mock message"} - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_2345" + self.anvil_response_mock.add(responses.POST, api_url, status=201, json={"message": "mock message"}) # CC admins group membership. self.anvil_response_mock.add( responses.PUT, - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_2345/admin/foo@firecloud.org", + self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_2345/admin/foo@firecloud.org", status=204, ) response = self.client.post( @@ -2241,12 +2021,8 @@ def test_manage_group_create_api_error(self): agreement_version = factories.AgreementVersionFactory.create() study_site = StudySiteFactory.create() # API response to create the associated anvil_access_group. - api_url = ( - self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1" - ) - self.anvil_response_mock.add( - responses.POST, api_url, status=500, json={"message": "other error"} - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1" + self.anvil_response_mock.add(responses.POST, api_url, status=500, json={"message": "other error"}) response = self.client.post( self.get_url(), { @@ -2311,9 +2087,7 @@ def test_managed_group_already_exists_in_app(self): # ...but there was an error with the group name. messages = list(response.context["messages"]) self.assertEqual(len(messages), 1) - self.assertEqual( - views.MemberAgreementCreate.ERROR_CREATING_GROUP, str(messages[0]) - ) + self.assertEqual(views.MemberAgreementCreate.ERROR_CREATING_GROUP, str(messages[0])) # No dbGaPApplication was created. self.assertEqual(models.SignedAgreement.objects.count(), 0) @@ -2322,13 +2096,8 @@ def test_admin_group_membership_api_error(self): representative = UserFactory.create() agreement_version = factories.AgreementVersionFactory.create() study_site = StudySiteFactory.create() - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_2345" - ) - self.anvil_response_mock.add( - responses.POST, api_url, status=201, json={"message": "mock message"} - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_2345" + self.anvil_response_mock.add(responses.POST, api_url, status=201, json={"message": "mock message"}) # CC admins group membership. self.anvil_response_mock.add( responses.PUT, @@ -2378,9 +2147,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) # Create an object test this with. self.obj = factories.MemberAgreementFactory.create() @@ -2410,9 +2177,7 @@ def test_status_code_with_user_permission(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url(1)) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -2436,9 +2201,7 @@ def test_response_includes_link_to_user_profile(self): """Response includes a link to the user profile page.""" self.client.force_login(self.user) response = self.client.get(self.get_url(self.obj.signed_agreement.cc_id)) - self.assertContains( - response, self.obj.signed_agreement.representative.get_absolute_url() - ) + self.assertContains(response, self.obj.signed_agreement.representative.get_absolute_url()) def test_response_includes_link_to_study_site(self): """Response includes a link to the study site detail page.""" @@ -2450,9 +2213,7 @@ def test_response_includes_link_to_anvil_access_group(self): """Response includes a link to the AnVIL access group detail page.""" self.client.force_login(self.user) response = self.client.get(self.get_url(self.obj.signed_agreement.cc_id)) - self.assertContains( - response, self.obj.signed_agreement.anvil_access_group.get_absolute_url() - ) + self.assertContains(response, self.obj.signed_agreement.anvil_access_group.get_absolute_url()) def test_response_show_deprecation_message_valid(self): """response context does not show a deprecation warning when AgreementMajorVersion is valid.""" @@ -2478,14 +2239,10 @@ def test_change_status_button_user_has_edit_perm(self): """Invalidate button appears when the user has edit permission and the instance is valid.""" user = User.objects.create_user(username="test_edit", password="test_edit") user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) self.client.force_login(user) response = self.client.get(self.get_url(self.obj.signed_agreement.cc_id)) @@ -2548,9 +2305,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -2578,9 +2333,7 @@ def test_status_code_with_user_permission(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url()) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -2591,9 +2344,7 @@ def test_table_class(self): self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertIn("table", response.context_data) - self.assertIsInstance( - response.context_data["table"], tables.MemberAgreementTable - ) + self.assertIsInstance(response.context_data["table"], tables.MemberAgreementTable) def test_workspace_table_none(self): """No rows are shown if there are no MemberAgreement objects.""" @@ -2621,14 +2372,10 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) # Create the admins group. self.cc_admins_group = ManagedGroupFactory.create(name="TEST_PRIMED_CC_ADMINS") @@ -2645,9 +2392,7 @@ def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." # Need a client for redirects. response = self.client.get(self.get_url()) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url() - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url()) def test_status_code_with_user_permission_edit(self): """Returns successful response code.""" @@ -2657,9 +2402,7 @@ def test_status_code_with_user_permission_edit(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url()) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -2667,13 +2410,9 @@ def test_access_without_user_permission(self): def test_access_without_user_permission_view(self): """Raises permission denied if user has only view permission.""" - user_view_perm = User.objects.create_user( - username="test-none", password="test-none" - ) + user_view_perm = User.objects.create_user(username="test-none", password="test-none") user_view_perm.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user_view_perm @@ -2692,9 +2431,7 @@ def test_form_classes(self): self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertIsInstance(response.context_data["form"], forms.SignedAgreementForm) - self.assertIsInstance( - response.context_data["formset"].forms[0], forms.DataAffiliateAgreementForm - ) + self.assertIsInstance(response.context_data["formset"].forms[0], forms.DataAffiliateAgreementForm) def test_can_create_object(self): """Can create an object.""" @@ -2705,15 +2442,13 @@ def test_can_create_object(self): # API response to create the associated anvil_access_group. self.anvil_response_mock.add( responses.POST, - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1234", + self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1234", status=201, json={"message": "mock message"}, ) self.anvil_response_mock.add( responses.POST, - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_UPLOAD_1234", + self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_UPLOAD_1234", status=201, json={"message": "mock message"}, ) @@ -2760,12 +2495,8 @@ def test_can_create_object(self): self.assertEqual(new_agreement.type, new_agreement.DATA_AFFILIATE) # AnVIL group was set correctly. self.assertIsInstance(new_agreement.anvil_access_group, ManagedGroup) - self.assertEqual( - new_agreement.anvil_access_group.name, "TEST_PRIMED_CDSA_ACCESS_1234" - ) - self.assertEqual( - new_agreement.status, models.SignedAgreement.StatusChoices.ACTIVE - ) + self.assertEqual(new_agreement.anvil_access_group.name, "TEST_PRIMED_CDSA_ACCESS_1234") + self.assertEqual(new_agreement.status, models.SignedAgreement.StatusChoices.ACTIVE) # Check the agreement type. self.assertEqual(models.DataAffiliateAgreement.objects.count(), 1) new_agreement_type = models.DataAffiliateAgreement.objects.latest("pk") @@ -2773,9 +2504,7 @@ def test_can_create_object(self): self.assertEqual(new_agreement_type.is_primary, True) self.assertEqual(new_agreement_type.study, study) self.assertIsInstance(new_agreement_type.anvil_upload_group, ManagedGroup) - self.assertEqual( - new_agreement_type.anvil_upload_group.name, "TEST_PRIMED_CDSA_UPLOAD_1234" - ) + self.assertEqual(new_agreement_type.anvil_upload_group.name, "TEST_PRIMED_CDSA_UPLOAD_1234") def test_redirect_url(self): """Redirects to successful url.""" @@ -2786,15 +2515,13 @@ def test_redirect_url(self): # API response to create the associated anvil_access_group. self.anvil_response_mock.add( responses.POST, - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1234", + self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1234", status=201, json={"message": "mock message"}, ) self.anvil_response_mock.add( responses.POST, - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_UPLOAD_1234", + self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_UPLOAD_1234", status=201, json={"message": "mock message"}, ) @@ -2840,15 +2567,13 @@ def test_success_message(self): # API response to create the associated anvil_access_group. self.anvil_response_mock.add( responses.POST, - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1234", + self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1234", status=201, json={"message": "mock message"}, ) self.anvil_response_mock.add( responses.POST, - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_UPLOAD_1234", + self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_UPLOAD_1234", status=201, json={"message": "mock message"}, ) @@ -2884,9 +2609,7 @@ def test_success_message(self): ) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.DataAffiliateAgreementCreate.success_message, str(messages[0]) - ) + self.assertEqual(views.DataAffiliateAgreementCreate.success_message, str(messages[0])) def test_can_create_primary_with_requires_study_review(self): """Can create an object.""" @@ -2897,15 +2620,13 @@ def test_can_create_primary_with_requires_study_review(self): # API response to create the associated anvil_access_group. self.anvil_response_mock.add( responses.POST, - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1234", + self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1234", status=201, json={"message": "mock message"}, ) self.anvil_response_mock.add( responses.POST, - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_UPLOAD_1234", + self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_UPLOAD_1234", status=201, json={"message": "mock message"}, ) @@ -2995,15 +2716,13 @@ def test_can_create_primary_with_additional_limitations(self): # API response to create the associated anvil_access_group. self.anvil_response_mock.add( responses.POST, - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1234", + self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1234", status=201, json={"message": "mock message"}, ) self.anvil_response_mock.add( responses.POST, - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_UPLOAD_1234", + self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_UPLOAD_1234", status=201, json={"message": "mock message"}, ) @@ -3541,12 +3260,8 @@ def test_error_duplicate_project_id(self): ) self.assertEqual(response.status_code, 200) # No new objects were created. - self.assertEqual( - models.SignedAgreement.objects.count(), 1 - ) # One already existed. - self.assertEqual( - models.DataAffiliateAgreement.objects.count(), 1 - ) # One already existed. + self.assertEqual(models.SignedAgreement.objects.count(), 1) # One already existed. + self.assertEqual(models.DataAffiliateAgreement.objects.count(), 1) # One already existed. # Form has errors in the correct field. form = response.context_data["form"] self.assertFalse(form.is_valid()) @@ -3571,15 +3286,13 @@ def test_creates_anvil_groups(self): study = StudyFactory.create() self.anvil_response_mock.add( responses.POST, - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_2345", + self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_2345", status=201, json={"message": "mock message"}, ) self.anvil_response_mock.add( responses.POST, - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_UPLOAD_2345", + self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_UPLOAD_2345", status=201, json={"message": "mock message"}, ) @@ -3615,18 +3328,14 @@ def test_creates_anvil_groups(self): self.assertEqual(response.status_code, 302) new_object = models.SignedAgreement.objects.latest("pk") # An access group was created. - self.assertEqual( - new_object.anvil_access_group.name, "TEST_PRIMED_CDSA_ACCESS_2345" - ) + self.assertEqual(new_object.anvil_access_group.name, "TEST_PRIMED_CDSA_ACCESS_2345") self.assertTrue(new_object.anvil_access_group.is_managed_by_app) # An upload group was created. self.assertEqual( new_object.dataaffiliateagreement.anvil_upload_group.name, "TEST_PRIMED_CDSA_UPLOAD_2345", ) - self.assertTrue( - new_object.dataaffiliateagreement.anvil_upload_group.is_managed_by_app - ) + self.assertTrue(new_object.dataaffiliateagreement.anvil_upload_group.is_managed_by_app) # Group-group memberships was created with PRIMED_CC_ADMINS as an admin of the access/uploader group. new_membership_1 = GroupGroupMembership.objects.get( parent_group=new_object.anvil_access_group, child_group=self.cc_admins_group @@ -3698,9 +3407,7 @@ def test_creates_anvil_access_group_different_setting(self): new_object.dataaffiliateagreement.anvil_upload_group.name, "foo_CDSA_UPLOAD_2345", ) - self.assertTrue( - new_object.dataaffiliateagreement.anvil_upload_group.is_managed_by_app - ) + self.assertTrue(new_object.dataaffiliateagreement.anvil_upload_group.is_managed_by_app) @override_settings(ANVIL_CC_ADMINS_GROUP_NAME="foo") def test_creates_anvil_groups_different_setting_cc_admins_group_name(self): @@ -3712,29 +3419,25 @@ def test_creates_anvil_groups_different_setting_cc_admins_group_name(self): study = StudyFactory.create() self.anvil_response_mock.add( responses.POST, - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_2345", + self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_2345", status=201, json={"message": "mock message"}, ) self.anvil_response_mock.add( responses.POST, - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_UPLOAD_2345", + self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_UPLOAD_2345", status=201, json={"message": "mock message"}, ) # CC admins group membership. self.anvil_response_mock.add( responses.PUT, - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_2345/admin/foo@firecloud.org", + self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_2345/admin/foo@firecloud.org", status=204, ) self.anvil_response_mock.add( responses.PUT, - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_UPLOAD_2345/admin/foo@firecloud.org", + self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_UPLOAD_2345/admin/foo@firecloud.org", status=204, ) response = self.client.post( @@ -3776,8 +3479,7 @@ def test_access_group_create_api_error(self): # API response to create the associated anvil_access_group. self.anvil_response_mock.add( responses.POST, - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1", + self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1", status=500, json={"message": "other error"}, ) @@ -3822,8 +3524,7 @@ def test_upload_group_create_api_error(self): # API response to create the associated anvil_access_group. self.anvil_response_mock.add( responses.POST, - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1", + self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1", status=201, json={"message": "mock message"}, ) @@ -3836,8 +3537,7 @@ def test_upload_group_create_api_error(self): ) self.anvil_response_mock.add( responses.POST, - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_UPLOAD_1", + self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_UPLOAD_1", status=500, json={"message": "other error"}, ) @@ -3905,9 +3605,7 @@ def test_access_group_already_exists_in_app(self): # ...but there was an error with the group name. messages = list(response.context["messages"]) self.assertEqual(len(messages), 1) - self.assertEqual( - views.DataAffiliateAgreementCreate.ERROR_CREATING_GROUP, str(messages[0]) - ) + self.assertEqual(views.DataAffiliateAgreementCreate.ERROR_CREATING_GROUP, str(messages[0])) self.assertEqual(models.SignedAgreement.objects.count(), 0) def test_upload_group_already_exists_in_app(self): @@ -3942,9 +3640,7 @@ def test_upload_group_already_exists_in_app(self): # ...but there was an error with the group name. messages = list(response.context["messages"]) self.assertEqual(len(messages), 1) - self.assertEqual( - views.DataAffiliateAgreementCreate.ERROR_CREATING_GROUP, str(messages[0]) - ) + self.assertEqual(views.DataAffiliateAgreementCreate.ERROR_CREATING_GROUP, str(messages[0])) self.assertEqual(models.SignedAgreement.objects.count(), 0) def test_admin_group_membership_access_api_error(self): @@ -3956,8 +3652,7 @@ def test_admin_group_membership_access_api_error(self): # API response to create the associated anvil_access_group. self.anvil_response_mock.add( responses.POST, - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1234", + self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1234", status=201, json={"message": "mock message"}, ) @@ -4022,15 +3717,13 @@ def test_admin_group_membership_upload_api_error(self): # API response to create the associated anvil_access_group. self.anvil_response_mock.add( responses.POST, - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1234", + self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1234", status=201, json={"message": "mock message"}, ) self.anvil_response_mock.add( responses.POST, - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_UPLOAD_1234", + self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_UPLOAD_1234", status=201, json={"message": "mock message"}, ) @@ -4089,9 +3782,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) # Create an object test this with. self.obj = factories.DataAffiliateAgreementFactory.create() @@ -4121,9 +3812,7 @@ def test_status_code_with_user_permission(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url(1)) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -4147,9 +3836,7 @@ def test_response_includes_link_to_user_profile(self): """Response includes a link to the user profile page.""" self.client.force_login(self.user) response = self.client.get(self.get_url(self.obj.signed_agreement.cc_id)) - self.assertContains( - response, self.obj.signed_agreement.representative.get_absolute_url() - ) + self.assertContains(response, self.obj.signed_agreement.representative.get_absolute_url()) def test_response_includes_link_to_study(self): """Response includes a link to the study detail page.""" @@ -4161,9 +3848,7 @@ def test_response_includes_link_to_anvil_access_group(self): """Response includes a link to the AnVIL access group detail page.""" self.client.force_login(self.user) response = self.client.get(self.get_url(self.obj.signed_agreement.cc_id)) - self.assertContains( - response, self.obj.signed_agreement.anvil_access_group.get_absolute_url() - ) + self.assertContains(response, self.obj.signed_agreement.anvil_access_group.get_absolute_url()) def test_response_includes_link_to_anvil_upload_group(self): """Response includes a link to the AnVIL access group detail page.""" @@ -4195,14 +3880,10 @@ def test_change_status_button_user_has_edit_perm(self): """Invalidate button appears when the user has edit permission and the instance is valid.""" user = User.objects.create_user(username="test_edit", password="test_edit") user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) self.client.force_login(user) response = self.client.get(self.get_url(self.obj.signed_agreement.cc_id)) @@ -4241,9 +3922,7 @@ def test_response_includes_additional_limitations(self): self.client.force_login(self.user) response = self.client.get(self.get_url(instance.signed_agreement.cc_id)) self.assertContains(response, "Additional limitations") - self.assertContains( - response, "Test limitations for this data affiliate agreement" - ) + self.assertContains(response, "Test limitations for this data affiliate agreement") def test_response_with_no_additional_limitations(self): """Response includes a link to the study detail page.""" @@ -4280,9 +3959,7 @@ def test_response_is_primary(self): def test_response_requires_study_review(self): """Response includes info about requires_study_review.""" - instance = factories.DataAffiliateAgreementFactory.create( - is_primary=True, requires_study_review=True - ) + instance = factories.DataAffiliateAgreementFactory.create(is_primary=True, requires_study_review=True) self.client.force_login(self.user) response = self.client.get(self.get_url(instance.signed_agreement.cc_id)) self.assertContains(response, "Study review required?") @@ -4312,9 +3989,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -4342,9 +4017,7 @@ def test_status_code_with_user_permission(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url()) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -4355,9 +4028,7 @@ def test_table_class(self): self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertIn("table", response.context_data) - self.assertIsInstance( - response.context_data["table"], tables.DataAffiliateAgreementTable - ) + self.assertIsInstance(response.context_data["table"], tables.DataAffiliateAgreementTable) def test_workspace_table_none(self): """No rows are shown if there are no DataAffiliateAgreement objects.""" @@ -4385,14 +4056,10 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) # Create the admins group. self.cc_admins_group = ManagedGroupFactory.create(name="TEST_PRIMED_CC_ADMINS") @@ -4409,9 +4076,7 @@ def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." # Need a client for redirects. response = self.client.get(self.get_url()) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url() - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url()) def test_status_code_with_user_permission_edit(self): """Returns successful response code.""" @@ -4421,9 +4086,7 @@ def test_status_code_with_user_permission_edit(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url()) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -4431,13 +4094,9 @@ def test_access_without_user_permission(self): def test_access_without_user_permission_view(self): """Raises permission denied if user has only view permission.""" - user_view_perm = User.objects.create_user( - username="test-none", password="test-none" - ) + user_view_perm = User.objects.create_user(username="test-none", password="test-none") user_view_perm.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user_view_perm @@ -4469,8 +4128,7 @@ def test_can_create_object(self): # API response to create the associated anvil_access_group. self.anvil_response_mock.add( responses.POST, - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1234", + self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1234", status=201, json={"message": "mock message"}, ) @@ -4510,12 +4168,8 @@ def test_can_create_object(self): self.assertEqual(new_agreement.type, new_agreement.NON_DATA_AFFILIATE) # AnVIL group was set correctly. self.assertIsInstance(new_agreement.anvil_access_group, ManagedGroup) - self.assertEqual( - new_agreement.anvil_access_group.name, "TEST_PRIMED_CDSA_ACCESS_1234" - ) - self.assertEqual( - new_agreement.status, models.SignedAgreement.StatusChoices.ACTIVE - ) + self.assertEqual(new_agreement.anvil_access_group.name, "TEST_PRIMED_CDSA_ACCESS_1234") + self.assertEqual(new_agreement.status, models.SignedAgreement.StatusChoices.ACTIVE) # Check the agreement type. self.assertEqual(models.NonDataAffiliateAgreement.objects.count(), 1) new_agreement_type = models.NonDataAffiliateAgreement.objects.latest("pk") @@ -4528,13 +4182,8 @@ def test_redirect_url(self): representative = UserFactory.create() agreement_version = factories.AgreementVersionFactory.create() # API response to create the associated anvil_access_group. - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1234" - ) - self.anvil_response_mock.add( - responses.POST, api_url, status=201, json={"message": "mock message"} - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1234" + self.anvil_response_mock.add(responses.POST, api_url, status=201, json={"message": "mock message"}) # CC admins group membership. self.anvil_response_mock.add( responses.PUT, @@ -4567,13 +4216,8 @@ def test_success_message(self): representative = UserFactory.create() agreement_version = factories.AgreementVersionFactory.create() # API response to create the associated anvil_access_group. - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1234" - ) - self.anvil_response_mock.add( - responses.POST, api_url, status=201, json={"message": "mock message"} - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1234" + self.anvil_response_mock.add(responses.POST, api_url, status=201, json={"message": "mock message"}) # CC admins group membership. self.anvil_response_mock.add( responses.PUT, @@ -4599,9 +4243,7 @@ def test_success_message(self): ) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.NonDataAffiliateAgreementCreate.success_message, str(messages[0]) - ) + self.assertEqual(views.NonDataAffiliateAgreementCreate.success_message, str(messages[0])) def test_error_missing_cc_id(self): """Form shows an error when cc_id is missing.""" @@ -4964,12 +4606,8 @@ def test_error_duplicate_project_id(self): ) self.assertEqual(response.status_code, 200) # No new objects were created. - self.assertEqual( - models.SignedAgreement.objects.count(), 1 - ) # One already existed. - self.assertEqual( - models.NonDataAffiliateAgreement.objects.count(), 1 - ) # One already existed. + self.assertEqual(models.SignedAgreement.objects.count(), 1) # One already existed. + self.assertEqual(models.NonDataAffiliateAgreement.objects.count(), 1) # One already existed. # Form has errors in the correct field. form = response.context_data["form"] self.assertFalse(form.is_valid()) @@ -4991,13 +4629,8 @@ def test_creates_anvil_access_group(self): self.client.force_login(self.user) representative = UserFactory.create() agreement_version = factories.AgreementVersionFactory.create() - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_2345" - ) - self.anvil_response_mock.add( - responses.POST, api_url, status=201, json={"message": "mock message"} - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_2345" + self.anvil_response_mock.add(responses.POST, api_url, status=201, json={"message": "mock message"}) # CC admins group membership. self.anvil_response_mock.add( responses.PUT, @@ -5041,12 +4674,8 @@ def test_creates_anvil_groups_different_setting(self): self.client.force_login(self.user) representative = UserFactory.create() agreement_version = factories.AgreementVersionFactory.create() - api_url = ( - self.api_client.sam_entry_point + "/api/groups/v1/foo_CDSA_ACCESS_2345" - ) - self.anvil_response_mock.add( - responses.POST, api_url, status=201, json={"message": "mock message"} - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/foo_CDSA_ACCESS_2345" + self.anvil_response_mock.add(responses.POST, api_url, status=201, json={"message": "mock message"}) # CC admins group membership. self.anvil_response_mock.add( responses.PUT, @@ -5086,18 +4715,12 @@ def test_creates_anvil_groups_different_setting_cc_admins_group_name(self): self.client.force_login(self.user) representative = UserFactory.create() agreement_version = factories.AgreementVersionFactory.create() - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_2345" - ) - self.anvil_response_mock.add( - responses.POST, api_url, status=201, json={"message": "mock message"} - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_2345" + self.anvil_response_mock.add(responses.POST, api_url, status=201, json={"message": "mock message"}) # CC admins group membership. self.anvil_response_mock.add( responses.PUT, - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_2345/admin/foo@firecloud.org", + self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_2345/admin/foo@firecloud.org", status=204, ) response = self.client.post( @@ -5130,12 +4753,8 @@ def test_manage_group_create_api_error(self): representative = UserFactory.create() agreement_version = factories.AgreementVersionFactory.create() # API response to create the associated anvil_access_group. - api_url = ( - self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1" - ) - self.anvil_response_mock.add( - responses.POST, api_url, status=500, json={"message": "other error"} - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_CDSA_ACCESS_1" + self.anvil_response_mock.add(responses.POST, api_url, status=500, json={"message": "other error"}) response = self.client.post( self.get_url(), { @@ -5197,9 +4816,7 @@ def test_managed_group_already_exists_in_app(self): # ...but there was an error with the group name. messages = list(response.context["messages"]) self.assertEqual(len(messages), 1) - self.assertEqual( - views.NonDataAffiliateAgreementCreate.ERROR_CREATING_GROUP, str(messages[0]) - ) + self.assertEqual(views.NonDataAffiliateAgreementCreate.ERROR_CREATING_GROUP, str(messages[0])) # No dbGaPApplication was created. self.assertEqual(models.SignedAgreement.objects.count(), 0) @@ -5213,9 +4830,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) # Create an object test this with. self.obj = factories.NonDataAffiliateAgreementFactory.create() @@ -5245,9 +4860,7 @@ def test_status_code_with_user_permission(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url(1)) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -5271,17 +4884,13 @@ def test_response_includes_link_to_user_profile(self): """Response includes a link to the user profile page.""" self.client.force_login(self.user) response = self.client.get(self.get_url(self.obj.signed_agreement.cc_id)) - self.assertContains( - response, self.obj.signed_agreement.representative.get_absolute_url() - ) + self.assertContains(response, self.obj.signed_agreement.representative.get_absolute_url()) def test_response_includes_link_to_anvil_access_group(self): """Response includes a link to the AnVIL access group detail page.""" self.client.force_login(self.user) response = self.client.get(self.get_url(self.obj.signed_agreement.cc_id)) - self.assertContains( - response, self.obj.signed_agreement.anvil_access_group.get_absolute_url() - ) + self.assertContains(response, self.obj.signed_agreement.anvil_access_group.get_absolute_url()) def test_response_show_deprecation_message_valid(self): """response context does not show a deprecation warning when AgreementMajorVersion is valid.""" @@ -5307,14 +4916,10 @@ def test_change_status_button_user_has_edit_perm(self): """Invalidate button appears when the user has edit permission and the instance is valid.""" user = User.objects.create_user(username="test_edit", password="test_edit") user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) self.client.force_login(user) response = self.client.get(self.get_url(self.obj.signed_agreement.cc_id)) @@ -5354,9 +4959,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -5384,9 +4987,7 @@ def test_status_code_with_user_permission(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url()) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -5397,9 +4998,7 @@ def test_table_class(self): self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertIn("table", response.context_data) - self.assertIsInstance( - response.context_data["table"], tables.NonDataAffiliateAgreementTable - ) + self.assertIsInstance(response.context_data["table"], tables.NonDataAffiliateAgreementTable) def test_workspace_table_none(self): """No rows are shown if there are no NonDataAffiliateAgreement objects.""" @@ -5482,9 +5081,7 @@ def test_table_class(self): self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertIn("table", response.context_data) - self.assertIsInstance( - response.context_data["table"], tables.RepresentativeRecordsTable - ) + self.assertIsInstance(response.context_data["table"], tables.RepresentativeRecordsTable) def test_table_no_rows(self): """No rows are shown if there are no SignedAgreement objects.""" @@ -5534,9 +5131,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) # Create the test group. self.anvil_cdsa_group = ManagedGroupFactory.create(name="TEST_PRIMED_CDSA") @@ -5569,9 +5164,7 @@ def test_status_code_with_user_permission_view(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url()) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -5712,14 +5305,10 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) # Create the test group. self.anvil_cdsa_group = ManagedGroupFactory.create(name="TEST_PRIMED_CDSA") @@ -5745,9 +5334,7 @@ def test_status_code_with_user_permission_view(self): """Returns forbidden response code if the user only has view permission.""" user_view = User.objects.create_user(username="test-view", password="test-view") user_view.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url(1)) request.user = user_view @@ -5756,9 +5343,7 @@ def test_status_code_with_user_permission_view(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url(1)) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -5773,9 +5358,7 @@ def test_get_context_data_access_audit(self): """The data_access_audit exists in the context.""" member_agreement = factories.MemberAgreementFactory.create() self.client.force_login(self.user) - response = self.client.get( - self.get_url(member_agreement.signed_agreement.cc_id) - ) + response = self.client.get(self.get_url(member_agreement.signed_agreement.cc_id)) self.assertIn("audit_result", response.context_data) self.assertIsInstance( response.context_data["audit_result"], @@ -5791,9 +5374,7 @@ def test_get_context_verified_access(self): ) # Check the audit_result in the context. self.client.force_login(self.user) - response = self.client.get( - self.get_url(member_agreement.signed_agreement.cc_id) - ) + response = self.client.get(self.get_url(member_agreement.signed_agreement.cc_id)) self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] self.assertIsInstance(audit_result, signed_agreement_audit.VerifiedAccess) @@ -5811,9 +5392,7 @@ def test_get_context_verified_no_access(self): # ) # Check the audit_result in the context. self.client.force_login(self.user) - response = self.client.get( - self.get_url(member_agreement.signed_agreement.cc_id) - ) + response = self.client.get(self.get_url(member_agreement.signed_agreement.cc_id)) self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] self.assertIsInstance(audit_result, signed_agreement_audit.VerifiedNoAccess) @@ -5831,9 +5410,7 @@ def test_get_context_remove_access(self): ) # Check the audit_result in the context. self.client.force_login(self.user) - response = self.client.get( - self.get_url(member_agreement.signed_agreement.cc_id) - ) + response = self.client.get(self.get_url(member_agreement.signed_agreement.cc_id)) self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] self.assertIsInstance(audit_result, signed_agreement_audit.RemoveAccess) @@ -5849,9 +5426,7 @@ def test_get_context_grant_access(self): # ) # Check the audit_result in the context. self.client.force_login(self.user) - response = self.client.get( - self.get_url(member_agreement.signed_agreement.cc_id) - ) + response = self.client.get(self.get_url(member_agreement.signed_agreement.cc_id)) self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] self.assertIsInstance(audit_result, signed_agreement_audit.GrantAccess) @@ -5869,9 +5444,7 @@ def test_post_context_verified_access(self): ) # Check the response. self.client.force_login(self.user) - response = self.client.post( - self.get_url(member_agreement.signed_agreement.cc_id), {} - ) + response = self.client.post(self.get_url(member_agreement.signed_agreement.cc_id), {}) self.assertRedirects(response, member_agreement.get_absolute_url()) # Make sure the membership hasn't changed. membership.refresh_from_db() @@ -5888,9 +5461,7 @@ def test_post_context_verified_no_access(self): # ) # Check the response. self.client.force_login(self.user) - response = self.client.post( - self.get_url(member_agreement.signed_agreement.cc_id), {} - ) + response = self.client.post(self.get_url(member_agreement.signed_agreement.cc_id), {}) self.assertRedirects(response, member_agreement.get_absolute_url()) self.assertEqual(GroupGroupMembership.objects.count(), 0) @@ -5916,9 +5487,7 @@ def test_post_context_remove_access(self): ) # Check the response. self.client.force_login(self.user) - response = self.client.post( - self.get_url(member_agreement.signed_agreement.cc_id), {} - ) + response = self.client.post(self.get_url(member_agreement.signed_agreement.cc_id), {}) self.assertRedirects(response, member_agreement.get_absolute_url()) # Make sure the membership hasn't changed. with self.assertRaises(GroupGroupMembership.DoesNotExist): @@ -5947,21 +5516,15 @@ def test_post_htmx_context_remove_access(self): # Check the response. self.client.force_login(self.user) header = {"HTTP_HX-Request": "true"} - response = self.client.post( - self.get_url(member_agreement.signed_agreement.cc_id), {}, **header - ) - self.assertEqual( - response.content.decode(), views.SignedAgreementAuditResolve.htmx_success - ) + response = self.client.post(self.get_url(member_agreement.signed_agreement.cc_id), {}, **header) + self.assertEqual(response.content.decode(), views.SignedAgreementAuditResolve.htmx_success) # Make sure the membership hasn't changed. with self.assertRaises(GroupGroupMembership.DoesNotExist): membership.refresh_from_db() def test_post_context_grant_access(self): """Context with GrantAccess.""" - member_agreement = factories.MemberAgreementFactory.create( - signed_agreement__cc_id=2345 - ) + member_agreement = factories.MemberAgreementFactory.create(signed_agreement__cc_id=2345) # GroupGroupMembershipFactory.create( # parent_group=self.anvil_cdsa_group, # child_group=member_agreement.signed_agreement.anvil_access_group, @@ -5978,9 +5541,7 @@ def test_post_context_grant_access(self): ) # Check the response. self.client.force_login(self.user) - response = self.client.post( - self.get_url(member_agreement.signed_agreement.cc_id), {} - ) + response = self.client.post(self.get_url(member_agreement.signed_agreement.cc_id), {}) self.assertRedirects(response, member_agreement.get_absolute_url()) membership = GroupGroupMembership.objects.get( parent_group=self.anvil_cdsa_group, @@ -5990,9 +5551,7 @@ def test_post_context_grant_access(self): def test_post_htmx_grant_access(self): """Context with GrantAccess.""" - member_agreement = factories.MemberAgreementFactory.create( - signed_agreement__cc_id=2345 - ) + member_agreement = factories.MemberAgreementFactory.create(signed_agreement__cc_id=2345) # GroupGroupMembershipFactory.create( # parent_group=self.anvil_cdsa_group, # child_group=member_agreement.signed_agreement.anvil_access_group, @@ -6010,12 +5569,8 @@ def test_post_htmx_grant_access(self): # Check the response. self.client.force_login(self.user) header = {"HTTP_HX-Request": "true"} - response = self.client.post( - self.get_url(member_agreement.signed_agreement.cc_id), {}, **header - ) - self.assertEqual( - response.content.decode(), views.SignedAgreementAuditResolve.htmx_success - ) + response = self.client.post(self.get_url(member_agreement.signed_agreement.cc_id), {}, **header) + self.assertEqual(response.content.decode(), views.SignedAgreementAuditResolve.htmx_success) membership = GroupGroupMembership.objects.get( parent_group=self.anvil_cdsa_group, child_group=member_agreement.signed_agreement.anvil_access_group, @@ -6027,9 +5582,7 @@ def test_get_only_this_signed_agreement(self): factories.MemberAgreementFactory.create(signed_agreement__cc_id=1234) member_agreement = factories.MemberAgreementFactory.create() self.client.force_login(self.user) - response = self.client.get( - self.get_url(member_agreement.signed_agreement.cc_id) - ) + response = self.client.get(self.get_url(member_agreement.signed_agreement.cc_id)) self.assertIn("audit_result", response.context_data) self.assertIsInstance( response.context_data["audit_result"], @@ -6043,9 +5596,7 @@ def test_get_only_this_signed_agreement(self): def test_post_only_this_signed_agreement(self): """Only runs on the specified signed_agreement.""" factories.MemberAgreementFactory.create(signed_agreement__cc_id=1234) - member_agreement = factories.MemberAgreementFactory.create( - signed_agreement__cc_id=2345 - ) + member_agreement = factories.MemberAgreementFactory.create(signed_agreement__cc_id=2345) # GroupGroupMembershipFactory.create( # parent_group=self.anvil_cdsa_group, # child_group=member_agreement.signed_agreement.anvil_access_group, @@ -6062,9 +5613,7 @@ def test_post_only_this_signed_agreement(self): ) # Check the response. self.client.force_login(self.user) - response = self.client.post( - self.get_url(member_agreement.signed_agreement.cc_id), {} - ) + response = self.client.post(self.get_url(member_agreement.signed_agreement.cc_id), {}) self.assertRedirects(response, member_agreement.get_absolute_url()) membership = GroupGroupMembership.objects.get( parent_group=self.anvil_cdsa_group, @@ -6074,9 +5623,7 @@ def test_post_only_this_signed_agreement(self): def test_anvil_api_error_grant(self): """AnVIL API errors are properly handled.""" - member_agreement = factories.MemberAgreementFactory.create( - signed_agreement__cc_id=2345 - ) + member_agreement = factories.MemberAgreementFactory.create(signed_agreement__cc_id=2345) # GroupGroupMembershipFactory.create( # parent_group=self.anvil_cdsa_group, # child_group=member_agreement.signed_agreement.anvil_access_group, @@ -6094,9 +5641,7 @@ def test_anvil_api_error_grant(self): ) # Check the response. self.client.force_login(self.user) - response = self.client.post( - self.get_url(member_agreement.signed_agreement.cc_id), {} - ) + response = self.client.post(self.get_url(member_agreement.signed_agreement.cc_id), {}) self.assertEqual(response.status_code, 200) # No group membership was created. self.assertEqual(GroupGroupMembership.objects.count(), 0) @@ -6111,9 +5656,7 @@ def test_anvil_api_error_grant(self): def test_anvil_api_error_grant_htmx(self): """AnVIL API errors are properly handled.""" - member_agreement = factories.MemberAgreementFactory.create( - signed_agreement__cc_id=2345 - ) + member_agreement = factories.MemberAgreementFactory.create(signed_agreement__cc_id=2345) # GroupGroupMembershipFactory.create( # parent_group=self.anvil_cdsa_group, # child_group=member_agreement.signed_agreement.anvil_access_group, @@ -6132,12 +5675,8 @@ def test_anvil_api_error_grant_htmx(self): # Check the response. self.client.force_login(self.user) header = {"HTTP_HX-Request": "true"} - response = self.client.post( - self.get_url(member_agreement.signed_agreement.cc_id), {}, **header - ) - self.assertEqual( - response.content.decode(), views.SignedAgreementAuditResolve.htmx_error - ) + response = self.client.post(self.get_url(member_agreement.signed_agreement.cc_id), {}, **header) + self.assertEqual(response.content.decode(), views.SignedAgreementAuditResolve.htmx_error) # No group membership was created. self.assertEqual(GroupGroupMembership.objects.count(), 0) # No messages waere added. @@ -6167,9 +5706,7 @@ def test_anvil_api_error_remove(self): ) # Check the response. self.client.force_login(self.user) - response = self.client.post( - self.get_url(member_agreement.signed_agreement.cc_id), {} - ) + response = self.client.post(self.get_url(member_agreement.signed_agreement.cc_id), {}) self.assertEqual(response.status_code, 200) # The group-group membership still exists. membership.refresh_from_db() @@ -6206,12 +5743,8 @@ def test_anvil_api_error_remove_htmx(self): # Check the response. self.client.force_login(self.user) header = {"HTTP_HX-Request": "true"} - response = self.client.post( - self.get_url(member_agreement.signed_agreement.cc_id), {}, **header - ) - self.assertEqual( - response.content.decode(), views.SignedAgreementAuditResolve.htmx_error - ) + response = self.client.post(self.get_url(member_agreement.signed_agreement.cc_id), {}, **header) + self.assertEqual(response.content.decode(), views.SignedAgreementAuditResolve.htmx_error) # The group-group membership still exists. membership.refresh_from_db() # No messages was added. @@ -6222,17 +5755,14 @@ def test_anvil_api_error_remove_htmx(self): def test_anvil_cdsa_group_does_not_exist(self): """Settings file has a different CDSA group name.""" cdsa_group = ManagedGroupFactory.create(name="FOOBAR") - member_agreement = factories.MemberAgreementFactory.create( - signed_agreement__cc_id=2345 - ) + member_agreement = factories.MemberAgreementFactory.create(signed_agreement__cc_id=2345) # GroupGroupMembershipFactory.create( # parent_group=self.anvil_cdsa_group, # child_group=member_agreement.signed_agreement.anvil_access_group, # ) # Add API response api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/FOOBAR/member/TEST_PRIMED_CDSA_ACCESS_2345@firecloud.org" + self.api_client.sam_entry_point + "/api/groups/v1/FOOBAR/member/TEST_PRIMED_CDSA_ACCESS_2345@firecloud.org" ) self.anvil_response_mock.add( responses.PUT, @@ -6241,9 +5771,7 @@ def test_anvil_cdsa_group_does_not_exist(self): ) # Check the response. self.client.force_login(self.user) - response = self.client.post( - self.get_url(member_agreement.signed_agreement.cc_id), {} - ) + response = self.client.post(self.get_url(member_agreement.signed_agreement.cc_id), {}) self.assertRedirects(response, member_agreement.get_absolute_url()) membership = GroupGroupMembership.objects.get( parent_group=cdsa_group, @@ -6261,9 +5789,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.anvil_cdsa_group = ManagedGroupFactory.create(name="TEST_PRIMED_CDSA") @@ -6295,9 +5821,7 @@ def test_status_code_with_user_permission_view(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url()) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -6447,14 +5971,10 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) # Create the test group. self.anvil_cdsa_group = ManagedGroupFactory.create(name="TEST_PRIMED_CDSA") @@ -6480,9 +6000,7 @@ def test_status_code_with_user_permission_view(self): """Returns forbidden response code if the user only has view permission.""" user_view = User.objects.create_user(username="test-view", password="test-view") user_view.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo", "bar")) request.user = user_view @@ -6491,9 +6009,7 @@ def test_status_code_with_user_permission_view(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url("foo", "bar")) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -6508,20 +6024,14 @@ def test_billing_project_does_not_exist(self): def test_workspace_name_does_not_exist(self): cdsa_workspace = factories.CDSAWorkspaceFactory.create() self.client.force_login(self.user) - response = self.client.get( - self.get_url(cdsa_workspace.workspace.billing_project.name, "foo") - ) + response = self.client.get(self.get_url(cdsa_workspace.workspace.billing_project.name, "foo")) self.assertEqual(response.status_code, 404) def test_get_context_audit_result(self): """The data_access_audit exists in the context.""" workspace = factories.CDSAWorkspaceFactory.create() self.client.force_login(self.user) - response = self.client.get( - self.get_url( - workspace.workspace.billing_project.name, workspace.workspace.name - ) - ) + response = self.client.get(self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name)) self.assertIn("audit_result", response.context_data) self.assertIsInstance( response.context_data["audit_result"], @@ -6539,11 +6049,7 @@ def test_get_context_verified_access(self): ) # Check the table in the context. self.client.force_login(self.user) - response = self.client.get( - self.get_url( - workspace.workspace.billing_project.name, workspace.workspace.name - ) - ) + response = self.client.get(self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name)) self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] self.assertIsInstance( @@ -6563,11 +6069,7 @@ def test_get_verified_no_access(self): workspace = factories.CDSAWorkspaceFactory.create() # Check the table in the context. self.client.force_login(self.user) - response = self.client.get( - self.get_url( - workspace.workspace.billing_project.name, workspace.workspace.name - ) - ) + response = self.client.get(self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name)) self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] self.assertIsInstance( @@ -6576,9 +6078,7 @@ def test_get_verified_no_access(self): ) self.assertEqual(audit_result.workspace, workspace) self.assertIsNone(audit_result.data_affiliate_agreement) - self.assertEqual( - audit_result.note, workspace_audit.WorkspaceAccessAudit.NO_PRIMARY_AGREEMENT - ) + self.assertEqual(audit_result.note, workspace_audit.WorkspaceAccessAudit.NO_PRIMARY_AGREEMENT) self.assertIsNone(audit_result.action) def test_get_grant_access(self): @@ -6588,11 +6088,7 @@ def test_get_grant_access(self): workspace = factories.CDSAWorkspaceFactory.create(study=study) # Check the table in the context. self.client.force_login(self.user) - response = self.client.get( - self.get_url( - workspace.workspace.billing_project.name, workspace.workspace.name - ) - ) + response = self.client.get(self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name)) self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] self.assertIsInstance( @@ -6615,19 +6111,13 @@ def test_get_remove_access(self): child_group=self.anvil_cdsa_group, ) self.client.force_login(self.user) - response = self.client.get( - self.get_url( - workspace.workspace.billing_project.name, workspace.workspace.name - ) - ) + response = self.client.get(self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name)) self.assertIn("audit_result", response.context_data) audit_result = response.context_data["audit_result"] self.assertIsInstance(audit_result, workspace_audit.RemoveAccess) self.assertEqual(audit_result.workspace, workspace) self.assertIsNone(audit_result.data_affiliate_agreement) - self.assertEqual( - audit_result.note, workspace_audit.WorkspaceAccessAudit.NO_PRIMARY_AGREEMENT - ) + self.assertEqual(audit_result.note, workspace_audit.WorkspaceAccessAudit.NO_PRIMARY_AGREEMENT) self.assertEqual(audit_result.action, "Remove access") def test_post_verified_access(self): @@ -6644,18 +6134,14 @@ def test_post_verified_access(self): # Check the response self.client.force_login(self.user) response = self.client.post( - self.get_url( - workspace.workspace.billing_project.name, workspace.workspace.name - ), + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name), {}, ) self.assertRedirects(response, workspace.get_absolute_url()) # Make sure the membership hasn't changed. membership.refresh_from_db() self.assertEqual(membership.modified, date_created) - self.assertEqual( - membership.parent_group, workspace.workspace.authorization_domains.first() - ) + self.assertEqual(membership.parent_group, workspace.workspace.authorization_domains.first()) self.assertEqual(membership.child_group, self.anvil_cdsa_group) def test_post_verified_no_access(self): @@ -6669,9 +6155,7 @@ def test_post_verified_no_access(self): # Check the response self.client.force_login(self.user) response = self.client.post( - self.get_url( - workspace.workspace.billing_project.name, workspace.workspace.name - ), + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name), {}, ) self.assertRedirects(response, workspace.get_absolute_url()) @@ -6681,14 +6165,11 @@ def test_post_grant_access(self): """Context with GrantAccess.""" study = StudyFactory.create() factories.DataAffiliateAgreementFactory.create(study=study) - workspace = factories.CDSAWorkspaceFactory.create( - study=study, workspace__name="TEST_CDSA" - ) + workspace = factories.CDSAWorkspaceFactory.create(study=study, workspace__name="TEST_CDSA") # Add API response # Note that the auth domain group is created automatically by the factory using the workspace name. api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/auth_TEST_CDSA/member/TEST_PRIMED_CDSA@firecloud.org" + self.api_client.sam_entry_point + "/api/groups/v1/auth_TEST_CDSA/member/TEST_PRIMED_CDSA@firecloud.org" ) self.anvil_response_mock.add( responses.PUT, @@ -6698,9 +6179,7 @@ def test_post_grant_access(self): # Check the response. self.client.force_login(self.user) response = self.client.post( - self.get_url( - workspace.workspace.billing_project.name, workspace.workspace.name - ), + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name), {}, ) self.assertRedirects(response, workspace.get_absolute_url()) @@ -6714,14 +6193,11 @@ def test_post_grant_access_htmx(self): """Context with GrantAccess.""" study = StudyFactory.create() factories.DataAffiliateAgreementFactory.create(study=study) - workspace = factories.CDSAWorkspaceFactory.create( - study=study, workspace__name="TEST_CDSA" - ) + workspace = factories.CDSAWorkspaceFactory.create(study=study, workspace__name="TEST_CDSA") # Add API response # Note that the auth domain group is created automatically by the factory using the workspace name. api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/auth_TEST_CDSA/member/TEST_PRIMED_CDSA@firecloud.org" + self.api_client.sam_entry_point + "/api/groups/v1/auth_TEST_CDSA/member/TEST_PRIMED_CDSA@firecloud.org" ) self.anvil_response_mock.add( responses.PUT, @@ -6732,15 +6208,9 @@ def test_post_grant_access_htmx(self): self.client.force_login(self.user) header = {"HTTP_HX-Request": "true"} response = self.client.post( - self.get_url( - workspace.workspace.billing_project.name, workspace.workspace.name - ), - {}, - **header - ) - self.assertEqual( - response.content.decode(), views.SignedAgreementAuditResolve.htmx_success + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name), {}, **header ) + self.assertEqual(response.content.decode(), views.SignedAgreementAuditResolve.htmx_success) # Membership has been created. membership = GroupGroupMembership.objects.get( parent_group=workspace.workspace.authorization_domains.first(), @@ -6750,17 +6220,14 @@ def test_post_grant_access_htmx(self): def test_post_remove_access(self): """Get request with RemoveAccess audit result.""" - workspace = factories.CDSAWorkspaceFactory.create( - workspace__name="TEST_WORKSPACE" - ) + workspace = factories.CDSAWorkspaceFactory.create(workspace__name="TEST_WORKSPACE") membership = GroupGroupMembershipFactory.create( parent_group=workspace.workspace.authorization_domains.first(), child_group=self.anvil_cdsa_group, ) # Add API response api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/auth_TEST_WORKSPACE/member/TEST_PRIMED_CDSA@firecloud.org" + self.api_client.sam_entry_point + "/api/groups/v1/auth_TEST_WORKSPACE/member/TEST_PRIMED_CDSA@firecloud.org" ) self.anvil_response_mock.add( responses.DELETE, @@ -6769,9 +6236,7 @@ def test_post_remove_access(self): ) self.client.force_login(self.user) response = self.client.post( - self.get_url( - workspace.workspace.billing_project.name, workspace.workspace.name - ), + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name), {}, ) self.assertRedirects(response, workspace.get_absolute_url()) @@ -6781,17 +6246,14 @@ def test_post_remove_access(self): def test_post_htmx_remove_access_htmx(self): """HTMX post request with RemoveAccess audit result.""" - workspace = factories.CDSAWorkspaceFactory.create( - workspace__name="TEST_WORKSPACE" - ) + workspace = factories.CDSAWorkspaceFactory.create(workspace__name="TEST_WORKSPACE") membership = GroupGroupMembershipFactory.create( parent_group=workspace.workspace.authorization_domains.first(), child_group=self.anvil_cdsa_group, ) # Add API response api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/auth_TEST_WORKSPACE/member/TEST_PRIMED_CDSA@firecloud.org" + self.api_client.sam_entry_point + "/api/groups/v1/auth_TEST_WORKSPACE/member/TEST_PRIMED_CDSA@firecloud.org" ) self.anvil_response_mock.add( responses.DELETE, @@ -6801,15 +6263,9 @@ def test_post_htmx_remove_access_htmx(self): self.client.force_login(self.user) header = {"HTTP_HX-Request": "true"} response = self.client.post( - self.get_url( - workspace.workspace.billing_project.name, workspace.workspace.name - ), - {}, - **header - ) - self.assertEqual( - response.content.decode(), views.CDSAWorkspaceAuditResolve.htmx_success + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name), {}, **header ) + self.assertEqual(response.content.decode(), views.CDSAWorkspaceAuditResolve.htmx_success) # Make sure the membership has been deleted. with self.assertRaises(GroupGroupMembership.DoesNotExist): membership.refresh_from_db() @@ -6819,11 +6275,7 @@ def test_get_only_this_workspace(self): factories.CDSAWorkspaceFactory.create() workspace = factories.CDSAWorkspaceFactory.create() self.client.force_login(self.user) - response = self.client.get( - self.get_url( - workspace.workspace.billing_project.name, workspace.workspace.name - ) - ) + response = self.client.get(self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name)) self.assertIn("audit_result", response.context_data) self.assertIsInstance( response.context_data["audit_result"], @@ -6835,14 +6287,11 @@ def test_anvil_api_error_grant(self): """AnVIL API errors are properly handled.""" study = StudyFactory.create() factories.DataAffiliateAgreementFactory.create(study=study) - workspace = factories.CDSAWorkspaceFactory.create( - study=study, workspace__name="TEST_CDSA" - ) + workspace = factories.CDSAWorkspaceFactory.create(study=study, workspace__name="TEST_CDSA") # Add API response # Note that the auth domain group is created automatically by the factory using the workspace name. api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/auth_TEST_CDSA/member/TEST_PRIMED_CDSA@firecloud.org" + self.api_client.sam_entry_point + "/api/groups/v1/auth_TEST_CDSA/member/TEST_PRIMED_CDSA@firecloud.org" ) self.anvil_response_mock.add( responses.PUT, @@ -6853,9 +6302,7 @@ def test_anvil_api_error_grant(self): # Check the response. self.client.force_login(self.user) response = self.client.post( - self.get_url( - workspace.workspace.billing_project.name, workspace.workspace.name - ), + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name), {}, ) self.assertEqual(response.status_code, 200) @@ -6874,14 +6321,11 @@ def test_anvil_api_error_grant_htmx(self): """AnVIL API errors are properly handled with htmx.""" study = StudyFactory.create() factories.DataAffiliateAgreementFactory.create(study=study) - workspace = factories.CDSAWorkspaceFactory.create( - study=study, workspace__name="TEST_CDSA" - ) + workspace = factories.CDSAWorkspaceFactory.create(study=study, workspace__name="TEST_CDSA") # Add API response # Note that the auth domain group is created automatically by the factory using the workspace name. api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/auth_TEST_CDSA/member/TEST_PRIMED_CDSA@firecloud.org" + self.api_client.sam_entry_point + "/api/groups/v1/auth_TEST_CDSA/member/TEST_PRIMED_CDSA@firecloud.org" ) self.anvil_response_mock.add( responses.PUT, @@ -6893,15 +6337,9 @@ def test_anvil_api_error_grant_htmx(self): self.client.force_login(self.user) header = {"HTTP_HX-Request": "true"} response = self.client.post( - self.get_url( - workspace.workspace.billing_project.name, workspace.workspace.name - ), - {}, - **header - ) - self.assertEqual( - response.content.decode(), views.SignedAgreementAuditResolve.htmx_error + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name), {}, **header ) + self.assertEqual(response.content.decode(), views.SignedAgreementAuditResolve.htmx_error) # No group membership was created. self.assertEqual(GroupGroupMembership.objects.count(), 0) # No messages were added. @@ -6910,17 +6348,14 @@ def test_anvil_api_error_grant_htmx(self): def test_anvil_api_error_remove(self): """AnVIL API errors are properly handled.""" - workspace = factories.CDSAWorkspaceFactory.create( - workspace__name="TEST_WORKSPACE" - ) + workspace = factories.CDSAWorkspaceFactory.create(workspace__name="TEST_WORKSPACE") membership = GroupGroupMembershipFactory.create( parent_group=workspace.workspace.authorization_domains.first(), child_group=self.anvil_cdsa_group, ) # Add API response api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/auth_TEST_WORKSPACE/member/TEST_PRIMED_CDSA@firecloud.org" + self.api_client.sam_entry_point + "/api/groups/v1/auth_TEST_WORKSPACE/member/TEST_PRIMED_CDSA@firecloud.org" ) self.anvil_response_mock.add( responses.DELETE, @@ -6930,9 +6365,7 @@ def test_anvil_api_error_remove(self): ) self.client.force_login(self.user) response = self.client.post( - self.get_url( - workspace.workspace.billing_project.name, workspace.workspace.name - ), + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name), {}, ) self.assertEqual(response.status_code, 200) @@ -6949,17 +6382,14 @@ def test_anvil_api_error_remove(self): def test_anvil_api_error_remove_htmx(self): """AnVIL API errors are properly handled.""" - workspace = factories.CDSAWorkspaceFactory.create( - workspace__name="TEST_WORKSPACE" - ) + workspace = factories.CDSAWorkspaceFactory.create(workspace__name="TEST_WORKSPACE") membership = GroupGroupMembershipFactory.create( parent_group=workspace.workspace.authorization_domains.first(), child_group=self.anvil_cdsa_group, ) # Add API response api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/auth_TEST_WORKSPACE/member/TEST_PRIMED_CDSA@firecloud.org" + self.api_client.sam_entry_point + "/api/groups/v1/auth_TEST_WORKSPACE/member/TEST_PRIMED_CDSA@firecloud.org" ) self.anvil_response_mock.add( responses.DELETE, @@ -6970,15 +6400,9 @@ def test_anvil_api_error_remove_htmx(self): self.client.force_login(self.user) header = {"HTTP_HX-Request": "true"} response = self.client.post( - self.get_url( - workspace.workspace.billing_project.name, workspace.workspace.name - ), - {}, - **header - ) - self.assertEqual( - response.content.decode(), views.SignedAgreementAuditResolve.htmx_error + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name), {}, **header ) + self.assertEqual(response.content.decode(), views.SignedAgreementAuditResolve.htmx_error) # The group-group membership still exists. membership.refresh_from_db() # No messages was added. @@ -6991,15 +6415,10 @@ def test_different_cdsa_group_name(self): cdsa_group = ManagedGroupFactory.create(name="FOOBAR") study = StudyFactory.create() factories.DataAffiliateAgreementFactory.create(study=study) - workspace = factories.CDSAWorkspaceFactory.create( - study=study, workspace__name="TEST_CDSA" - ) + workspace = factories.CDSAWorkspaceFactory.create(study=study, workspace__name="TEST_CDSA") # Add API response # Note that the auth domain group is created automatically by the factory using the workspace name. - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/auth_TEST_CDSA/member/FOOBAR@firecloud.org" - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/auth_TEST_CDSA/member/FOOBAR@firecloud.org" self.anvil_response_mock.add( responses.PUT, api_url, @@ -7008,9 +6427,7 @@ def test_different_cdsa_group_name(self): # Check the response. self.client.force_login(self.user) response = self.client.post( - self.get_url( - workspace.workspace.billing_project.name, workspace.workspace.name - ), + self.get_url(workspace.workspace.billing_project.name, workspace.workspace.name), {}, ) self.assertRedirects(response, workspace.get_absolute_url()) @@ -7070,12 +6487,8 @@ def test_table_three_rows(self): def test_only_shows_data_affiliate_records(self): member_agreement = factories.MemberAgreementFactory.create(is_primary=True) - data_affiliate_agreement = factories.DataAffiliateAgreementFactory.create( - is_primary=True - ) - non_data_affiliate_agreement = ( - factories.NonDataAffiliateAgreementFactory.create() - ) + data_affiliate_agreement = factories.DataAffiliateAgreementFactory.create(is_primary=True) + non_data_affiliate_agreement = factories.NonDataAffiliateAgreementFactory.create() self.client.force_login(self.user) response = self.client.get(self.get_url()) table = response.context_data["table"] @@ -7085,12 +6498,8 @@ def test_only_shows_data_affiliate_records(self): self.assertNotIn(non_data_affiliate_agreement, table.data) def test_only_shows_primary_data_affiliate_records(self): - primary_agreement = factories.DataAffiliateAgreementFactory.create( - is_primary=True - ) - component_agreement = factories.DataAffiliateAgreementFactory.create( - is_primary=False - ) + primary_agreement = factories.DataAffiliateAgreementFactory.create(is_primary=True) + component_agreement = factories.DataAffiliateAgreementFactory.create(is_primary=False) self.client.force_login(self.user) response = self.client.get(self.get_url()) table = response.context_data["table"] @@ -7150,9 +6559,7 @@ def test_table_class(self): self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertIn("table", response.context_data) - self.assertIsInstance( - response.context_data["table"], tables.UserAccessRecordsTable - ) + self.assertIsInstance(response.context_data["table"], tables.UserAccessRecordsTable) def test_table_no_rows(self): """No rows are shown if there are no users in CDSA access groups.""" @@ -7172,9 +6579,7 @@ def test_table_one_agreement_no_members(self): def test_table_one_agreement_one_member(self): """One row is shown if there is one agreement and one account group member.""" agreement = factories.MemberAgreementFactory.create(is_primary=True) - GroupAccountMembershipFactory.create( - group=agreement.signed_agreement.anvil_access_group - ) + GroupAccountMembershipFactory.create(group=agreement.signed_agreement.anvil_access_group) self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertIn("table", response.context_data) @@ -7183,9 +6588,7 @@ def test_table_one_agreement_one_member(self): def test_table_one_agreements_two_members(self): """Two rows are shown if there is one agreement with two account group members.""" agreement = factories.MemberAgreementFactory.create(is_primary=True) - GroupAccountMembershipFactory.create_batch( - 2, group=agreement.signed_agreement.anvil_access_group - ) + GroupAccountMembershipFactory.create_batch(2, group=agreement.signed_agreement.anvil_access_group) self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertIn("table", response.context_data) @@ -7194,13 +6597,9 @@ def test_table_one_agreements_two_members(self): def test_table_two_agreements(self): """Multiple rows is shown if there are two agreements and multiple account group members.""" agreement_1 = factories.MemberAgreementFactory.create(is_primary=True) - GroupAccountMembershipFactory.create_batch( - 2, group=agreement_1.signed_agreement.anvil_access_group - ) + GroupAccountMembershipFactory.create_batch(2, group=agreement_1.signed_agreement.anvil_access_group) agreement_2 = factories.MemberAgreementFactory.create(is_primary=True) - GroupAccountMembershipFactory.create_batch( - 3, group=agreement_2.signed_agreement.anvil_access_group - ) + GroupAccountMembershipFactory.create_batch(3, group=agreement_2.signed_agreement.anvil_access_group) self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertIn("table", response.context_data) @@ -7208,17 +6607,11 @@ def test_table_two_agreements(self): def test_only_shows_records_for_all_agreement_types(self): agreement_1 = factories.MemberAgreementFactory.create(is_primary=True) - GroupAccountMembershipFactory.create( - group=agreement_1.signed_agreement.anvil_access_group - ) + GroupAccountMembershipFactory.create(group=agreement_1.signed_agreement.anvil_access_group) agreement_2 = factories.DataAffiliateAgreementFactory.create(is_primary=True) - GroupAccountMembershipFactory.create( - group=agreement_2.signed_agreement.anvil_access_group - ) + GroupAccountMembershipFactory.create(group=agreement_2.signed_agreement.anvil_access_group) agreement_3 = factories.NonDataAffiliateAgreementFactory.create() - GroupAccountMembershipFactory.create( - group=agreement_3.signed_agreement.anvil_access_group - ) + GroupAccountMembershipFactory.create(group=agreement_3.signed_agreement.anvil_access_group) self.client.force_login(self.user) response = self.client.get(self.get_url()) table = response.context_data["table"] @@ -7226,13 +6619,9 @@ def test_only_shows_records_for_all_agreement_types(self): def test_shows_includes_component_agreements(self): agreement_1 = factories.MemberAgreementFactory.create(is_primary=False) - GroupAccountMembershipFactory.create( - group=agreement_1.signed_agreement.anvil_access_group - ) + GroupAccountMembershipFactory.create(group=agreement_1.signed_agreement.anvil_access_group) agreement_2 = factories.DataAffiliateAgreementFactory.create(is_primary=False) - GroupAccountMembershipFactory.create( - group=agreement_2.signed_agreement.anvil_access_group - ) + GroupAccountMembershipFactory.create(group=agreement_2.signed_agreement.anvil_access_group) self.client.force_login(self.user) response = self.client.get(self.get_url()) table = response.context_data["table"] @@ -7256,15 +6645,11 @@ def test_does_not_show_other_group_members(self): def test_only_includes_active_agreements(self): active_agreement = factories.MemberAgreementFactory.create() - active_member = GroupAccountMembershipFactory.create( - group=active_agreement.signed_agreement.anvil_access_group - ) + active_member = GroupAccountMembershipFactory.create(group=active_agreement.signed_agreement.anvil_access_group) lapsed_agreement = factories.MemberAgreementFactory.create( signed_agreement__status=models.SignedAgreement.StatusChoices.LAPSED ) - lapsed_member = GroupAccountMembershipFactory.create( - group=lapsed_agreement.signed_agreement.anvil_access_group - ) + lapsed_member = GroupAccountMembershipFactory.create(group=lapsed_agreement.signed_agreement.anvil_access_group) withdrawn_agreement = factories.MemberAgreementFactory.create( signed_agreement__status=models.SignedAgreement.StatusChoices.WITHDRAWN ) @@ -7318,9 +6703,7 @@ def test_table_class(self): self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertIn("table", response.context_data) - self.assertIsInstance( - response.context_data["table"], tables.CDSAWorkspaceRecordsTable - ) + self.assertIsInstance(response.context_data["table"], tables.CDSAWorkspaceRecordsTable) def test_table_no_rows(self): """No rows are shown if there are no CDSAWorkspaces objects.""" @@ -7380,9 +6763,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) def test_status_code_with_user_permission(self): @@ -7439,11 +6820,7 @@ def test_render_duo_modifiers(self): def test_associated_data_prep_view_user(self): """View users do not see the associated data prep section""" user = User.objects.create_user(username="test-view", password="test-view") - user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) - ) + user.user_permissions.add(Permission.objects.get(codename=AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME)) obj = factories.CDSAWorkspaceFactory.create() DataPrepWorkspaceFactory.create(target_workspace=obj.workspace) @@ -7471,15 +6848,11 @@ def test_associated_data_prep_workspaces_context_exists(self): def test_only_show_one_associated_data_prep_workspace(self): cdsa_obj = factories.CDSAWorkspaceFactory.create() - dataPrep_obj = DataPrepWorkspaceFactory.create( - target_workspace=cdsa_obj.workspace - ) + dataPrep_obj = DataPrepWorkspaceFactory.create(target_workspace=cdsa_obj.workspace) self.client.force_login(self.user) response = self.client.get(cdsa_obj.get_absolute_url()) self.assertIn("associated_data_prep_workspaces", response.context_data) - self.assertEqual( - len(response.context_data["associated_data_prep_workspaces"].rows), 1 - ) + self.assertEqual(len(response.context_data["associated_data_prep_workspaces"].rows), 1) self.assertIn( dataPrep_obj.workspace, response.context_data["associated_data_prep_workspaces"].data, @@ -7487,18 +6860,12 @@ def test_only_show_one_associated_data_prep_workspace(self): def test_show_two_associated_data_prep_workspaces(self): cdsa_obj = factories.CDSAWorkspaceFactory.create() - dataPrep_obj1 = DataPrepWorkspaceFactory.create( - target_workspace=cdsa_obj.workspace - ) - dataPrep_obj2 = DataPrepWorkspaceFactory.create( - target_workspace=cdsa_obj.workspace - ) + dataPrep_obj1 = DataPrepWorkspaceFactory.create(target_workspace=cdsa_obj.workspace) + dataPrep_obj2 = DataPrepWorkspaceFactory.create(target_workspace=cdsa_obj.workspace) self.client.force_login(self.user) response = self.client.get(cdsa_obj.get_absolute_url()) self.assertIn("associated_data_prep_workspaces", response.context_data) - self.assertEqual( - len(response.context_data["associated_data_prep_workspaces"].rows), 2 - ) + self.assertEqual(len(response.context_data["associated_data_prep_workspaces"].rows), 2) self.assertIn( dataPrep_obj1.workspace, response.context_data["associated_data_prep_workspaces"].data, @@ -7517,9 +6884,7 @@ def test_context_data_prep_active_with_no_prep_workspace(self): def test_context_data_prep_active_with_one_inactive_prep_workspace(self): instance = factories.CDSAWorkspaceFactory.create() - DataPrepWorkspaceFactory.create( - target_workspace=instance.workspace, is_active=False - ) + DataPrepWorkspaceFactory.create(target_workspace=instance.workspace, is_active=False) self.client.force_login(self.user) response = self.client.get(instance.get_absolute_url()) self.assertIn("data_prep_active", response.context_data) @@ -7527,9 +6892,7 @@ def test_context_data_prep_active_with_one_inactive_prep_workspace(self): def test_context_data_prep_active_with_one_active_prep_workspace(self): instance = factories.CDSAWorkspaceFactory.create() - DataPrepWorkspaceFactory.create( - target_workspace=instance.workspace, is_active=True - ) + DataPrepWorkspaceFactory.create(target_workspace=instance.workspace, is_active=True) self.client.force_login(self.user) response = self.client.get(instance.get_absolute_url()) self.assertIn("data_prep_active", response.context_data) @@ -7537,12 +6900,8 @@ def test_context_data_prep_active_with_one_active_prep_workspace(self): def test_context_data_prep_active_with_one_active_one_inactive_prep_workspace(self): instance = factories.CDSAWorkspaceFactory.create() - DataPrepWorkspaceFactory.create( - target_workspace=instance.workspace, is_active=True - ) - DataPrepWorkspaceFactory.create( - target_workspace=instance.workspace, is_active=True - ) + DataPrepWorkspaceFactory.create(target_workspace=instance.workspace, is_active=True) + DataPrepWorkspaceFactory.create(target_workspace=instance.workspace, is_active=True) self.client.force_login(self.user) response = self.client.get(instance.get_absolute_url()) self.assertIn("data_prep_active", response.context_data) @@ -7571,9 +6930,7 @@ def test_response_includes_additional_limitations(self): ) self.client.force_login(self.user) response = self.client.get(instance.get_absolute_url()) - self.assertContains( - response, "Test limitations for this data affiliate agreement" - ) + self.assertContains(response, "Test limitations for this data affiliate agreement") def test_response_data_use_limitations(self): """All data use limitations appear in the response content.""" @@ -7582,12 +6939,8 @@ def test_response_data_use_limitations(self): data_use_permission__abbreviation="P", additional_limitations="Test additional limitations for workspace", ) - modifier_1 = DataUseModifierFactory.create( - abbreviation="M1", definition="Test modifier 1." - ) - modifier_2 = DataUseModifierFactory.create( - abbreviation="M2", definition="Test modifier 2." - ) + modifier_1 = DataUseModifierFactory.create(abbreviation="M1", definition="Test modifier 1.") + modifier_2 = DataUseModifierFactory.create(abbreviation="M2", definition="Test modifier 2.") instance.data_use_modifiers.add(modifier_1, modifier_2) # Create an agreement with data use limitations. factories.DataAffiliateAgreementFactory.create( @@ -7663,7 +7016,7 @@ def test_response_no_primary_cdsa(self): self.assertContains( response, # """
Associated CDSA
mdash;
""" - """No primary CDSA""" + """No primary CDSA""", # """
Associated CDSA
""", # noqa: E501 ) @@ -7680,14 +7033,10 @@ def setUp(self): # Create a user with both view and edit permissions. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) self.requester = UserFactory.create() self.workspace_type = "cdsa" @@ -7797,9 +7146,7 @@ def test_creates_upload_workspace_with_duo_modifiers(self): def test_creates_upload_workspace_with_disease_term(self): """Posting valid data to the form creates a workspace data object when using a custom adapter.""" study = factories.StudyFactory.create() - data_use_permission = DataUsePermissionFactory.create( - requires_disease_term=True - ) + data_use_permission = DataUsePermissionFactory.create(requires_disease_term=True) # Create an extra that won't be specified. billing_project = BillingProjectFactory.create(name="test-billing-project") url = self.api_client.rawls_entry_point + "/api/workspaces" diff --git a/primed/cdsa/urls.py b/primed/cdsa/urls.py index 2a991365..ee4d487d 100644 --- a/primed/cdsa/urls.py +++ b/primed/cdsa/urls.py @@ -48,9 +48,7 @@ [ path("", views.DataAffiliateAgreementList.as_view(), name="list"), path("new/", views.DataAffiliateAgreementCreate.as_view(), name="new"), - path( - "/", views.DataAffiliateAgreementDetail.as_view(), name="detail" - ), + path("/", views.DataAffiliateAgreementDetail.as_view(), name="detail"), path( "/update/", views.SignedAgreementStatusUpdate.as_view(), diff --git a/primed/cdsa/views.py b/primed/cdsa/views.py index c2bc83bb..5986db22 100644 --- a/primed/cdsa/views.py +++ b/primed/cdsa/views.py @@ -31,9 +31,7 @@ logger = logging.getLogger(__name__) -class AgreementMajorVersionDetail( - AnVILConsortiumManagerStaffViewRequired, MultiTableMixin, DetailView -): +class AgreementMajorVersionDetail(AnVILConsortiumManagerStaffViewRequired, MultiTableMixin, DetailView): """Display a "detail" page for an agreement major version (e.g., 1.x).""" model = models.AgreementMajorVersion @@ -47,18 +45,13 @@ def get_object(self, queryset=None): obj = queryset.get(version=major_version) except (KeyError, self.model.DoesNotExist): raise Http404( - _("No %(verbose_name)s found matching the query") - % {"verbose_name": queryset.model._meta.verbose_name} + _("No %(verbose_name)s found matching the query") % {"verbose_name": queryset.model._meta.verbose_name} ) return obj def get_tables_data(self): - agreement_version_qs = models.AgreementVersion.objects.filter( - major_version=self.object - ) - signed_agreement_qs = models.SignedAgreement.objects.filter( - version__major_version=self.object - ) + agreement_version_qs = models.AgreementVersion.objects.filter(major_version=self.object) + signed_agreement_qs = models.SignedAgreement.objects.filter(version__major_version=self.object) return [agreement_version_qs, signed_agreement_qs] def get_context_data(self, **kwargs): @@ -67,17 +60,13 @@ def get_context_data(self, **kwargs): edit_permission_codename = "anvil_consortium_manager." + ( AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME ) - context[ - "show_invalidate_button" - ] = self.object.is_valid and self.request.user.has_perm( + context["show_invalidate_button"] = self.object.is_valid and self.request.user.has_perm( edit_permission_codename ) return context -class AgreementMajorVersionInvalidate( - AnVILConsortiumManagerStaffEditRequired, SuccessMessageMixin, UpdateView -): +class AgreementMajorVersionInvalidate(AnVILConsortiumManagerStaffEditRequired, SuccessMessageMixin, UpdateView): """A view to invalidate an AgreementMajorVersion instance. This view sets the is_valid field to False. It also sets the status of all associated @@ -99,8 +88,7 @@ def get_object(self, queryset=None): obj = queryset.get(version=major_version) except (KeyError, self.model.DoesNotExist): raise Http404( - _("No %(verbose_name)s found matching the query") - % {"verbose_name": queryset.model._meta.verbose_name} + _("No %(verbose_name)s found matching the query") % {"verbose_name": queryset.model._meta.verbose_name} ) return obj @@ -137,9 +125,7 @@ def get_success_url(self): # Change status for CDSAs to lapsed when their major version is invalidated. -class AgreementVersionDetail( - AnVILConsortiumManagerStaffViewRequired, SingleTableMixin, DetailView -): +class AgreementVersionDetail(AnVILConsortiumManagerStaffViewRequired, SingleTableMixin, DetailView): """Display a "detail" page for an agreement major/minor version (e.g., 1.3).""" model = models.AgreementVersion @@ -156,13 +142,10 @@ def get_object(self, queryset=None): try: major_version = self.kwargs["major_version"] minor_version = self.kwargs["minor_version"] - obj = queryset.get( - major_version__version=major_version, minor_version=minor_version - ) + obj = queryset.get(major_version__version=major_version, minor_version=minor_version) except (KeyError, self.model.DoesNotExist): raise Http404( - _("No %(verbose_name)s found matching the query") - % {"verbose_name": queryset.model._meta.verbose_name} + _("No %(verbose_name)s found matching the query") % {"verbose_name": queryset.model._meta.verbose_name} ) return obj @@ -237,16 +220,12 @@ def get_agreement(self, form, formset): settings.ANVIL_DATA_ACCESS_GROUP_PREFIX, form.instance.cc_id, ) - access_group = ManagedGroup( - name=access_group_name, email=access_group_name + "@firecloud.org" - ) + access_group = ManagedGroup(name=access_group_name, email=access_group_name + "@firecloud.org") # Make sure the group doesn't exist already. access_group.full_clean() access_group.save() # Add the cc admins group as a member. - cc_admins_group = ManagedGroup.objects.get( - name=settings.ANVIL_CC_ADMINS_GROUP_NAME - ) + cc_admins_group = ManagedGroup.objects.get(name=settings.ANVIL_CC_ADMINS_GROUP_NAME) self.admin_access_membership = GroupGroupMembership( parent_group=access_group, child_group=cc_admins_group, @@ -290,22 +269,16 @@ def form_valid(self, form): except ValidationError as e: # log the error. logger.error(str(e)) - messages.add_message( - self.request, messages.ERROR, self.ERROR_CREATING_GROUP - ) + messages.add_message(self.request, messages.ERROR, self.ERROR_CREATING_GROUP) return self.render_to_response(self.get_context_data(form=form)) except AnVILAPIError as e: # log the error. logger.error(str(e)) - messages.add_message( - self.request, messages.ERROR, "AnVIL API Error: " + str(e) - ) + messages.add_message(self.request, messages.ERROR, "AnVIL API Error: " + str(e)) return self.render_to_response(self.get_context_data(form=form)) def form_invalid(self, form, formset): - return self.render_to_response( - self.get_context_data(form=form, formset=formset) - ) + return self.render_to_response(self.get_context_data(form=form, formset=formset)) def get_success_url(self): return self.object.get_absolute_url() @@ -357,16 +330,12 @@ def get_agreement_type(self, form, formset): settings.ANVIL_DATA_ACCESS_GROUP_PREFIX, form.instance.cc_id, ) - upload_group = ManagedGroup( - name=upload_group_name, email=upload_group_name + "@firecloud.org" - ) + upload_group = ManagedGroup(name=upload_group_name, email=upload_group_name + "@firecloud.org") # Make sure the group doesn't exist already. upload_group.full_clean() upload_group.save() # Add the cc admins group as a member. - cc_admins_group = ManagedGroup.objects.get( - name=settings.ANVIL_CC_ADMINS_GROUP_NAME - ) + cc_admins_group = ManagedGroup.objects.get(name=settings.ANVIL_CC_ADMINS_GROUP_NAME) self.admin_upload_membership = GroupGroupMembership( parent_group=upload_group, child_group=cc_admins_group, @@ -390,22 +359,17 @@ def get_object(self, queryset=None): obj = queryset.get(signed_agreement__cc_id=self.kwargs.get("cc_id")) except queryset.model.DoesNotExist: raise Http404( - "No %(verbose_name)s found matching the query" - % {"verbose_name": queryset.model._meta.verbose_name} + "No %(verbose_name)s found matching the query" % {"verbose_name": queryset.model._meta.verbose_name} ) return obj def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context[ - "show_deprecation_message" - ] = not self.object.signed_agreement.version.major_version.is_valid + context["show_deprecation_message"] = not self.object.signed_agreement.version.major_version.is_valid edit_permission_codename = "anvil_consortium_manager." + ( AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME ) - context["show_update_button"] = self.request.user.has_perm( - edit_permission_codename - ) + context["show_update_button"] = self.request.user.has_perm(edit_permission_codename) return context @@ -416,10 +380,7 @@ class MemberAgreementList(AnVILConsortiumManagerStaffViewRequired, SingleTableVi table_class = tables.MemberAgreementTable -class SignedAgreementStatusUpdate( - AnVILConsortiumManagerStaffEditRequired, SuccessMessageMixin, UpdateView -): - +class SignedAgreementStatusUpdate(AnVILConsortiumManagerStaffEditRequired, SuccessMessageMixin, UpdateView): model = models.SignedAgreement form_class = forms.SignedAgreementStatusForm template_name = "cdsa/signedagreement_status_update.html" @@ -430,13 +391,10 @@ def get_object(self, queryset=None): """Look up the agreement by agreement_type_indicator and CDSA cc_id.""" queryset = self.get_queryset() try: - obj = queryset.get( - cc_id=self.kwargs.get("cc_id"), type=self.kwargs.get("agreement_type") - ) + obj = queryset.get(cc_id=self.kwargs.get("cc_id"), type=self.kwargs.get("agreement_type")) except queryset.model.DoesNotExist: raise Http404( - "No %(verbose_name)s found matching the query" - % {"verbose_name": queryset.model._meta.verbose_name} + "No %(verbose_name)s found matching the query" % {"verbose_name": queryset.model._meta.verbose_name} ) return obj @@ -453,28 +411,21 @@ def get_object(self, queryset=None): obj = queryset.get(signed_agreement__cc_id=self.kwargs.get("cc_id")) except queryset.model.DoesNotExist: raise Http404( - "No %(verbose_name)s found matching the query" - % {"verbose_name": queryset.model._meta.verbose_name} + "No %(verbose_name)s found matching the query" % {"verbose_name": queryset.model._meta.verbose_name} ) return obj def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context[ - "show_deprecation_message" - ] = not self.object.signed_agreement.version.major_version.is_valid + context["show_deprecation_message"] = not self.object.signed_agreement.version.major_version.is_valid edit_permission_codename = "anvil_consortium_manager." + ( AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME ) - context["show_update_button"] = self.request.user.has_perm( - edit_permission_codename - ) + context["show_update_button"] = self.request.user.has_perm(edit_permission_codename) return context -class DataAffiliateAgreementList( - AnVILConsortiumManagerStaffViewRequired, SingleTableView -): +class DataAffiliateAgreementList(AnVILConsortiumManagerStaffViewRequired, SingleTableView): """Display a list of DataAffiliateAgreement objects.""" model = models.DataAffiliateAgreement @@ -498,9 +449,7 @@ class NonDataAffiliateAgreementCreate( ERROR_CREATING_GROUP = "Error creating access group on AnVIL." -class NonDataAffiliateAgreementDetail( - AnVILConsortiumManagerStaffViewRequired, DetailView -): +class NonDataAffiliateAgreementDetail(AnVILConsortiumManagerStaffViewRequired, DetailView): """View to show details about a `NonDataAffiliateAgreement`.""" model = models.NonDataAffiliateAgreement @@ -512,28 +461,21 @@ def get_object(self, queryset=None): obj = queryset.get(signed_agreement__cc_id=self.kwargs.get("cc_id")) except queryset.model.DoesNotExist: raise Http404( - "No %(verbose_name)s found matching the query" - % {"verbose_name": queryset.model._meta.verbose_name} + "No %(verbose_name)s found matching the query" % {"verbose_name": queryset.model._meta.verbose_name} ) return obj def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context[ - "show_deprecation_message" - ] = not self.object.signed_agreement.version.major_version.is_valid + context["show_deprecation_message"] = not self.object.signed_agreement.version.major_version.is_valid edit_permission_codename = "anvil_consortium_manager." + ( AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME ) - context["show_update_button"] = self.request.user.has_perm( - edit_permission_codename - ) + context["show_update_button"] = self.request.user.has_perm(edit_permission_codename) return context -class NonDataAffiliateAgreementList( - AnVILConsortiumManagerStaffViewRequired, SingleTableView -): +class NonDataAffiliateAgreementList(AnVILConsortiumManagerStaffViewRequired, SingleTableView): """Display a list of NonDataAffiliateAgreement objects.""" model = models.NonDataAffiliateAgreement @@ -544,19 +486,13 @@ class SignedAgreementAudit(AnVILConsortiumManagerStaffViewRequired, TemplateView """View to show audit results for `SignedAgreements`.""" template_name = "cdsa/signedagreement_audit.html" - ERROR_CDSA_GROUP_DOES_NOT_EXIST = ( - """The CDSA group "{}" does not exist in the app.""" - ) + ERROR_CDSA_GROUP_DOES_NOT_EXIST = """The CDSA group "{}" does not exist in the app.""" def get(self, request, *args, **kwargs): - if not models.ManagedGroup.objects.filter( - name=settings.ANVIL_CDSA_GROUP_NAME - ).exists(): + if not models.ManagedGroup.objects.filter(name=settings.ANVIL_CDSA_GROUP_NAME).exists(): messages.error( self.request, - self.ERROR_CDSA_GROUP_DOES_NOT_EXIST.format( - settings.ANVIL_CDSA_GROUP_NAME - ), + self.ERROR_CDSA_GROUP_DOES_NOT_EXIST.format(settings.ANVIL_CDSA_GROUP_NAME), ) return HttpResponseRedirect(reverse("anvil_consortium_manager:index")) return super().get(request, *args, **kwargs) @@ -572,10 +508,7 @@ def get_context_data(self, **kwargs): return context -class SignedAgreementAuditResolve( - AnVILConsortiumManagerStaffEditRequired, SingleObjectMixin, FormView -): - +class SignedAgreementAuditResolve(AnVILConsortiumManagerStaffEditRequired, SingleObjectMixin, FormView): model = models.SignedAgreement form_class = Form template_name = "cdsa/signedagreement_audit_resolve.html" @@ -589,16 +522,13 @@ def get_object(self, queryset=None): obj = queryset.get(cc_id=self.kwargs.get("cc_id")) except queryset.model.DoesNotExist: raise Http404( - "No %(verbose_name)s found matching the query" - % {"verbose_name": queryset.model._meta.verbose_name} + "No %(verbose_name)s found matching the query" % {"verbose_name": queryset.model._meta.verbose_name} ) return obj def get_audit_result(self): audit = signed_agreement_audit.SignedAgreementAccessAudit( - signed_agreement_queryset=models.SignedAgreement.objects.filter( - pk=self.object.pk - ) + signed_agreement_queryset=models.SignedAgreement.objects.filter(pk=self.object.pk) ) audit.run_audit() return audit.get_all_results()[0] @@ -664,9 +594,7 @@ class CDSAWorkspaceAudit(AnVILConsortiumManagerStaffViewRequired, TemplateView): """View to show audit results for `CDSAWorkspaces`.""" template_name = "cdsa/cdsaworkspace_audit.html" - ERROR_CDSA_GROUP_DOES_NOT_EXIST = ( - """The CDSA group "{}" does not exist in the app.""" - ) + ERROR_CDSA_GROUP_DOES_NOT_EXIST = """The CDSA group "{}" does not exist in the app.""" def get(self, request, *args, **kwargs): try: @@ -674,9 +602,7 @@ def get(self, request, *args, **kwargs): except models.ManagedGroup.DoesNotExist: messages.error( self.request, - self.ERROR_CDSA_GROUP_DOES_NOT_EXIST.format( - settings.ANVIL_CDSA_GROUP_NAME - ), + self.ERROR_CDSA_GROUP_DOES_NOT_EXIST.format(settings.ANVIL_CDSA_GROUP_NAME), ) return HttpResponseRedirect(reverse("anvil_consortium_manager:index")) return super().get(request, *args, **kwargs) @@ -692,10 +618,7 @@ def get_context_data(self, **kwargs): return context -class CDSAWorkspaceAuditResolve( - AnVILConsortiumManagerStaffEditRequired, SingleObjectMixin, FormView -): - +class CDSAWorkspaceAuditResolve(AnVILConsortiumManagerStaffEditRequired, SingleObjectMixin, FormView): model = models.CDSAWorkspace form_class = Form template_name = "cdsa/cdsaworkspace_audit_resolve.html" @@ -707,23 +630,18 @@ def get_object(self, queryset=None): queryset = self.get_queryset() try: obj = queryset.get( - workspace__billing_project__name=self.kwargs.get( - "billing_project_slug" - ), + workspace__billing_project__name=self.kwargs.get("billing_project_slug"), workspace__name=self.kwargs.get("workspace_slug"), ) except queryset.model.DoesNotExist: raise Http404( - "No %(verbose_name)s found matching the query" - % {"verbose_name": queryset.model._meta.verbose_name} + "No %(verbose_name)s found matching the query" % {"verbose_name": queryset.model._meta.verbose_name} ) return obj def get_audit_result(self): audit = workspace_audit.WorkspaceAccessAudit( - cdsa_workspace_queryset=models.CDSAWorkspace.objects.filter( - pk=self.object.pk - ) + cdsa_workspace_queryset=models.CDSAWorkspace.objects.filter(pk=self.object.pk) ) audit.run_audit() return audit.get_all_results()[0] diff --git a/primed/collaborative_analysis/adapters.py b/primed/collaborative_analysis/adapters.py index 0e439385..f070d926 100644 --- a/primed/collaborative_analysis/adapters.py +++ b/primed/collaborative_analysis/adapters.py @@ -15,6 +15,4 @@ class CollaborativeAnalysisWorkspaceAdapter(BaseWorkspaceAdapter): workspace_form_class = WorkspaceForm workspace_data_model = models.CollaborativeAnalysisWorkspace workspace_data_form_class = forms.CollaborativeAnalysisWorkspaceForm - workspace_detail_template_name = ( - "collaborative_analysis/collaborativeanalysisworkspace_detail.html" - ) + workspace_detail_template_name = "collaborative_analysis/collaborativeanalysisworkspace_detail.html" diff --git a/primed/collaborative_analysis/audit.py b/primed/collaborative_analysis/audit.py index e4764e6f..2633ce59 100644 --- a/primed/collaborative_analysis/audit.py +++ b/primed/collaborative_analysis/audit.py @@ -114,9 +114,7 @@ class CollaborativeAnalysisWorkspaceAccessAudit(PRIMEDAudit): DCC_ACCESS = "CC groups are allowed access." # Allowed reasons for no access. - NOT_IN_SOURCE_AUTH_DOMAINS = ( - "Account is not in all source auth domains for this workspace." - ) + NOT_IN_SOURCE_AUTH_DOMAINS = "Account is not in all source auth domains for this workspace." NOT_IN_ANALYST_GROUP = "Account is not in the analyst group for this workspace." INACTIVE_ACCOUNT = "Account is inactive." NON_DCC_GROUP = "Non-CC groups are not allowed access." @@ -149,9 +147,7 @@ def _audit_workspace(self, workspace): # Get a list of accounts in the auth domain. auth_domain_membership = [ x.account - for x in GroupAccountMembership.objects.filter( - group=workspace.workspace.authorization_domains.first() - ) + for x in GroupAccountMembership.objects.filter(group=workspace.workspace.authorization_domains.first()) ] for membership in analyst_memberships: self._audit_workspace_and_account(workspace, membership.account) @@ -199,15 +195,9 @@ def _audit_workspace_and_group(self, collaborative_analysis_workspace, group): access_allowed = group.name in [ "PRIMED_CC_WRITERS", ] - in_auth_domain = ( - collaborative_analysis_workspace.workspace.authorization_domains.first() - ) - auth_domain = ( - collaborative_analysis_workspace.workspace.authorization_domains.first() - ) - in_auth_domain = GroupGroupMembership.objects.filter( - parent_group=auth_domain, child_group=group - ).exists() + in_auth_domain = collaborative_analysis_workspace.workspace.authorization_domains.first() + auth_domain = collaborative_analysis_workspace.workspace.authorization_domains.first() + in_auth_domain = GroupGroupMembership.objects.filter(parent_group=auth_domain, child_group=group).exists() if access_allowed and in_auth_domain: self.verified.append( VerifiedAccess( @@ -254,22 +244,15 @@ def _audit_workspace_and_account(self, collaborative_analysis_workspace, account # Get all groups for the account. account_groups = account.get_all_groups() # Check whether the account is in the analyst group. - in_analyst_group = ( - collaborative_analysis_workspace.analyst_group in account_groups - ) + in_analyst_group = collaborative_analysis_workspace.analyst_group in account_groups # Check whether the account is in the auth domain of the collab workspace. - in_auth_domain = ( - collaborative_analysis_workspace.workspace.authorization_domains.first() - in account_groups - ) + in_auth_domain = collaborative_analysis_workspace.workspace.authorization_domains.first() in account_groups if in_analyst_group: # Check whether access is allowed. Start by assuming yes, and then # set to false if the account should not have access. access_allowed = True # Loop over all source workspaces. - for ( - source_workspace - ) in collaborative_analysis_workspace.source_workspaces.all(): + for source_workspace in collaborative_analysis_workspace.source_workspaces.all(): # Loop over all auth domains for that source workspace. for source_auth_domain in source_workspace.authorization_domains.all(): # If the user is not in the auth domain, they are not allowed to have access to the workspace. diff --git a/primed/collaborative_analysis/management/commands/run_collaborative_analysis_audit.py b/primed/collaborative_analysis/management/commands/run_collaborative_analysis_audit.py index e92790c0..e8af4904 100644 --- a/primed/collaborative_analysis/management/commands/run_collaborative_analysis_audit.py +++ b/primed/collaborative_analysis/management/commands/run_collaborative_analysis_audit.py @@ -25,9 +25,7 @@ def handle(self, *args, **options): # Report errors and needs access. audit_ok = data_access_audit.ok() # Construct the url for handling errors. - url = ( - "https://" + Site.objects.get_current().domain + reverse("dbgap:audit:all") - ) + url = "https://" + Site.objects.get_current().domain + reverse("dbgap:audit:all") if audit_ok: self.stdout.write(self.style.SUCCESS("ok!")) else: @@ -35,15 +33,11 @@ def handle(self, *args, **options): # Print results self.stdout.write("* Verified: {}".format(len(data_access_audit.verified))) - self.stdout.write( - "* Needs action: {}".format(len(data_access_audit.needs_action)) - ) + self.stdout.write("* Needs action: {}".format(len(data_access_audit.needs_action))) self.stdout.write("* Errors: {}".format(len(data_access_audit.errors))) if not audit_ok: - self.stdout.write( - self.style.ERROR(f"Please visit {url} to resolve these issues.") - ) + self.stdout.write(self.style.ERROR(f"Please visit {url} to resolve these issues.")) # Send email if requested and there are problems. email = options["email"] diff --git a/primed/collaborative_analysis/models.py b/primed/collaborative_analysis/models.py index edcac496..475d488a 100644 --- a/primed/collaborative_analysis/models.py +++ b/primed/collaborative_analysis/models.py @@ -6,7 +6,6 @@ # Note that "RequesterModel" is not included, because we have the "custodian" tracked instead. class CollaborativeAnalysisWorkspace(TimeStampedModel, BaseWorkspaceData): - purpose = models.TextField( help_text="The intended purpose for this workspace.", ) diff --git a/primed/collaborative_analysis/tests/factories.py b/primed/collaborative_analysis/tests/factories.py index 30175a73..243ac017 100644 --- a/primed/collaborative_analysis/tests/factories.py +++ b/primed/collaborative_analysis/tests/factories.py @@ -19,9 +19,7 @@ class Meta: custodian = SubFactory(UserFactory) analyst_group = SubFactory( ManagedGroupFactory, - name=LazyAttribute( - lambda o: "analysts_{}".format(o.factory_parent.workspace.name) - ), + name=LazyAttribute(lambda o: "analysts_{}".format(o.factory_parent.workspace.name)), ) @post_generation @@ -32,9 +30,7 @@ def authorization_domains(self, create, extracted, **kwargs): return # Create an authorization domain. - auth_domain = ManagedGroupFactory.create( - name="auth_{}".format(self.workspace.name) - ) + auth_domain = ManagedGroupFactory.create(name="auth_{}".format(self.workspace.name)) print(auth_domain) self.workspace.authorization_domains.add(auth_domain) diff --git a/primed/collaborative_analysis/tests/test_audit.py b/primed/collaborative_analysis/tests/test_audit.py index b29f1756..ffb50388 100644 --- a/primed/collaborative_analysis/tests/test_audit.py +++ b/primed/collaborative_analysis/tests/test_audit.py @@ -23,9 +23,7 @@ def setUp(self): def test_account_verified_access(self): workspace = factories.CollaborativeAnalysisWorkspaceFactory.create() account = AccountFactory.create() - instance = audit.VerifiedAccess( - collaborative_analysis_workspace=workspace, member=account, note="test" - ) + instance = audit.VerifiedAccess(collaborative_analysis_workspace=workspace, member=account, note="test") expected_url = reverse( "collaborative_analysis:audit:resolve", args=[ @@ -39,9 +37,7 @@ def test_account_verified_access(self): def test_account_verified_no_access(self): workspace = factories.CollaborativeAnalysisWorkspaceFactory.create() account = AccountFactory.create() - instance = audit.VerifiedNoAccess( - collaborative_analysis_workspace=workspace, member=account, note="test" - ) + instance = audit.VerifiedNoAccess(collaborative_analysis_workspace=workspace, member=account, note="test") expected_url = reverse( "collaborative_analysis:audit:resolve", args=[ @@ -55,9 +51,7 @@ def test_account_verified_no_access(self): def test_account_grant_access(self): workspace = factories.CollaborativeAnalysisWorkspaceFactory.create() account = AccountFactory.create() - instance = audit.GrantAccess( - collaborative_analysis_workspace=workspace, member=account, note="test" - ) + instance = audit.GrantAccess(collaborative_analysis_workspace=workspace, member=account, note="test") expected_url = reverse( "collaborative_analysis:audit:resolve", args=[ @@ -71,9 +65,7 @@ def test_account_grant_access(self): def test_account_remove_access(self): workspace = factories.CollaborativeAnalysisWorkspaceFactory.create() account = AccountFactory.create() - instance = audit.RemoveAccess( - collaborative_analysis_workspace=workspace, member=account, note="test" - ) + instance = audit.RemoveAccess(collaborative_analysis_workspace=workspace, member=account, note="test") expected_url = reverse( "collaborative_analysis:audit:resolve", args=[ @@ -87,9 +79,7 @@ def test_account_remove_access(self): def test_group_verified_access(self): workspace = factories.CollaborativeAnalysisWorkspaceFactory.create() group = ManagedGroupFactory.create() - instance = audit.VerifiedAccess( - collaborative_analysis_workspace=workspace, member=group, note="test" - ) + instance = audit.VerifiedAccess(collaborative_analysis_workspace=workspace, member=group, note="test") expected_url = reverse( "collaborative_analysis:audit:resolve", args=[ @@ -103,9 +93,7 @@ def test_group_verified_access(self): def test_group_verified_no_access(self): workspace = factories.CollaborativeAnalysisWorkspaceFactory.create() group = ManagedGroupFactory.create() - instance = audit.VerifiedNoAccess( - collaborative_analysis_workspace=workspace, member=group, note="test" - ) + instance = audit.VerifiedNoAccess(collaborative_analysis_workspace=workspace, member=group, note="test") expected_url = reverse( "collaborative_analysis:audit:resolve", args=[ @@ -119,9 +107,7 @@ def test_group_verified_no_access(self): def test_group_grant_access(self): workspace = factories.CollaborativeAnalysisWorkspaceFactory.create() group = ManagedGroupFactory.create() - instance = audit.GrantAccess( - collaborative_analysis_workspace=workspace, member=group, note="test" - ) + instance = audit.GrantAccess(collaborative_analysis_workspace=workspace, member=group, note="test") expected_url = reverse( "collaborative_analysis:audit:resolve", args=[ @@ -135,9 +121,7 @@ def test_group_grant_access(self): def test_group_remove_access(self): workspace = factories.CollaborativeAnalysisWorkspaceFactory.create() group = ManagedGroupFactory.create() - instance = audit.RemoveAccess( - collaborative_analysis_workspace=workspace, member=group, note="test" - ) + instance = audit.RemoveAccess(collaborative_analysis_workspace=workspace, member=group, note="test") expected_url = reverse( "collaborative_analysis:audit:resolve", args=[ @@ -185,18 +169,14 @@ def test_analyst_in_collab_auth_domain_in_source_auth_domain(self): source_workspace = dbGaPWorkspaceFactory.create() workspace.source_workspaces.add(source_workspace.workspace) # Analyst group membership. - GroupAccountMembershipFactory.create( - group=workspace.analyst_group, account=account - ) + GroupAccountMembershipFactory.create(group=workspace.analyst_group, account=account) # Source workspace auth domains membership. GroupAccountMembershipFactory.create( group=source_workspace.workspace.authorization_domains.first(), account=account, ) # CollaborativeAnalysisWorkspace auth domain membership. - GroupAccountMembershipFactory.create( - group=workspace.workspace.authorization_domains.first(), account=account - ) + GroupAccountMembershipFactory.create(group=workspace.workspace.authorization_domains.first(), account=account) # Set up audit collab_audit = audit.CollaborativeAnalysisWorkspaceAccessAudit() # Run audit @@ -219,17 +199,13 @@ def test_analyst_in_collab_auth_domain_not_in_source_auth_domain(self): source_workspace = dbGaPWorkspaceFactory.create() workspace.source_workspaces.add(source_workspace.workspace) # Analyst group membership. - GroupAccountMembershipFactory.create( - group=workspace.analyst_group, account=account - ) + GroupAccountMembershipFactory.create(group=workspace.analyst_group, account=account) # Source workspace auth domains membership. # GroupAccountMembershipFactory.create( # group=source_workspace.workspace.authorization_domains.first(), account=account # ) # CollaborativeAnalysisWorkspace auth domain membership. - GroupAccountMembershipFactory.create( - group=workspace.workspace.authorization_domains.first(), account=account - ) + GroupAccountMembershipFactory.create(group=workspace.workspace.authorization_domains.first(), account=account) # Set up audit collab_audit = audit.CollaborativeAnalysisWorkspaceAccessAudit() # Run audit @@ -252,9 +228,7 @@ def test_analyst_not_in_collab_auth_domain_in_source_auth_domain(self): source_workspace = dbGaPWorkspaceFactory.create() workspace.source_workspaces.add(source_workspace.workspace) # Analyst group membership. - GroupAccountMembershipFactory.create( - group=workspace.analyst_group, account=account - ) + GroupAccountMembershipFactory.create(group=workspace.analyst_group, account=account) # Source workspace auth domains membership. GroupAccountMembershipFactory.create( group=source_workspace.workspace.authorization_domains.first(), @@ -286,9 +260,7 @@ def test_analyst_not_in_collab_auth_domain_not_in_source_auth_domain(self): source_workspace = dbGaPWorkspaceFactory.create() workspace.source_workspaces.add(source_workspace.workspace) # Analyst group membership. - GroupAccountMembershipFactory.create( - group=workspace.analyst_group, account=account - ) + GroupAccountMembershipFactory.create(group=workspace.analyst_group, account=account) # Source workspace auth domains membership. # GroupAccountMembershipFactory.create( # group=source_workspace.workspace.authorization_domains.first(), account=account @@ -318,13 +290,9 @@ def test_analyst_in_collab_auth_domain_two_source_auth_domains_in_both(self): # Set up source workspaces. source_workspace = dbGaPWorkspaceFactory.create() workspace.source_workspaces.add(source_workspace.workspace) - source_auth_domain_2 = WorkspaceAuthorizationDomainFactory.create( - workspace=source_workspace.workspace - ) + source_auth_domain_2 = WorkspaceAuthorizationDomainFactory.create(workspace=source_workspace.workspace) # Analyst group membership. - GroupAccountMembershipFactory.create( - group=workspace.analyst_group, account=account - ) + GroupAccountMembershipFactory.create(group=workspace.analyst_group, account=account) # Source workspace auth domains membership. GroupAccountMembershipFactory.create( group=source_workspace.workspace.authorization_domains.all()[0], @@ -335,9 +303,7 @@ def test_analyst_in_collab_auth_domain_two_source_auth_domains_in_both(self): account=account, ) # CollaborativeAnalysisWorkspace auth domain membership. - GroupAccountMembershipFactory.create( - group=workspace.workspace.authorization_domains.first(), account=account - ) + GroupAccountMembershipFactory.create(group=workspace.workspace.authorization_domains.first(), account=account) # Set up audit collab_audit = audit.CollaborativeAnalysisWorkspaceAccessAudit() # Run audit @@ -363,9 +329,7 @@ def test_analyst_in_collab_auth_domain_two_source_auth_domains_in_one(self): # add an extra auth doamin WorkspaceAuthorizationDomainFactory.create(workspace=source_workspace.workspace) # Analyst group membership. - GroupAccountMembershipFactory.create( - group=workspace.analyst_group, account=account - ) + GroupAccountMembershipFactory.create(group=workspace.analyst_group, account=account) # Source workspace auth domains membership. GroupAccountMembershipFactory.create( group=source_workspace.workspace.authorization_domains.first(), @@ -376,9 +340,7 @@ def test_analyst_in_collab_auth_domain_two_source_auth_domains_in_one(self): # account=account, # ) # CollaborativeAnalysisWorkspace auth domain membership. - GroupAccountMembershipFactory.create( - group=workspace.workspace.authorization_domains.first(), account=account - ) + GroupAccountMembershipFactory.create(group=workspace.workspace.authorization_domains.first(), account=account) # Set up audit collab_audit = audit.CollaborativeAnalysisWorkspaceAccessAudit() # Run audit @@ -404,9 +366,7 @@ def test_analyst_in_collab_auth_domain_two_source_auth_domains_in_neither(self): # add an extra auth doamin WorkspaceAuthorizationDomainFactory.create(workspace=source_workspace.workspace) # Analyst group membership. - GroupAccountMembershipFactory.create( - group=workspace.analyst_group, account=account - ) + GroupAccountMembershipFactory.create(group=workspace.analyst_group, account=account) # Source workspace auth domains membership. # GroupAccountMembershipFactory.create( # group=source_workspace.workspace.authorization_domains.first(), @@ -417,9 +377,7 @@ def test_analyst_in_collab_auth_domain_two_source_auth_domains_in_neither(self): # account=account, # ) # CollaborativeAnalysisWorkspace auth domain membership. - GroupAccountMembershipFactory.create( - group=workspace.workspace.authorization_domains.first(), account=account - ) + GroupAccountMembershipFactory.create(group=workspace.workspace.authorization_domains.first(), account=account) # Set up audit collab_audit = audit.CollaborativeAnalysisWorkspaceAccessAudit() # Run audit @@ -442,13 +400,9 @@ def test_analyst_not_in_collab_auth_domain_two_source_auth_domains_in_both(self) source_workspace = dbGaPWorkspaceFactory.create() workspace.source_workspaces.add(source_workspace.workspace) source_auth_domain_1 = source_workspace.workspace.authorization_domains.first() - source_auth_domain_2 = WorkspaceAuthorizationDomainFactory.create( - workspace=source_workspace.workspace - ) + source_auth_domain_2 = WorkspaceAuthorizationDomainFactory.create(workspace=source_workspace.workspace) # Analyst group membership. - GroupAccountMembershipFactory.create( - group=workspace.analyst_group, account=account - ) + GroupAccountMembershipFactory.create(group=workspace.analyst_group, account=account) # Source workspace auth domains membership. GroupAccountMembershipFactory.create( group=source_auth_domain_1, @@ -483,13 +437,9 @@ def test_analyst_not_in_collab_auth_domain_two_source_auth_domains_in_one(self): # Set up source workspaces. source_workspace = dbGaPWorkspaceFactory.create() workspace.source_workspaces.add(source_workspace.workspace) - source_auth_domain_2 = WorkspaceAuthorizationDomainFactory.create( - workspace=source_workspace.workspace - ) + source_auth_domain_2 = WorkspaceAuthorizationDomainFactory.create(workspace=source_workspace.workspace) # Analyst group membership. - GroupAccountMembershipFactory.create( - group=workspace.analyst_group, account=account - ) + GroupAccountMembershipFactory.create(group=workspace.analyst_group, account=account) # Source workspace auth domains membership. # GroupAccountMembershipFactory.create( # group=source_auth_domain_1, @@ -526,9 +476,7 @@ def test_analyst_not_in_collab_auth_domain_two_source_auth_domains_in_neither(se workspace.source_workspaces.add(source_workspace.workspace) WorkspaceAuthorizationDomainFactory.create(workspace=source_workspace.workspace) # Analyst group membership. - GroupAccountMembershipFactory.create( - group=workspace.analyst_group, account=account - ) + GroupAccountMembershipFactory.create(group=workspace.analyst_group, account=account) # Source workspace auth domains membership. # GroupAccountMembershipFactory.create( # group=source_auth_domain_1, @@ -564,14 +512,10 @@ def test_in_collab_auth_domain_no_source_workspaces(self): source_workspace = WorkspaceFactory.create() workspace.source_workspaces.add(source_workspace) # Analyst group membership. - GroupAccountMembershipFactory.create( - group=workspace.analyst_group, account=account - ) + GroupAccountMembershipFactory.create(group=workspace.analyst_group, account=account) # Source workspace auth domains membership. # CollaborativeAnalysisWorkspace auth domain membership. - GroupAccountMembershipFactory.create( - group=workspace.workspace.authorization_domains.first(), account=account - ) + GroupAccountMembershipFactory.create(group=workspace.workspace.authorization_domains.first(), account=account) # Set up audit collab_audit = audit.CollaborativeAnalysisWorkspaceAccessAudit() # Run audit @@ -594,9 +538,7 @@ def test_not_in_collab_auth_domain_no_source_workspaces(self): source_workspace = WorkspaceFactory.create() workspace.source_workspaces.add(source_workspace) # Analyst group membership. - GroupAccountMembershipFactory.create( - group=workspace.analyst_group, account=account - ) + GroupAccountMembershipFactory.create(group=workspace.analyst_group, account=account) # Source workspace auth domains membership. # CollaborativeAnalysisWorkspace auth domain membership. # GroupAccountMembershipFactory.create( @@ -626,9 +568,7 @@ def test_in_collab_auth_domain_two_source_workspaces_in_both_auth_domains(self): source_workspace_2 = CDSAWorkspaceFactory.create() workspace.source_workspaces.add(source_workspace_2.workspace) # Analyst group membership. - GroupAccountMembershipFactory.create( - group=workspace.analyst_group, account=account - ) + GroupAccountMembershipFactory.create(group=workspace.analyst_group, account=account) # Source workspace auth domains membership. GroupAccountMembershipFactory.create( group=source_workspace_1.workspace.authorization_domains.first(), @@ -639,9 +579,7 @@ def test_in_collab_auth_domain_two_source_workspaces_in_both_auth_domains(self): account=account, ) # CollaborativeAnalysisWorkspace auth domain membership. - GroupAccountMembershipFactory.create( - group=workspace.workspace.authorization_domains.first(), account=account - ) + GroupAccountMembershipFactory.create(group=workspace.workspace.authorization_domains.first(), account=account) # Set up audit collab_audit = audit.CollaborativeAnalysisWorkspaceAccessAudit() # Run audit @@ -666,9 +604,7 @@ def test_in_collab_auth_domain_two_source_workspaces_in_one_auth_domains(self): source_workspace_2 = CDSAWorkspaceFactory.create() workspace.source_workspaces.add(source_workspace_2.workspace) # Analyst group membership. - GroupAccountMembershipFactory.create( - group=workspace.analyst_group, account=account - ) + GroupAccountMembershipFactory.create(group=workspace.analyst_group, account=account) # Source workspace auth domains membership. GroupAccountMembershipFactory.create( group=source_workspace_1.workspace.authorization_domains.first(), @@ -679,9 +615,7 @@ def test_in_collab_auth_domain_two_source_workspaces_in_one_auth_domains(self): # account=account, # ) # CollaborativeAnalysisWorkspace auth domain membership. - GroupAccountMembershipFactory.create( - group=workspace.workspace.authorization_domains.first(), account=account - ) + GroupAccountMembershipFactory.create(group=workspace.workspace.authorization_domains.first(), account=account) # Set up audit collab_audit = audit.CollaborativeAnalysisWorkspaceAccessAudit() # Run audit @@ -706,9 +640,7 @@ def test_in_collab_auth_domain_two_source_workspaces_in_neither_auth_domains(sel source_workspace_2 = CDSAWorkspaceFactory.create() workspace.source_workspaces.add(source_workspace_2.workspace) # Analyst group membership. - GroupAccountMembershipFactory.create( - group=workspace.analyst_group, account=account - ) + GroupAccountMembershipFactory.create(group=workspace.analyst_group, account=account) # Source workspace auth domains membership. # GroupAccountMembershipFactory.create( # group=source_workspace_1.workspace.authorization_domains.first(), @@ -719,9 +651,7 @@ def test_in_collab_auth_domain_two_source_workspaces_in_neither_auth_domains(sel # account=account, # ) # CollaborativeAnalysisWorkspace auth domain membership. - GroupAccountMembershipFactory.create( - group=workspace.workspace.authorization_domains.first(), account=account - ) + GroupAccountMembershipFactory.create(group=workspace.workspace.authorization_domains.first(), account=account) # Set up audit collab_audit = audit.CollaborativeAnalysisWorkspaceAccessAudit() # Run audit @@ -746,9 +676,7 @@ def test_not_in_collab_auth_domain_two_source_workspaces_in_both_auth_domains(se source_workspace_2 = CDSAWorkspaceFactory.create() workspace.source_workspaces.add(source_workspace_2.workspace) # Analyst group membership. - GroupAccountMembershipFactory.create( - group=workspace.analyst_group, account=account - ) + GroupAccountMembershipFactory.create(group=workspace.analyst_group, account=account) # Source workspace auth domains membership. GroupAccountMembershipFactory.create( group=source_workspace_1.workspace.authorization_domains.first(), @@ -786,9 +714,7 @@ def test_not_in_collab_auth_domain_two_source_workspaces_in_one_auth_domains(sel source_workspace_2 = CDSAWorkspaceFactory.create() workspace.source_workspaces.add(source_workspace_2.workspace) # Analyst group membership. - GroupAccountMembershipFactory.create( - group=workspace.analyst_group, account=account - ) + GroupAccountMembershipFactory.create(group=workspace.analyst_group, account=account) # Source workspace auth domains membership. GroupAccountMembershipFactory.create( group=source_workspace_1.workspace.authorization_domains.first(), @@ -828,9 +754,7 @@ def test_not_in_collab_auth_domain_two_source_workspaces_in_neither_auth_domains source_workspace_2 = CDSAWorkspaceFactory.create() workspace.source_workspaces.add(source_workspace_2.workspace) # Analyst group membership. - GroupAccountMembershipFactory.create( - group=workspace.analyst_group, account=account - ) + GroupAccountMembershipFactory.create(group=workspace.analyst_group, account=account) # Source workspace auth domains membership. # GroupAccountMembershipFactory.create( # group=source_workspace_1.workspace.authorization_domains.first(), @@ -861,17 +785,11 @@ def test_two_analysts(self): # Create an analyst that needs access. workspace = factories.CollaborativeAnalysisWorkspaceFactory.create() analyst_1 = AccountFactory.create() - GroupAccountMembershipFactory.create( - group=workspace.analyst_group, account=analyst_1 - ) + GroupAccountMembershipFactory.create(group=workspace.analyst_group, account=analyst_1) # Create an analyst that has access. analyst_2 = AccountFactory.create() - GroupAccountMembershipFactory.create( - group=workspace.analyst_group, account=analyst_2 - ) - GroupAccountMembershipFactory.create( - group=workspace.workspace.authorization_domains.first(), account=analyst_2 - ) + GroupAccountMembershipFactory.create(group=workspace.analyst_group, account=analyst_2) + GroupAccountMembershipFactory.create(group=workspace.workspace.authorization_domains.first(), account=analyst_2) collab_audit = audit.CollaborativeAnalysisWorkspaceAccessAudit() collab_audit._audit_workspace(workspace) self.assertEqual(len(collab_audit.verified), 1) @@ -893,9 +811,7 @@ def test_not_in_analyst_group(self): workspace = factories.CollaborativeAnalysisWorkspaceFactory.create() # Create an analyst that has access but is not in the analyst group. analyst = AccountFactory.create() - GroupAccountMembershipFactory.create( - group=workspace.workspace.authorization_domains.first(), account=analyst - ) + GroupAccountMembershipFactory.create(group=workspace.workspace.authorization_domains.first(), account=analyst) collab_audit = audit.CollaborativeAnalysisWorkspaceAccessAudit() collab_audit._audit_workspace(workspace) self.assertEqual(len(collab_audit.verified), 0) @@ -1015,15 +931,11 @@ def test_two_workspaces(self): # Create a workspace with an analyst that needs access. workspace_1 = factories.CollaborativeAnalysisWorkspaceFactory.create() analyst_1 = AccountFactory.create() - GroupAccountMembershipFactory.create( - group=workspace_1.analyst_group, account=analyst_1 - ) + GroupAccountMembershipFactory.create(group=workspace_1.analyst_group, account=analyst_1) # Create a workspace with an analyst that has access. workspace_2 = factories.CollaborativeAnalysisWorkspaceFactory.create() analyst_2 = AccountFactory.create() - GroupAccountMembershipFactory.create( - group=workspace_2.analyst_group, account=analyst_2 - ) + GroupAccountMembershipFactory.create(group=workspace_2.analyst_group, account=analyst_2) GroupAccountMembershipFactory.create( group=workspace_2.workspace.authorization_domains.first(), account=analyst_2 ) @@ -1048,21 +960,15 @@ def test_queryset(self): # Create a workspace with an analyst that needs access. workspace_1 = factories.CollaborativeAnalysisWorkspaceFactory.create() analyst_1 = AccountFactory.create() - GroupAccountMembershipFactory.create( - group=workspace_1.analyst_group, account=analyst_1 - ) + GroupAccountMembershipFactory.create(group=workspace_1.analyst_group, account=analyst_1) # Create a workspace with an analyst that has access. workspace_2 = factories.CollaborativeAnalysisWorkspaceFactory.create() analyst_2 = AccountFactory.create() - GroupAccountMembershipFactory.create( - group=workspace_2.analyst_group, account=analyst_2 - ) + GroupAccountMembershipFactory.create(group=workspace_2.analyst_group, account=analyst_2) GroupAccountMembershipFactory.create( group=workspace_2.workspace.authorization_domains.first(), account=analyst_2 ) - collab_audit_1 = audit.CollaborativeAnalysisWorkspaceAccessAudit( - queryset=[workspace_1] - ) + collab_audit_1 = audit.CollaborativeAnalysisWorkspaceAccessAudit(queryset=[workspace_1]) collab_audit_1.run_audit() self.assertEqual(len(collab_audit_1.verified), 0) self.assertEqual(len(collab_audit_1.needs_action), 1) @@ -1072,9 +978,7 @@ def test_queryset(self): self.assertEqual(record.collaborative_analysis_workspace, workspace_1) self.assertEqual(record.member, analyst_1) self.assertEqual(record.note, collab_audit_1.IN_SOURCE_AUTH_DOMAINS) - collab_audit_2 = audit.CollaborativeAnalysisWorkspaceAccessAudit( - queryset=[workspace_2] - ) + collab_audit_2 = audit.CollaborativeAnalysisWorkspaceAccessAudit(queryset=[workspace_2]) collab_audit_2.run_audit() self.assertEqual(len(collab_audit_2.verified), 1) self.assertEqual(len(collab_audit_2.needs_action), 0) diff --git a/primed/collaborative_analysis/tests/test_commands.py b/primed/collaborative_analysis/tests/test_commands.py index 2fa3be81..36e1e04c 100644 --- a/primed/collaborative_analysis/tests/test_commands.py +++ b/primed/collaborative_analysis/tests/test_commands.py @@ -24,9 +24,7 @@ def test_command_output_no_records(self): """Test command output.""" out = StringIO() call_command("run_collaborative_analysis_audit", "--no-color", stdout=out) - self.assertIn( - "Running Collaborative analysis access audit... ok!", out.getvalue() - ) + self.assertIn("Running Collaborative analysis access audit... ok!", out.getvalue()) self.assertIn("* Verified: 0", out.getvalue()) self.assertIn("* Needs action: 0", out.getvalue()) self.assertIn("* Errors: 0", out.getvalue()) @@ -42,9 +40,7 @@ def test_command_run_audit_one_instance_verified(self): GroupAccountMembershipFactory.create(group=workspace.analyst_group) out = StringIO() call_command("run_collaborative_analysis_audit", "--no-color", stdout=out) - self.assertIn( - "Running Collaborative analysis access audit... ok!", out.getvalue() - ) + self.assertIn("Running Collaborative analysis access audit... ok!", out.getvalue()) self.assertIn("* Verified: 1", out.getvalue()) self.assertIn("* Needs action: 0", out.getvalue()) self.assertIn("* Errors: 0", out.getvalue()) @@ -76,9 +72,7 @@ def test_command_run_audit_one_instance_error(self): workspace = factories.CollaborativeAnalysisWorkspaceFactory.create() workspace.source_workspaces.add(source_workspace.workspace) # One group with unexpected access. - GroupGroupMembershipFactory.create( - parent_group=workspace.workspace.authorization_domains.first() - ) + GroupGroupMembershipFactory.create(parent_group=workspace.workspace.authorization_domains.first()) out = StringIO() call_command("run_collaborative_analysis_audit", "--no-color", stdout=out) self.assertIn( @@ -105,9 +99,7 @@ def test_command_run_audit_one_instance_verified_email(self): email="test@example.com", stdout=out, ) - self.assertIn( - "Running Collaborative analysis access audit... ok!", out.getvalue() - ) + self.assertIn("Running Collaborative analysis access audit... ok!", out.getvalue()) # Zero messages have been sent by default. self.assertEqual(len(mail.outbox), 0) @@ -137,9 +129,7 @@ def test_command_run_audit_one_instance_needs_action_email(self): self.assertEqual(len(mail.outbox), 1) email = mail.outbox[0] self.assertEqual(email.to, ["test@example.com"]) - self.assertEqual( - email.subject, "Collaborative analysis access audit - problems found" - ) + self.assertEqual(email.subject, "Collaborative analysis access audit - problems found") def test_command_run_audit_one_instance_error_email(self): """Test command output with one error instance.""" @@ -148,9 +138,7 @@ def test_command_run_audit_one_instance_error_email(self): workspace = factories.CollaborativeAnalysisWorkspaceFactory.create() workspace.source_workspaces.add(source_workspace.workspace) # One group with unexpected access. - GroupGroupMembershipFactory.create( - parent_group=workspace.workspace.authorization_domains.first() - ) + GroupGroupMembershipFactory.create(parent_group=workspace.workspace.authorization_domains.first()) out = StringIO() call_command( "run_collaborative_analysis_audit", @@ -169,9 +157,7 @@ def test_command_run_audit_one_instance_error_email(self): self.assertEqual(len(mail.outbox), 1) email = mail.outbox[0] self.assertEqual(email.to, ["test@example.com"]) - self.assertEqual( - email.subject, "Collaborative analysis access audit - problems found" - ) + self.assertEqual(email.subject, "Collaborative analysis access audit - problems found") def test_different_domain(self): """Test command output when a different domain is specified.""" diff --git a/primed/collaborative_analysis/tests/test_tables.py b/primed/collaborative_analysis/tests/test_tables.py index f8482f99..4399fc59 100644 --- a/primed/collaborative_analysis/tests/test_tables.py +++ b/primed/collaborative_analysis/tests/test_tables.py @@ -38,9 +38,7 @@ def test_number_source_workspaces_one(self): source_workspace = WorkspaceFactory.create() obj = self.model_factory.create() obj.source_workspaces.add(source_workspace) - table = self.table_class( - self.model.objects.filter(workspace_type="collab_analysis") - ) + table = self.table_class(self.model.objects.filter(workspace_type="collab_analysis")) self.assertEqual(table.rows[0].get_cell("number_source_workspaces"), 1) def test_number_source_workspaces_two(self): @@ -50,9 +48,7 @@ def test_number_source_workspaces_two(self): obj = self.model_factory.create() obj.source_workspaces.add(source_workspace_1) obj.source_workspaces.add(source_workspace_2) - table = self.table_class( - self.model.objects.filter(workspace_type="collab_analysis") - ) + table = self.table_class(self.model.objects.filter(workspace_type="collab_analysis")) self.assertEqual(table.rows[0].get_cell("number_source_workspaces"), 2) @@ -86,9 +82,7 @@ def test_number_source_workspaces_one(self): source_workspace = WorkspaceFactory.create() obj = self.model_factory.create() obj.source_workspaces.add(source_workspace) - table = self.table_class( - self.model.objects.filter(workspace_type="collab_analysis") - ) + table = self.table_class(self.model.objects.filter(workspace_type="collab_analysis")) self.assertEqual(table.rows[0].get_cell("number_source_workspaces"), 1) def test_number_source_workspaces_two(self): @@ -98,7 +92,5 @@ def test_number_source_workspaces_two(self): obj = self.model_factory.create() obj.source_workspaces.add(source_workspace_1) obj.source_workspaces.add(source_workspace_2) - table = self.table_class( - self.model.objects.filter(workspace_type="collab_analysis") - ) + table = self.table_class(self.model.objects.filter(workspace_type="collab_analysis")) self.assertEqual(table.rows[0].get_cell("number_source_workspaces"), 2) diff --git a/primed/collaborative_analysis/tests/test_views.py b/primed/collaborative_analysis/tests/test_views.py index 361f8fc4..36327a31 100644 --- a/primed/collaborative_analysis/tests/test_views.py +++ b/primed/collaborative_analysis/tests/test_views.py @@ -58,9 +58,7 @@ def test_links_for_staff_view(self): """Returns successful response code.""" user = User.objects.create_user(username="test", password="test") user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.client.force_login(user) response = self.client.get(self.get_url()) @@ -69,11 +67,7 @@ def test_links_for_staff_view(self): def test_links_for_view(self): """Returns successful response code.""" user = User.objects.create_user(username="test", password="test") - user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) - ) + user.user_permissions.add(Permission.objects.get(codename=AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME)) self.client.force_login(user) response = self.client.get(self.get_url()) self.assertNotContains(response, reverse("collaborative_analysis:audit:all")) @@ -86,9 +80,7 @@ def setUp(self): """Set up test class.""" self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def test_status_code_with_user_permission(self): @@ -114,29 +106,21 @@ def test_links_to_source_workspace(self): response = self.client.get(obj.workspace.get_absolute_url()) self.assertIn(dbgap_workspace.get_absolute_url(), response.content.decode()) self.assertIn(cdsa_workspace.get_absolute_url(), response.content.decode()) - self.assertIn( - open_access_workspace.get_absolute_url(), response.content.decode() - ) + self.assertIn(open_access_workspace.get_absolute_url(), response.content.decode()) def test_link_to_custodian(self): """Links to the custodian's user profile appear on the detail page.""" custodian = UserFactory.create() - obj = factories.CollaborativeAnalysisWorkspaceFactory.create( - custodian=custodian - ) + obj = factories.CollaborativeAnalysisWorkspaceFactory.create(custodian=custodian) self.client.force_login(self.user) response = self.client.get(obj.workspace.get_absolute_url()) self.assertIn(custodian.get_absolute_url(), response.content.decode()) def test_link_to_analyst_group_staff_view(self): """Links to the analyst group's detail page appear on the detail page for staff_viewers.""" - user = User.objects.create_user( - username="test-staff-view", password="test-staff-view" - ) + user = User.objects.create_user(username="test-staff-view", password="test-staff-view") user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) obj = factories.CollaborativeAnalysisWorkspaceFactory.create() self.client.force_login(user) @@ -149,20 +133,14 @@ def test_link_to_analyst_group_view(self): obj = factories.CollaborativeAnalysisWorkspaceFactory.create() self.client.force_login(self.user) response = self.client.get(obj.workspace.get_absolute_url()) - self.assertNotIn( - obj.analyst_group.get_absolute_url(), response.content.decode() - ) + self.assertNotIn(obj.analyst_group.get_absolute_url(), response.content.decode()) self.assertNotIn(obj.analyst_group.name, response.content.decode()) def test_link_to_audit_staff_view(self): """Links to the audit view page do appear on the detail page for staff viewers.""" - user = User.objects.create_user( - username="test-staff-view", password="test-staff-view" - ) + user = User.objects.create_user(username="test-staff-view", password="test-staff-view") user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) obj = factories.CollaborativeAnalysisWorkspaceFactory.create() self.client.force_login(user) @@ -199,14 +177,10 @@ def setUp(self): # Create a user with both view and edit permissions. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) self.workspace_type = "collab_analysis" self.custodian = UserFactory.create() @@ -270,14 +244,10 @@ def setUp(self): # Create a user with both view and edit permissions. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) self.custodian = UserFactory.create() self.source_workspace = dbGaPWorkspaceFactory.create().workspace @@ -290,25 +260,15 @@ def get_url(self, *args): def get_api_url(self, billing_project_name, workspace_name): """Return the Terra API url for a given billing project and workspace.""" - return ( - self.api_client.rawls_entry_point - + "/api/workspaces/" - + billing_project_name - + "/" - + workspace_name - ) + return self.api_client.rawls_entry_point + "/api/workspaces/" + billing_project_name + "/" + workspace_name - def get_api_json_response( - self, billing_project, workspace, authorization_domains=[], access="OWNER" - ): + def get_api_json_response(self, billing_project, workspace, authorization_domains=[], access="OWNER"): """Return a pared down version of the json response from the AnVIL API with only fields we need.""" json_data = { "accessLevel": access, "owners": [], "workspace": { - "authorizationDomain": [ - {"membersGroupName": x} for x in authorization_domains - ], + "authorizationDomain": [{"membersGroupName": x} for x in authorization_domains], "name": workspace, "namespace": billing_project, "isLocked": False, @@ -326,9 +286,7 @@ def test_creates_workspace(self): responses.GET, workspace_list_url, match=[ - responses.matchers.query_param_matcher( - {"fields": "workspace.namespace,workspace.name,accessLevel"} - ) + responses.matchers.query_param_matcher({"fields": "workspace.namespace,workspace.name,accessLevel"}) ], status=200, json=[self.get_api_json_response(billing_project.name, workspace_name)], @@ -398,13 +356,9 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) - ) - self.collaborative_analysis_workspace = ( - factories.CollaborativeAnalysisWorkspaceFactory.create() + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) + self.collaborative_analysis_workspace = factories.CollaborativeAnalysisWorkspaceFactory.create() def get_url(self, *args): """Get the url for the view being tested.""" @@ -444,9 +398,7 @@ def test_status_code_with_user_permission_view(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get( self.get_url( self.collaborative_analysis_workspace.workspace.billing_project.name, @@ -463,9 +415,7 @@ def test_access_without_user_permission(self): def test_invalid_billing_project_name(self): """Raises a 404 error with an invalid object dbgap_application_pk.""" - request = self.factory.get( - self.get_url("foo", self.collaborative_analysis_workspace.workspace.name) - ) + request = self.factory.get(self.get_url("foo", self.collaborative_analysis_workspace.workspace.name)) request.user = self.user with self.assertRaises(Http404): self.get_view()( @@ -476,9 +426,7 @@ def test_invalid_billing_project_name(self): def test_invalid_workspace_name(self): """Raises a 404 error with an invalid object dbgap_application_pk.""" - request = self.factory.get( - self.get_url(self.collaborative_analysis_workspace.workspace.name, "foo") - ) + request = self.factory.get(self.get_url(self.collaborative_analysis_workspace.workspace.name, "foo")) request.user = self.user with self.assertRaises(Http404): self.get_view()( @@ -512,13 +460,9 @@ def test_context_verified_table_access(self): account = AccountFactory.create() # Set up source workspaces. source_workspace = dbGaPWorkspaceFactory.create() - self.collaborative_analysis_workspace.source_workspaces.add( - source_workspace.workspace - ) + self.collaborative_analysis_workspace.source_workspaces.add(source_workspace.workspace) # Analyst group membership. - GroupAccountMembershipFactory.create( - group=self.collaborative_analysis_workspace.analyst_group, account=account - ) + GroupAccountMembershipFactory.create(group=self.collaborative_analysis_workspace.analyst_group, account=account) # Source workspace auth domains membership. GroupAccountMembershipFactory.create( group=source_workspace.workspace.authorization_domains.first(), @@ -561,13 +505,9 @@ def test_context_verified_table_no_access(self): account = AccountFactory.create() # Set up source workspaces. source_workspace = dbGaPWorkspaceFactory.create() - self.collaborative_analysis_workspace.source_workspaces.add( - source_workspace.workspace - ) + self.collaborative_analysis_workspace.source_workspaces.add(source_workspace.workspace) # Analyst group membership. - GroupAccountMembershipFactory.create( - group=self.collaborative_analysis_workspace.analyst_group, account=account - ) + GroupAccountMembershipFactory.create(group=self.collaborative_analysis_workspace.analyst_group, account=account) # Source workspace auth domains membership. # GroupAccountMembershipFactory.create( # group=source_workspace.workspace.authorization_domains.first(), @@ -609,13 +549,9 @@ def test_context_needs_action_table_grant(self): account = AccountFactory.create() # Set up source workspaces. source_workspace = dbGaPWorkspaceFactory.create() - self.collaborative_analysis_workspace.source_workspaces.add( - source_workspace.workspace - ) + self.collaborative_analysis_workspace.source_workspaces.add(source_workspace.workspace) # Analyst group membership. - GroupAccountMembershipFactory.create( - group=self.collaborative_analysis_workspace.analyst_group, account=account - ) + GroupAccountMembershipFactory.create(group=self.collaborative_analysis_workspace.analyst_group, account=account) # Source workspace auth domains membership. GroupAccountMembershipFactory.create( group=source_workspace.workspace.authorization_domains.first(), @@ -657,13 +593,9 @@ def test_context_needs_action_table_remoe(self): account = AccountFactory.create() # Set up source workspaces. source_workspace = dbGaPWorkspaceFactory.create() - self.collaborative_analysis_workspace.source_workspaces.add( - source_workspace.workspace - ) + self.collaborative_analysis_workspace.source_workspaces.add(source_workspace.workspace) # Analyst group membership. - GroupAccountMembershipFactory.create( - group=self.collaborative_analysis_workspace.analyst_group, account=account - ) + GroupAccountMembershipFactory.create(group=self.collaborative_analysis_workspace.analyst_group, account=account) # Source workspace auth domains membership. # GroupAccountMembershipFactory.create( # group=source_workspace.workspace.authorization_domains.first(), @@ -744,9 +676,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -778,9 +708,7 @@ def test_status_code_with_user_permission_view(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url()) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -840,9 +768,7 @@ def test_context_verified_table_access(self): source_workspace = dbGaPWorkspaceFactory.create() instance.source_workspaces.add(source_workspace.workspace) # Analyst group membership. - GroupAccountMembershipFactory.create( - group=instance.analyst_group, account=account - ) + GroupAccountMembershipFactory.create(group=instance.analyst_group, account=account) # Source workspace auth domains membership. GroupAccountMembershipFactory.create( group=source_workspace.workspace.authorization_domains.first(), @@ -883,9 +809,7 @@ def test_context_verified_table_no_access(self): source_workspace = dbGaPWorkspaceFactory.create() instance.source_workspaces.add(source_workspace.workspace) # Analyst group membership. - GroupAccountMembershipFactory.create( - group=instance.analyst_group, account=account - ) + GroupAccountMembershipFactory.create(group=instance.analyst_group, account=account) # Source workspace auth domains membership. # GroupAccountMembershipFactory.create( # group=source_workspace.workspace.authorization_domains.first(), @@ -925,9 +849,7 @@ def test_context_needs_action_table_grant(self): source_workspace = dbGaPWorkspaceFactory.create() instance.source_workspaces.add(source_workspace.workspace) # Analyst group membership. - GroupAccountMembershipFactory.create( - group=instance.analyst_group, account=account - ) + GroupAccountMembershipFactory.create(group=instance.analyst_group, account=account) # Source workspace auth domains membership. GroupAccountMembershipFactory.create( group=source_workspace.workspace.authorization_domains.first(), @@ -967,9 +889,7 @@ def test_context_needs_action_table_remove(self): source_workspace = dbGaPWorkspaceFactory.create() instance.source_workspaces.add(source_workspace.workspace) # Analyst group membership. - GroupAccountMembershipFactory.create( - group=instance.analyst_group, account=account - ) + GroupAccountMembershipFactory.create(group=instance.analyst_group, account=account) # Source workspace auth domains membership. # GroupAccountMembershipFactory.create( # group=source_workspace.workspace.authorization_domains.first(), @@ -1042,14 +962,10 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -1069,9 +985,7 @@ def test_view_redirect_not_logged_in(self): response = self.client.get(self.get_url("foo", "bar", "test@example.com")) self.assertRedirects( response, - resolve_url(settings.LOGIN_URL) - + "?next=" - + self.get_url("foo", "bar", "test@example.com"), + resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url("foo", "bar", "test@example.com"), ) def test_status_code_account_with_user_permission_view(self): @@ -1104,9 +1018,7 @@ def test_status_code_group_with_user_permission_view(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url("foo", "bar", "test@example.com")) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -1117,9 +1029,7 @@ def test_invalid_billing_project_name(self): collab_workspace = factories.CollaborativeAnalysisWorkspaceFactory.create() account = AccountFactory.create() self.client.force_login(self.user) - response = self.client.get( - self.get_url("foo", collab_workspace.workspace.name, account.email) - ) + response = self.client.get(self.get_url("foo", collab_workspace.workspace.name, account.email)) self.assertEqual(response.status_code, 404) def test_invalid_workspace_name(self): @@ -1127,11 +1037,7 @@ def test_invalid_workspace_name(self): collab_workspace = factories.CollaborativeAnalysisWorkspaceFactory.create() account = AccountFactory.create() self.client.force_login(self.user) - response = self.client.get( - self.get_url( - collab_workspace.workspace.billing_project.name, "foo", account.email - ) - ) + response = self.client.get(self.get_url(collab_workspace.workspace.billing_project.name, "foo", account.email)) self.assertEqual(response.status_code, 404) def test_invalid_email(self): @@ -1544,9 +1450,7 @@ def test_post_verified_no_access_group(self): def test_post_grant_access_account(self): """Get request with verified access.""" - workspace = factories.CollaborativeAnalysisWorkspaceFactory.create( - workspace__name="TEST_COLLAB" - ) + workspace = factories.CollaborativeAnalysisWorkspaceFactory.create(workspace__name="TEST_COLLAB") account = AccountFactory.create(email="test@example.com") # Analyst group membership. GroupAccountMembershipFactory.create( @@ -1560,10 +1464,7 @@ def test_post_grant_access_account(self): # ) # Add API response # Note that the auth domain group is created automatically by the factory using the workspace name. - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/auth_TEST_COLLAB/member/test@example.com" - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/auth_TEST_COLLAB/member/test@example.com" self.anvil_response_mock.add( responses.PUT, api_url, @@ -1588,9 +1489,7 @@ def test_post_grant_access_account(self): def test_post_grant_access_group(self): """Get request with verified access for a group.""" - workspace = factories.CollaborativeAnalysisWorkspaceFactory.create( - workspace__name="TEST_COLLAB" - ) + workspace = factories.CollaborativeAnalysisWorkspaceFactory.create(workspace__name="TEST_COLLAB") group = ManagedGroupFactory.create(name="PRIMED_CC_WRITERS") # Auth domain membership. # GroupGroupMembershipFactory.create( @@ -1600,8 +1499,7 @@ def test_post_grant_access_group(self): # Add API response # Note that the auth domain group is created automatically by the factory using the workspace name. api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/auth_TEST_COLLAB/member/PRIMED_CC_WRITERS@firecloud.org" + self.api_client.sam_entry_point + "/api/groups/v1/auth_TEST_COLLAB/member/PRIMED_CC_WRITERS@firecloud.org" ) self.anvil_response_mock.add( responses.PUT, @@ -1627,9 +1525,7 @@ def test_post_grant_access_group(self): def test_post_remove_access_account(self): """Get request with verified access.""" - workspace = factories.CollaborativeAnalysisWorkspaceFactory.create( - workspace__name="TEST_COLLAB" - ) + workspace = factories.CollaborativeAnalysisWorkspaceFactory.create(workspace__name="TEST_COLLAB") account = AccountFactory.create(email="test@example.com") # Analyst group membership. # GroupAccountMembershipFactory.create( @@ -1643,10 +1539,7 @@ def test_post_remove_access_account(self): ) # Add API response # Note that the auth domain group is created automatically by the factory using the workspace name. - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/auth_TEST_COLLAB/member/test@example.com" - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/auth_TEST_COLLAB/member/test@example.com" self.anvil_response_mock.add( responses.DELETE, api_url, @@ -1667,9 +1560,7 @@ def test_post_remove_access_account(self): def test_post_remove_access_group(self): """Get request with verified access for a group.""" - workspace = factories.CollaborativeAnalysisWorkspaceFactory.create( - workspace__name="TEST_COLLAB" - ) + workspace = factories.CollaborativeAnalysisWorkspaceFactory.create(workspace__name="TEST_COLLAB") group = ManagedGroupFactory.create(name="test-group") # Auth domain membership. membership = GroupGroupMembershipFactory.create( @@ -1678,10 +1569,7 @@ def test_post_remove_access_group(self): ) # Add API response # Note that the auth domain group is created automatically by the factory using the workspace name. - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/auth_TEST_COLLAB/member/test-group@firecloud.org" - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/auth_TEST_COLLAB/member/test-group@firecloud.org" self.anvil_response_mock.add( responses.DELETE, api_url, @@ -1702,9 +1590,7 @@ def test_post_remove_access_group(self): def test_post_grant_access_account_htmx(self): """Get request with verified access.""" - workspace = factories.CollaborativeAnalysisWorkspaceFactory.create( - workspace__name="TEST_COLLAB" - ) + workspace = factories.CollaborativeAnalysisWorkspaceFactory.create(workspace__name="TEST_COLLAB") account = AccountFactory.create(email="test@example.com") # Analyst group membership. GroupAccountMembershipFactory.create( @@ -1718,10 +1604,7 @@ def test_post_grant_access_account_htmx(self): # ) # Add API response # Note that the auth domain group is created automatically by the factory using the workspace name. - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/auth_TEST_COLLAB/member/test@example.com" - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/auth_TEST_COLLAB/member/test@example.com" self.anvil_response_mock.add( responses.PUT, api_url, @@ -1736,7 +1619,7 @@ def test_post_grant_access_account_htmx(self): account.email, ), {}, - **header + **header, ) self.assertEqual( response.content.decode(), @@ -1751,9 +1634,7 @@ def test_post_grant_access_account_htmx(self): def test_post_grant_access_group_htmx(self): """Get request with verified access for a group.""" - workspace = factories.CollaborativeAnalysisWorkspaceFactory.create( - workspace__name="TEST_COLLAB" - ) + workspace = factories.CollaborativeAnalysisWorkspaceFactory.create(workspace__name="TEST_COLLAB") group = ManagedGroupFactory.create(name="PRIMED_CC_WRITERS") # Auth domain membership. # GroupGroupMembershipFactory.create( @@ -1763,8 +1644,7 @@ def test_post_grant_access_group_htmx(self): # Add API response # Note that the auth domain group is created automatically by the factory using the workspace name. api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/auth_TEST_COLLAB/member/PRIMED_CC_WRITERS@firecloud.org" + self.api_client.sam_entry_point + "/api/groups/v1/auth_TEST_COLLAB/member/PRIMED_CC_WRITERS@firecloud.org" ) self.anvil_response_mock.add( responses.PUT, @@ -1780,7 +1660,7 @@ def test_post_grant_access_group_htmx(self): group.email, ), {}, - **header + **header, ) self.assertEqual( response.content.decode(), @@ -1795,9 +1675,7 @@ def test_post_grant_access_group_htmx(self): def test_post_remove_access_account_htmx(self): """Get request with verified access.""" - workspace = factories.CollaborativeAnalysisWorkspaceFactory.create( - workspace__name="TEST_COLLAB" - ) + workspace = factories.CollaborativeAnalysisWorkspaceFactory.create(workspace__name="TEST_COLLAB") account = AccountFactory.create(email="test@example.com") # Analyst group membership. # GroupAccountMembershipFactory.create( @@ -1811,10 +1689,7 @@ def test_post_remove_access_account_htmx(self): ) # Add API response # Note that the auth domain group is created automatically by the factory using the workspace name. - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/auth_TEST_COLLAB/member/test@example.com" - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/auth_TEST_COLLAB/member/test@example.com" self.anvil_response_mock.add( responses.DELETE, api_url, @@ -1829,7 +1704,7 @@ def test_post_remove_access_account_htmx(self): account.email, ), {}, - **header + **header, ) self.assertEqual( response.content.decode(), @@ -1840,9 +1715,7 @@ def test_post_remove_access_account_htmx(self): def test_post_remove_access_group_htmx(self): """Get request with verified access for a group.""" - workspace = factories.CollaborativeAnalysisWorkspaceFactory.create( - workspace__name="TEST_COLLAB" - ) + workspace = factories.CollaborativeAnalysisWorkspaceFactory.create(workspace__name="TEST_COLLAB") group = ManagedGroupFactory.create(name="test-group") # Auth domain membership. membership = GroupGroupMembershipFactory.create( @@ -1851,10 +1724,7 @@ def test_post_remove_access_group_htmx(self): ) # Add API response # Note that the auth domain group is created automatically by the factory using the workspace name. - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/auth_TEST_COLLAB/member/test-group@firecloud.org" - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/auth_TEST_COLLAB/member/test-group@firecloud.org" self.anvil_response_mock.add( responses.DELETE, api_url, @@ -1869,7 +1739,7 @@ def test_post_remove_access_group_htmx(self): group.email, ), {}, - **header + **header, ) self.assertEqual( response.content.decode(), @@ -1880,9 +1750,7 @@ def test_post_remove_access_group_htmx(self): def test_anvil_error_grant_access_account(self): """Get request with verified access.""" - workspace = factories.CollaborativeAnalysisWorkspaceFactory.create( - workspace__name="TEST_COLLAB" - ) + workspace = factories.CollaborativeAnalysisWorkspaceFactory.create(workspace__name="TEST_COLLAB") account = AccountFactory.create(email="test@example.com") # Analyst group membership. GroupAccountMembershipFactory.create( @@ -1896,10 +1764,7 @@ def test_anvil_error_grant_access_account(self): # ) # Add API response # Note that the auth domain group is created automatically by the factory using the workspace name. - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/auth_TEST_COLLAB/member/test@example.com" - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/auth_TEST_COLLAB/member/test@example.com" self.anvil_response_mock.add( responses.PUT, api_url, @@ -1929,9 +1794,7 @@ def test_anvil_error_grant_access_account(self): def test_anvil_error_grant_access_group(self): """Get request with verified access for a group.""" - workspace = factories.CollaborativeAnalysisWorkspaceFactory.create( - workspace__name="TEST_COLLAB" - ) + workspace = factories.CollaborativeAnalysisWorkspaceFactory.create(workspace__name="TEST_COLLAB") group = ManagedGroupFactory.create(name="PRIMED_CC_WRITERS") # Auth domain membership. # GroupGroupMembershipFactory.create( @@ -1941,8 +1804,7 @@ def test_anvil_error_grant_access_group(self): # Add API response # Note that the auth domain group is created automatically by the factory using the workspace name. api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/auth_TEST_COLLAB/member/PRIMED_CC_WRITERS@firecloud.org" + self.api_client.sam_entry_point + "/api/groups/v1/auth_TEST_COLLAB/member/PRIMED_CC_WRITERS@firecloud.org" ) self.anvil_response_mock.add( responses.PUT, @@ -1973,9 +1835,7 @@ def test_anvil_error_grant_access_group(self): def test_anvil_error_remove_access_account(self): """Get request with verified access.""" - workspace = factories.CollaborativeAnalysisWorkspaceFactory.create( - workspace__name="TEST_COLLAB" - ) + workspace = factories.CollaborativeAnalysisWorkspaceFactory.create(workspace__name="TEST_COLLAB") account = AccountFactory.create(email="test@example.com") # Analyst group membership. # GroupAccountMembershipFactory.create( @@ -1989,10 +1849,7 @@ def test_anvil_error_remove_access_account(self): ) # Add API response # Note that the auth domain group is created automatically by the factory using the workspace name. - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/auth_TEST_COLLAB/member/test@example.com" - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/auth_TEST_COLLAB/member/test@example.com" self.anvil_response_mock.add( responses.DELETE, api_url, @@ -2022,9 +1879,7 @@ def test_anvil_error_remove_access_account(self): def test_anvil_error_remove_access_group(self): """Get request with verified access for a group.""" - workspace = factories.CollaborativeAnalysisWorkspaceFactory.create( - workspace__name="TEST_COLLAB" - ) + workspace = factories.CollaborativeAnalysisWorkspaceFactory.create(workspace__name="TEST_COLLAB") group = ManagedGroupFactory.create(name="test-group") # Auth domain membership. membership = GroupGroupMembershipFactory.create( @@ -2033,10 +1888,7 @@ def test_anvil_error_remove_access_group(self): ) # Add API response # Note that the auth domain group is created automatically by the factory using the workspace name. - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/auth_TEST_COLLAB/member/test-group@firecloud.org" - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/auth_TEST_COLLAB/member/test-group@firecloud.org" self.anvil_response_mock.add( responses.DELETE, api_url, @@ -2066,9 +1918,7 @@ def test_anvil_error_remove_access_group(self): def test_anvil_error_grant_access_account_htmx(self): """Get request with verified access.""" - workspace = factories.CollaborativeAnalysisWorkspaceFactory.create( - workspace__name="TEST_COLLAB" - ) + workspace = factories.CollaborativeAnalysisWorkspaceFactory.create(workspace__name="TEST_COLLAB") account = AccountFactory.create(email="test@example.com") # Analyst group membership. GroupAccountMembershipFactory.create( @@ -2082,10 +1932,7 @@ def test_anvil_error_grant_access_account_htmx(self): # ) # Add API response # Note that the auth domain group is created automatically by the factory using the workspace name. - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/auth_TEST_COLLAB/member/test@example.com" - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/auth_TEST_COLLAB/member/test@example.com" self.anvil_response_mock.add( responses.PUT, api_url, @@ -2101,7 +1948,7 @@ def test_anvil_error_grant_access_account_htmx(self): account.email, ), {}, - **header + **header, ) self.assertEqual( response.content.decode(), @@ -2115,9 +1962,7 @@ def test_anvil_error_grant_access_account_htmx(self): def test_anvil_error_grant_access_group_htmx(self): """Get request with verified access for a group.""" - workspace = factories.CollaborativeAnalysisWorkspaceFactory.create( - workspace__name="TEST_COLLAB" - ) + workspace = factories.CollaborativeAnalysisWorkspaceFactory.create(workspace__name="TEST_COLLAB") group = ManagedGroupFactory.create(name="PRIMED_CC_WRITERS") # Auth domain membership. # GroupGroupMembershipFactory.create( @@ -2127,8 +1972,7 @@ def test_anvil_error_grant_access_group_htmx(self): # Add API response # Note that the auth domain group is created automatically by the factory using the workspace name. api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/auth_TEST_COLLAB/member/PRIMED_CC_WRITERS@firecloud.org" + self.api_client.sam_entry_point + "/api/groups/v1/auth_TEST_COLLAB/member/PRIMED_CC_WRITERS@firecloud.org" ) self.anvil_response_mock.add( responses.PUT, @@ -2145,7 +1989,7 @@ def test_anvil_error_grant_access_group_htmx(self): group.email, ), {}, - **header + **header, ) self.assertEqual( response.content.decode(), @@ -2159,9 +2003,7 @@ def test_anvil_error_grant_access_group_htmx(self): def test_anvil_error_remove_access_account_htmx(self): """Get request with verified access.""" - workspace = factories.CollaborativeAnalysisWorkspaceFactory.create( - workspace__name="TEST_COLLAB" - ) + workspace = factories.CollaborativeAnalysisWorkspaceFactory.create(workspace__name="TEST_COLLAB") account = AccountFactory.create(email="test@example.com") # Analyst group membership. # GroupAccountMembershipFactory.create( @@ -2175,10 +2017,7 @@ def test_anvil_error_remove_access_account_htmx(self): ) # Add API response # Note that the auth domain group is created automatically by the factory using the workspace name. - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/auth_TEST_COLLAB/member/test@example.com" - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/auth_TEST_COLLAB/member/test@example.com" self.anvil_response_mock.add( responses.DELETE, api_url, @@ -2194,7 +2033,7 @@ def test_anvil_error_remove_access_account_htmx(self): account.email, ), {}, - **header + **header, ) self.assertEqual( response.content.decode(), @@ -2208,9 +2047,7 @@ def test_anvil_error_remove_access_account_htmx(self): def test_anvil_error_remove_access_group_htmx(self): """Get request with verified access for a group.""" - workspace = factories.CollaborativeAnalysisWorkspaceFactory.create( - workspace__name="TEST_COLLAB" - ) + workspace = factories.CollaborativeAnalysisWorkspaceFactory.create(workspace__name="TEST_COLLAB") group = ManagedGroupFactory.create(name="test-group") # Auth domain membership. membership = GroupGroupMembershipFactory.create( @@ -2219,10 +2056,7 @@ def test_anvil_error_remove_access_group_htmx(self): ) # Add API response # Note that the auth domain group is created automatically by the factory using the workspace name. - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/auth_TEST_COLLAB/member/test-group@firecloud.org" - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/auth_TEST_COLLAB/member/test-group@firecloud.org" self.anvil_response_mock.add( responses.DELETE, api_url, @@ -2238,7 +2072,7 @@ def test_anvil_error_remove_access_group_htmx(self): group.email, ), {}, - **header + **header, ) self.assertEqual( response.content.decode(), diff --git a/primed/collaborative_analysis/views.py b/primed/collaborative_analysis/views.py index fe3e08f2..d27205b4 100644 --- a/primed/collaborative_analysis/views.py +++ b/primed/collaborative_analysis/views.py @@ -42,17 +42,14 @@ def get_object(self, queryset=None): obj = queryset.get() except queryset.model.DoesNotExist: raise Http404( - _("No %(verbose_name)s found matching the query") - % {"verbose_name": queryset.model._meta.verbose_name} + _("No %(verbose_name)s found matching the query") % {"verbose_name": queryset.model._meta.verbose_name} ) return obj def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # Run the audit - data_access_audit = audit.CollaborativeAnalysisWorkspaceAccessAudit( - queryset=[self.object] - ) + data_access_audit = audit.CollaborativeAnalysisWorkspaceAccessAudit(queryset=[self.object]) data_access_audit.run_audit() context["verified_table"] = data_access_audit.get_verified_table() context["errors_table"] = data_access_audit.get_errors_table() @@ -64,9 +61,7 @@ def get_context_data(self, **kwargs): class WorkspaceAuditAll(AnVILConsortiumManagerStaffViewRequired, TemplateView): """View to show audit results for all `CollaborativeAnalysisWorkspace` objects.""" - template_name = ( - "collaborative_analysis/collaborativeanalysisworkspace_audit_all.html" - ) + template_name = "collaborative_analysis/collaborativeanalysisworkspace_audit_all.html" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) @@ -82,10 +77,7 @@ def get_context_data(self, **kwargs): return context -class CollaborativeAnalysisAuditResolve( - AnVILConsortiumManagerStaffEditRequired, FormView -): - +class CollaborativeAnalysisAuditResolve(AnVILConsortiumManagerStaffEditRequired, FormView): form_class = Form template_name = "collaborative_analysis/audit_resolve.html" htmx_success = """ Handled!""" @@ -105,8 +97,7 @@ def get_collaborative_analysis_workspace(self): obj = queryset.get() except queryset.model.DoesNotExist: raise Http404( - _("No %(verbose_name)s found matching the query") - % {"verbose_name": queryset.model._meta.verbose_name} + _("No %(verbose_name)s found matching the query") % {"verbose_name": queryset.model._meta.verbose_name} ) return obj @@ -125,50 +116,37 @@ def get_member(self): return ManagedGroup.objects.get(email=email) except ManagedGroup.DoesNotExist: raise Http404( - _("No %(verbose_name)s found matching the query") - % {"verbose_name": "Account or ManagedGroup"} + _("No %(verbose_name)s found matching the query") % {"verbose_name": "Account or ManagedGroup"} ) def get_audit_result(self): instance = audit.CollaborativeAnalysisWorkspaceAccessAudit( - queryset=models.CollaborativeAnalysisWorkspace.objects.filter( - pk=self.collaborative_analysis_workspace.pk - ) + queryset=models.CollaborativeAnalysisWorkspace.objects.filter(pk=self.collaborative_analysis_workspace.pk) ) # No way to include a queryset of members at this point - need to call the sub method directly. if isinstance(self.member, Account): - instance._audit_workspace_and_account( - self.collaborative_analysis_workspace, self.member - ) + instance._audit_workspace_and_account(self.collaborative_analysis_workspace, self.member) else: - instance._audit_workspace_and_group( - self.collaborative_analysis_workspace, self.member - ) + instance._audit_workspace_and_group(self.collaborative_analysis_workspace, self.member) # Set to completed, because we are just running this one specific check. instance.completed = True return instance.get_all_results()[0] def get(self, request, *args, **kwargs): - self.collaborative_analysis_workspace = ( - self.get_collaborative_analysis_workspace() - ) + self.collaborative_analysis_workspace = self.get_collaborative_analysis_workspace() self.member = self.get_member() self.audit_result = self.get_audit_result() return super().get(request, *args, **kwargs) def post(self, request, *args, **kwargs): - self.collaborative_analysis_workspace = ( - self.get_collaborative_analysis_workspace() - ) + self.collaborative_analysis_workspace = self.get_collaborative_analysis_workspace() self.member = self.get_member() self.audit_result = self.get_audit_result() return super().post(request, *args, **kwargs) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context[ - "collaborative_analysis_workspace" - ] = self.collaborative_analysis_workspace + context["collaborative_analysis_workspace"] = self.collaborative_analysis_workspace context["member"] = self.member context["audit_result"] = self.audit_result return context @@ -177,9 +155,7 @@ def get_success_url(self): return self.collaborative_analysis_workspace.get_absolute_url() def form_valid(self, form): - auth_domain = ( - self.collaborative_analysis_workspace.workspace.authorization_domains.first() - ) + auth_domain = self.collaborative_analysis_workspace.workspace.authorization_domains.first() # Handle the result. try: with transaction.atomic(): diff --git a/primed/dbgap/adapters.py b/primed/dbgap/adapters.py index a2ed57a9..d1eaf728 100644 --- a/primed/dbgap/adapters.py +++ b/primed/dbgap/adapters.py @@ -22,13 +22,7 @@ class dbGaPWorkspaceAdapter(BaseWorkspaceAdapter): def get_extra_detail_context_data(self, workspace, request): extra_context = {} - associated_data_prep = Workspace.objects.filter( - dataprepworkspace__target_workspace=workspace - ) - extra_context["associated_data_prep_workspaces"] = DataPrepWorkspaceUserTable( - associated_data_prep - ) - extra_context["data_prep_active"] = associated_data_prep.filter( - dataprepworkspace__is_active=True - ).exists() + associated_data_prep = Workspace.objects.filter(dataprepworkspace__target_workspace=workspace) + extra_context["associated_data_prep_workspaces"] = DataPrepWorkspaceUserTable(associated_data_prep) + extra_context["data_prep_active"] = associated_data_prep.filter(dataprepworkspace__is_active=True).exists() return extra_context diff --git a/primed/dbgap/audit.py b/primed/dbgap/audit.py index d76eb26f..b70e459c 100644 --- a/primed/dbgap/audit.py +++ b/primed/dbgap/audit.py @@ -29,12 +29,9 @@ class AuditResult(PRIMEDAuditResult): def __post_init__(self): if self.data_access_request and ( - self.data_access_request.dbgap_data_access_snapshot.dbgap_application - != self.dbgap_application + self.data_access_request.dbgap_data_access_snapshot.dbgap_application != self.dbgap_application ): - raise ValueError( - "data_access_request application and dbgap_application do not match." - ) + raise ValueError("data_access_request application and dbgap_application do not match.") def get_action_url(self): """The URL that handles the action needed.""" @@ -128,16 +125,13 @@ class dbGaPAccessAuditTable(tables.Table): dar_consent = tables.Column(verbose_name="DAR consent") has_access = BooleanIconColumn(show_false_icon=True) note = tables.Column() - action = tables.TemplateColumn( - template_name="dbgap/snippets/dbgap_audit_action_button.html" - ) + action = tables.TemplateColumn(template_name="dbgap/snippets/dbgap_audit_action_button.html") class Meta: attrs = {"class": "table align-middle"} class dbGaPAccessAudit(PRIMEDAudit): - # Access verified. APPROVED_DAR = "Approved DAR." @@ -161,22 +155,14 @@ def __init__(self, dbgap_application_queryset=None, dbgap_workspace_queryset=Non if dbgap_application_queryset is None: dbgap_application_queryset = dbGaPApplication.objects.all() if not ( - isinstance(dbgap_application_queryset, QuerySet) - and dbgap_application_queryset.model is dbGaPApplication + isinstance(dbgap_application_queryset, QuerySet) and dbgap_application_queryset.model is dbGaPApplication ): - raise ValueError( - "dbgap_application_queryset must be a queryset of dbGaPApplication objects." - ) + raise ValueError("dbgap_application_queryset must be a queryset of dbGaPApplication objects.") self.dbgap_application_queryset = dbgap_application_queryset if dbgap_workspace_queryset is None: dbgap_workspace_queryset = dbGaPWorkspace.objects.all() - if not ( - isinstance(dbgap_workspace_queryset, QuerySet) - and dbgap_workspace_queryset.model is dbGaPWorkspace - ): - raise ValueError( - "dbgap_workspace_queryset must be a queryset of dbGaPWorkspace objects." - ) + if not (isinstance(dbgap_workspace_queryset, QuerySet) and dbgap_workspace_queryset.model is dbGaPWorkspace): + raise ValueError("dbgap_workspace_queryset must be a queryset of dbGaPWorkspace objects.") self.dbgap_workspace_queryset = dbgap_workspace_queryset def _run_audit(self): @@ -186,15 +172,11 @@ def _run_audit(self): def audit_application_and_workspace(self, dbgap_application, dbgap_workspace): """Audit access for a specific dbGaP application and a specific workspace.""" - in_auth_domain = dbgap_workspace.workspace.is_in_authorization_domain( - dbgap_application.anvil_access_group - ) + in_auth_domain = dbgap_workspace.workspace.is_in_authorization_domain(dbgap_application.anvil_access_group) # Get the most recent snapshot. try: - dar_snapshot = dbgap_application.dbgapdataaccesssnapshot_set.get( - is_most_recent=True - ) + dar_snapshot = dbgap_application.dbgapdataaccesssnapshot_set.get(is_most_recent=True) except dbGaPDataAccessSnapshot.DoesNotExist: if in_auth_domain: # Error! @@ -219,9 +201,7 @@ def audit_application_and_workspace(self, dbgap_application, dbgap_workspace): try: # There should only be one DAR from this snapshot associated with a given workspace. - dar = dbgap_workspace.get_data_access_requests().get( - dbgap_data_access_snapshot=dar_snapshot - ) + dar = dbgap_workspace.get_data_access_requests().get(dbgap_data_access_snapshot=dar_snapshot) except dbGaPDataAccessRequest.DoesNotExist: # No matching DAR exists for this application. if in_auth_domain: diff --git a/primed/dbgap/constants.py b/primed/dbgap/constants.py index a8515dfc..91873559 100644 --- a/primed/dbgap/constants.py +++ b/primed/dbgap/constants.py @@ -1,8 +1,6 @@ DBGAP_STUDY_URL = "https://www.ncbi.nlm.nih.gov/projects/gap/cgi-bin/study.cgi" PHS_REGEX = r"^phs(?P\d{6})$" -FULL_ACCESSION_REGEX = ( - r"^phs(?P\d{6})\.v(?P\d+?)\.p(?P\d+?)$" -) +FULL_ACCESSION_REGEX = r"^phs(?P\d{6})\.v(?P\d+?)\.p(?P\d+?)$" JSON_DAR_DEFS = { "project": { diff --git a/primed/dbgap/forms.py b/primed/dbgap/forms.py index 8f690d66..efe22479 100644 --- a/primed/dbgap/forms.py +++ b/primed/dbgap/forms.py @@ -116,9 +116,7 @@ def clean_dbgap_dar_data(self): except jsonschema.exceptions.ValidationError as e: # Replace the full json string because it will be very long error_message = e.message.replace(str(e.instance), "JSON array") - raise ValidationError( - self.ERROR_JSON_VALIDATION, params={"error": error_message} - ) + raise ValidationError(self.ERROR_JSON_VALIDATION, params={"error": error_message}) # Verify that there is only one project in the json. if len(data) > 1: raise ValidationError("JSON array includes more than one project ID.") @@ -131,9 +129,7 @@ def clean_dbgap_dar_data(self): class dbGaPDataAccessSnapshotMultipleForm(forms.Form): """Form to create new dbGaPDataAccessSnapshots for multiple dbGaPApplications at once.""" - ERROR_PROJECT_ID_DOES_NOT_EXIST = ( - "dbGaP Application(s) for some project id(s) do not exist in app." - ) + ERROR_PROJECT_ID_DOES_NOT_EXIST = "dbGaP Application(s) for some project id(s) do not exist in app." ERROR_JSON_VALIDATION = "JSON validation error: %(error)s" dbgap_dar_data = forms.JSONField() @@ -145,16 +141,12 @@ def clean_dbgap_dar_data(self): except jsonschema.exceptions.ValidationError as e: # Replace the full json string because it will be very long error_message = e.message.replace(str(e.instance), "JSON array") - raise ValidationError( - self.ERROR_JSON_VALIDATION, params={"error": error_message} - ) + raise ValidationError(self.ERROR_JSON_VALIDATION, params={"error": error_message}) # Verify that all projects exist. missing_ids = [] for project_json in data: project_id = project_json["Project_id"] - if not models.dbGaPApplication.objects.filter( - dbgap_project_id=project_id - ).exists(): + if not models.dbGaPApplication.objects.filter(dbgap_project_id=project_id).exists(): missing_ids.append(str(project_id)) if missing_ids: raise ValidationError(self.ERROR_PROJECT_ID_DOES_NOT_EXIST) diff --git a/primed/dbgap/management/commands/run_dbgap_audit.py b/primed/dbgap/management/commands/run_dbgap_audit.py index 57089930..e7eed490 100644 --- a/primed/dbgap/management/commands/run_dbgap_audit.py +++ b/primed/dbgap/management/commands/run_dbgap_audit.py @@ -25,9 +25,7 @@ def handle(self, *args, **options): # Report errors and needs access. audit_ok = data_access_audit.ok() # Construct the url for handling errors. - url = ( - "https://" + Site.objects.get_current().domain + reverse("dbgap:audit:all") - ) + url = "https://" + Site.objects.get_current().domain + reverse("dbgap:audit:all") if audit_ok: self.stdout.write(self.style.SUCCESS("ok!")) else: @@ -35,15 +33,11 @@ def handle(self, *args, **options): # Print results self.stdout.write("* Verified: {}".format(len(data_access_audit.verified))) - self.stdout.write( - "* Needs action: {}".format(len(data_access_audit.needs_action)) - ) + self.stdout.write("* Needs action: {}".format(len(data_access_audit.needs_action))) self.stdout.write("* Errors: {}".format(len(data_access_audit.errors))) if not audit_ok: - self.stdout.write( - self.style.ERROR(f"Please visit {url} to resolve these issues.") - ) + self.stdout.write(self.style.ERROR(f"Please visit {url} to resolve these issues.")) # Send email if requested and there are problems. email = options["email"] diff --git a/primed/dbgap/models.py b/primed/dbgap/models.py index 0260a9ce..7749d577 100644 --- a/primed/dbgap/models.py +++ b/primed/dbgap/models.py @@ -53,14 +53,10 @@ def __str__(self): return "phs{phs:06d}".format(phs=self.dbgap_phs) def get_absolute_url(self): - return reverse( - "dbgap:dbgap_study_accessions:detail", kwargs={"dbgap_phs": self.dbgap_phs} - ) + return reverse("dbgap:dbgap_study_accessions:detail", kwargs={"dbgap_phs": self.dbgap_phs}) -class dbGaPWorkspace( - RequesterModel, DataUseOntologyModel, TimeStampedModel, BaseWorkspaceData -): +class dbGaPWorkspace(RequesterModel, DataUseOntologyModel, TimeStampedModel, BaseWorkspaceData): """A model to track additional data about dbGaP data in a workspace.""" # PositiveIntegerField allows 0 and we want this to be 1 or higher. @@ -99,13 +95,9 @@ class dbGaPWorkspace( # Unfortunately, there are often legacy codes that don't fit into the current main/modifiers model. # We also need this field to match to dbGaP authorized access, so store it separately.""" - data_use_limitations = models.TextField( - help_text="""The full data use limitations for this workspace.""" - ) + data_use_limitations = models.TextField(help_text="""The full data use limitations for this workspace.""") - acknowledgments = models.TextField( - help_text="Acknowledgments associated with data in this workspace." - ) + acknowledgments = models.TextField(help_text="Acknowledgments associated with data in this workspace.") available_data = models.ManyToManyField( AvailableData, help_text="Data available in this accession.", @@ -242,20 +234,13 @@ def clean(self): """ if self.dbgap_dar_data: try: - jsonschema.validate( - self.dbgap_dar_data, constants.JSON_PROJECT_DAR_SCHEMA - ) + jsonschema.validate(self.dbgap_dar_data, constants.JSON_PROJECT_DAR_SCHEMA) except jsonschema.exceptions.ValidationError as e: # Replace the full json string because it will be very long error_message = e.message.replace(str(e.instance), "JSON array") raise ValidationError({"dbgap_dar_data": error_message}) - if ( - self.dbgap_dar_data["Project_id"] - != self.dbgap_application.dbgap_project_id - ): - raise ValidationError( - "Project_id in JSON does not match dbgap_application.dbgap_project_id." - ) + if self.dbgap_dar_data["Project_id"] != self.dbgap_application.dbgap_project_id: + raise ValidationError("Project_id in JSON does not match dbgap_application.dbgap_project_id.") def create_dars_from_json(self): """Add DARs for this application from the dbGaP json for this project snapshot. @@ -280,19 +265,13 @@ def create_dars_from_json(self): # Make sure that the dbgap_project_id matches. project_id = project_json["Project_id"] if project_id != self.dbgap_application.dbgap_project_id: - raise ValueError( - "project_id does not match dbgap_application.dbgap_project_id." - ) + raise ValueError("project_id does not match dbgap_application.dbgap_project_id.") # Loop over studies and requests to create DARs. # Do not save them until everything has been successfully created. for study_json in project_json["studies"]: # Consider making this a model manager method for dbGaPStudyAccession, since it may be common. # Get the dbGaPStudyAccession associated with this phs. - phs = int( - re.match(constants.PHS_REGEX, study_json["study_accession"]).group( - "phs" - ) - ) + phs = int(re.match(constants.PHS_REGEX, study_json["study_accession"]).group("phs")) # Create the DAR. for request_json in study_json["requests"]: # dbGaP does not keep track of the original version and participant set associated with a DAR. @@ -313,10 +292,7 @@ def create_dars_from_json(self): raise ValueError("dbgap_phs mismatch") if previous_dar.dbgap_consent_code != request_json["consent_code"]: raise ValueError("dbgap_consent_code mismatch") - if ( - previous_dar.dbgap_data_access_snapshot.dbgap_application.dbgap_project_id - != project_id - ): + if previous_dar.dbgap_data_access_snapshot.dbgap_application.dbgap_project_id != project_id: raise ValueError("project_id mismatch") # If everything looks good, pull the original version and participant set from the previous DAR. original_version = previous_dar.original_version @@ -340,9 +316,7 @@ def create_dars_from_json(self): original_participant_set = int(match.group("participant_set")) except ValueError as e: # Log an error and re-raise. - msg = "DAR ID mismatch for snapshot pk {} and DAR ID {}".format( - self.pk, previous_dar.dbgap_dar_id - ) + msg = "DAR ID mismatch for snapshot pk {} and DAR ID {}".format(self.pk, previous_dar.dbgap_dar_id) logger.error(msg) logger.error(str(e)) raise diff --git a/primed/dbgap/tables.py b/primed/dbgap/tables.py index fa22c5b1..717a9e77 100644 --- a/primed/dbgap/tables.py +++ b/primed/dbgap/tables.py @@ -19,7 +19,7 @@ def __init__( accessor="get_dbgap_accession", dbgap_link_accessor="get_dbgap_link", verbose_name="dbGaP accession", - **kwargs + **kwargs, ): self.dbgap_link_accessor = dbgap_link_accessor super().__init__(accessor=accessor, verbose_name=verbose_name, **kwargs) @@ -29,9 +29,7 @@ def render(self, record): if self.dbgap_link_accessor: url = tables.A(self.dbgap_link_accessor).resolve(record) return format_html( - """{} """.format( - url, value - ) + """{} """.format(url, value) ) else: return value @@ -46,9 +44,7 @@ class ManyToManyDateTimeColumn(tables.columns.ManyToManyColumn): def transform(self, obj): context = Context() context.update({"value": obj.created, "default": self.default}) - return Template( - """{{ value|date:"DATETIME_FORMAT"|default:default }}""" - ).render(context) + return Template("""{{ value|date:"DATETIME_FORMAT"|default:default }}""").render(context) class dbGaPStudyAccessionTable(tables.Table): @@ -87,9 +83,7 @@ class dbGaPWorkspaceUserTable(tables.Table): "dbgapworkspace__dbgap_participant_set", ), ) - dbgapworkspace__dbgap_consent_abbreviation = tables.columns.Column( - verbose_name="Consent" - ) + dbgapworkspace__dbgap_consent_abbreviation = tables.columns.Column(verbose_name="Consent") dbgapworkspace__gsr_restricted = BooleanIconColumn( orderable=False, true_icon="dash-circle-fill", true_color="#ffc107" ) @@ -266,9 +260,7 @@ 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_workspaces = tables.columns.Column(accessor="get_dbgap_workspaces", orderable=False, default=" ") class Meta: model = models.dbGaPDataAccessRequest diff --git a/primed/dbgap/tests/factories.py b/primed/dbgap/tests/factories.py index 32151573..78e43981 100644 --- a/primed/dbgap/tests/factories.py +++ b/primed/dbgap/tests/factories.py @@ -91,9 +91,7 @@ def authorization_domains(self, create, extracted, **kwargs): return # Create an authorization domain. - auth_domain = ManagedGroupFactory.create( - name="auth_{}".format(self.workspace.name) - ) + auth_domain = ManagedGroupFactory.create(name="auth_{}".format(self.workspace.name)) self.workspace.authorization_domains.add(auth_domain) @@ -157,18 +155,12 @@ class dbGaPDataAccessRequestForWorkspaceFactory(DjangoModelFactory): """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_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 - ) + 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_consent_abbreviation = LazyAttribute(lambda o: o.dbgap_workspace.dbgap_consent_abbreviation) dbgap_current_status = models.dbGaPDataAccessRequest.APPROVED dbgap_dac = Faker("word") @@ -211,6 +203,4 @@ class dbGaPJSONProjectFactory(DictFactory): studies = List([SubFactory(dbGaPJSONStudyFactory)]) class Params: - dbgap_application = Trait( - Project_id=LazyAttribute(lambda o: o.dbgap_application.dbgap_project_id) - ) + dbgap_application = Trait(Project_id=LazyAttribute(lambda o: o.dbgap_application.dbgap_project_id)) diff --git a/primed/dbgap/tests/test_audit.py b/primed/dbgap/tests/test_audit.py index f2699c6a..10e076dd 100644 --- a/primed/dbgap/tests/test_audit.py +++ b/primed/dbgap/tests/test_audit.py @@ -221,9 +221,7 @@ def test_verified_access(self): """run_audit with one application and one workspace that has verified access.""" # Create a workspace and matching DAR. dbgap_workspace = factories.dbGaPWorkspaceFactory.create() - dar = factories.dbGaPDataAccessRequestForWorkspaceFactory.create( - dbgap_workspace=dbgap_workspace - ) + dar = factories.dbGaPDataAccessRequestForWorkspaceFactory.create(dbgap_workspace=dbgap_workspace) # Add the anvil group to the auth group for the workspace. GroupGroupMembershipFactory( parent_group=dbgap_workspace.workspace.authorization_domains.first(), @@ -237,9 +235,7 @@ def test_verified_access(self): record = dbgap_audit.verified[0] self.assertIsInstance(record, audit.VerifiedAccess) self.assertEqual(record.workspace, dbgap_workspace) - self.assertEqual( - record.dbgap_application, dar.dbgap_data_access_snapshot.dbgap_application - ) + self.assertEqual(record.dbgap_application, dar.dbgap_data_access_snapshot.dbgap_application) self.assertEqual(record.data_access_request, dar) self.assertTrue(dbgap_audit.ok()) @@ -297,9 +293,7 @@ def test_verified_no_access_dar_not_approved(self): record = dbgap_audit.verified[0] self.assertIsInstance(record, audit.VerifiedNoAccess) self.assertEqual(record.workspace, dbgap_workspace) - self.assertEqual( - record.dbgap_application, dar.dbgap_data_access_snapshot.dbgap_application - ) + self.assertEqual(record.dbgap_application, dar.dbgap_data_access_snapshot.dbgap_application) self.assertEqual(record.data_access_request, dar) self.assertEqual(record.note, audit.dbGaPAccessAudit.DAR_NOT_APPROVED) self.assertTrue(dbgap_audit.ok()) @@ -308,9 +302,7 @@ def test_verified_no_access_no_dar(self): """run_audit with one application and one workspace that has verified no access.""" # Create a workspace and matching DAR. dbgap_application = factories.dbGaPApplicationFactory.create() - factories.dbGaPDataAccessSnapshotFactory.create( - dbgap_application=dbgap_application - ) + factories.dbGaPDataAccessSnapshotFactory.create(dbgap_application=dbgap_application) dbgap_workspace = factories.dbGaPWorkspaceFactory.create() # Do not add the anvil group to the auth group for the workspace. dbgap_audit = audit.dbGaPAccessAudit() @@ -329,9 +321,7 @@ def test_verified_no_access_no_dar(self): def test_grant_access_new_approved_dar(self): # Create a workspace and matching DAR. # Workspace was created before the snapshot. - dbgap_workspace = factories.dbGaPWorkspaceFactory.create( - created=timezone.now() - timedelta(weeks=3) - ) + dbgap_workspace = factories.dbGaPWorkspaceFactory.create(created=timezone.now() - timedelta(weeks=3)) dar = factories.dbGaPDataAccessRequestForWorkspaceFactory.create( dbgap_workspace=dbgap_workspace, dbgap_data_access_snapshot__created=timezone.now() - timedelta(weeks=2), @@ -345,9 +335,7 @@ def test_grant_access_new_approved_dar(self): record = dbgap_audit.needs_action[0] self.assertIsInstance(record, audit.GrantAccess) self.assertEqual(record.workspace, dbgap_workspace) - self.assertEqual( - record.dbgap_application, dar.dbgap_data_access_snapshot.dbgap_application - ) + self.assertEqual(record.dbgap_application, dar.dbgap_data_access_snapshot.dbgap_application) self.assertEqual(record.data_access_request, dar) self.assertEqual(record.note, audit.dbGaPAccessAudit.NEW_APPROVED_DAR) self.assertFalse(dbgap_audit.ok()) @@ -355,9 +343,7 @@ def test_grant_access_new_approved_dar(self): def test_grant_access_new_workspace(self): # Create a workspace and matching DAR. # Workspace was created after the snapshot. - dbgap_workspace = factories.dbGaPWorkspaceFactory.create( - created=timezone.now() - timedelta(weeks=2) - ) + dbgap_workspace = factories.dbGaPWorkspaceFactory.create(created=timezone.now() - timedelta(weeks=2)) dar = factories.dbGaPDataAccessRequestForWorkspaceFactory.create( dbgap_workspace=dbgap_workspace, dbgap_data_access_snapshot__created=timezone.now() - timedelta(weeks=3), @@ -371,9 +357,7 @@ def test_grant_access_new_workspace(self): record = dbgap_audit.needs_action[0] self.assertIsInstance(record, audit.GrantAccess) self.assertEqual(record.workspace, dbgap_workspace) - self.assertEqual( - record.dbgap_application, dar.dbgap_data_access_snapshot.dbgap_application - ) + self.assertEqual(record.dbgap_application, dar.dbgap_data_access_snapshot.dbgap_application) self.assertEqual(record.data_access_request, dar) self.assertEqual(record.note, audit.dbGaPAccessAudit.NEW_WORKSPACE) self.assertFalse(dbgap_audit.ok()) @@ -381,9 +365,7 @@ def test_grant_access_new_workspace(self): def test_grant_access_updated_dar(self): # Create a workspace and matching DAR. # Workspace was created before the snapshot. - dbgap_workspace = factories.dbGaPWorkspaceFactory.create( - created=timezone.now() - timedelta(weeks=4) - ) + dbgap_workspace = factories.dbGaPWorkspaceFactory.create(created=timezone.now() - timedelta(weeks=4)) # Create an old snapshot where the DAR was not approved. dbgap_application = factories.dbGaPApplicationFactory.create() old_dar = factories.dbGaPDataAccessRequestForWorkspaceFactory.create( @@ -408,9 +390,7 @@ def test_grant_access_updated_dar(self): record = dbgap_audit.needs_action[0] self.assertIsInstance(record, audit.GrantAccess) self.assertEqual(record.workspace, dbgap_workspace) - self.assertEqual( - record.dbgap_application, dar.dbgap_data_access_snapshot.dbgap_application - ) + self.assertEqual(record.dbgap_application, dar.dbgap_data_access_snapshot.dbgap_application) self.assertEqual(record.data_access_request, dar) self.assertEqual(record.note, audit.dbGaPAccessAudit.NEW_APPROVED_DAR) self.assertFalse(dbgap_audit.ok()) @@ -447,9 +427,7 @@ def test_remove_access_udpated_dar(self): record = dbgap_audit.needs_action[0] self.assertIsInstance(record, audit.RemoveAccess) self.assertEqual(record.workspace, dbgap_workspace) - self.assertEqual( - record.dbgap_application, dar.dbgap_data_access_snapshot.dbgap_application - ) + self.assertEqual(record.dbgap_application, dar.dbgap_data_access_snapshot.dbgap_application) self.assertEqual(record.data_access_request, dar) self.assertEqual(record.note, audit.dbGaPAccessAudit.PREVIOUS_APPROVAL) self.assertFalse(dbgap_audit.ok()) @@ -568,16 +546,12 @@ def test_two_applications(self): record = dbgap_audit.verified[0] self.assertIsInstance(record, audit.VerifiedAccess) self.assertEqual(record.workspace, dbgap_workspace) - self.assertEqual( - record.dbgap_application, dar_1.dbgap_data_access_snapshot.dbgap_application - ) + self.assertEqual(record.dbgap_application, dar_1.dbgap_data_access_snapshot.dbgap_application) self.assertEqual(record.data_access_request, dar_1) record = dbgap_audit.needs_action[0] self.assertIsInstance(record, audit.GrantAccess) self.assertEqual(record.workspace, dbgap_workspace) - self.assertEqual( - record.dbgap_application, dar_2.dbgap_data_access_snapshot.dbgap_application - ) + self.assertEqual(record.dbgap_application, dar_2.dbgap_data_access_snapshot.dbgap_application) self.assertEqual(record.data_access_request, dar_2) def test_dbgap_application_queryset(self): @@ -613,9 +587,7 @@ def test_dbgap_workspace_queryset(self): def test_dbgap_workspace_queryset_wrong_class(self): """dbGaPAccessAudit raises error if dbgap_workspace_queryset has the wrong model class.""" with self.assertRaises(ValueError) as e: - audit.dbGaPAccessAudit( - dbgap_workspace_queryset=models.dbGaPApplication.objects.all() - ) + audit.dbGaPAccessAudit(dbgap_workspace_queryset=models.dbGaPApplication.objects.all()) self.assertEqual( str(e.exception), "dbgap_workspace_queryset must be a queryset of dbGaPWorkspace objects.", @@ -634,9 +606,7 @@ def test_dbgap_workspace_queryset_not_queryset(self): def test_dbgap_application_queryset_wrong_class(self): """dbGaPAccessAudit raises error if dbgap_application_queryset has the wrong model class.""" with self.assertRaises(ValueError) as e: - audit.dbGaPAccessAudit( - dbgap_application_queryset=models.dbGaPWorkspace.objects.all() - ) + audit.dbGaPAccessAudit(dbgap_application_queryset=models.dbGaPWorkspace.objects.all()) self.assertEqual( str(e.exception), "dbgap_application_queryset must be a queryset of dbGaPApplication objects.", @@ -658,17 +628,13 @@ def test_two_applications_two_workspaces(self): def test_ok_with_verified_and_needs_action(self): # Create a workspace and matching DAR. dbgap_workspace = factories.dbGaPWorkspaceFactory.create() - other_dar = factories.dbGaPDataAccessRequestForWorkspaceFactory.create( - dbgap_workspace=dbgap_workspace - ) + other_dar = factories.dbGaPDataAccessRequestForWorkspaceFactory.create(dbgap_workspace=dbgap_workspace) # Add the anvil group to the auth group for the workspace. GroupGroupMembershipFactory( parent_group=dbgap_workspace.workspace.authorization_domains.first(), child_group=other_dar.dbgap_data_access_snapshot.dbgap_application.anvil_access_group, ) - factories.dbGaPDataAccessRequestForWorkspaceFactory.create( - dbgap_workspace=dbgap_workspace - ) + factories.dbGaPDataAccessRequestForWorkspaceFactory.create(dbgap_workspace=dbgap_workspace) # # Add the anvil group to the auth group for the workspace. # GroupGroupMembershipFactory( # parent_group=dbgap_workspace.workspace.authorization_domains.first(), @@ -683,9 +649,7 @@ def test_ok_with_verified_and_needs_action(self): def test_ok_with_verified_and_error(self): # Create a workspace and matching DAR. dbgap_workspace = factories.dbGaPWorkspaceFactory.create() - other_dar = factories.dbGaPDataAccessRequestForWorkspaceFactory.create( - dbgap_workspace=dbgap_workspace - ) + other_dar = factories.dbGaPDataAccessRequestForWorkspaceFactory.create(dbgap_workspace=dbgap_workspace) # Add the anvil group to the auth group for the workspace. GroupGroupMembershipFactory( parent_group=dbgap_workspace.workspace.authorization_domains.first(), diff --git a/primed/dbgap/tests/test_commands.py b/primed/dbgap/tests/test_commands.py index e3b4dc93..97f8f3fb 100644 --- a/primed/dbgap/tests/test_commands.py +++ b/primed/dbgap/tests/test_commands.py @@ -43,9 +43,7 @@ def test_command_run_audit_one_instance_needs_action(self): """Test command output with one needs_action instance.""" # Create a workspace and matching DAR. dbgap_workspace = factories.dbGaPWorkspaceFactory.create() - factories.dbGaPDataAccessRequestForWorkspaceFactory.create( - dbgap_workspace=dbgap_workspace - ) + factories.dbGaPDataAccessRequestForWorkspaceFactory.create(dbgap_workspace=dbgap_workspace) out = StringIO() call_command("run_dbgap_audit", "--no-color", stdout=out) self.assertIn("Running dbGaP access audit... problems found.", out.getvalue()) @@ -79,9 +77,7 @@ def test_command_run_audit_one_instance_verified_email(self): factories.dbGaPWorkspaceFactory.create() factories.dbGaPApplicationFactory.create() out = StringIO() - call_command( - "run_dbgap_audit", "--no-color", email="test@example.com", stdout=out - ) + call_command("run_dbgap_audit", "--no-color", email="test@example.com", stdout=out) self.assertIn("Running dbGaP access audit... ok!", out.getvalue()) # Zero messages have been sent by default. self.assertEqual(len(mail.outbox), 0) @@ -90,13 +86,9 @@ def test_command_run_audit_one_instance_needs_action_email(self): """Email is sent for one needs_action instance.""" # Create a workspace and matching DAR. dbgap_workspace = factories.dbGaPWorkspaceFactory.create() - factories.dbGaPDataAccessRequestForWorkspaceFactory.create( - dbgap_workspace=dbgap_workspace - ) + factories.dbGaPDataAccessRequestForWorkspaceFactory.create(dbgap_workspace=dbgap_workspace) out = StringIO() - call_command( - "run_dbgap_audit", "--no-color", email="test@example.com", stdout=out - ) + call_command("run_dbgap_audit", "--no-color", email="test@example.com", stdout=out) self.assertIn("Running dbGaP access audit... problems found.", out.getvalue()) self.assertIn("* Verified: 0", out.getvalue()) self.assertIn("* Needs action: 1", out.getvalue()) @@ -117,9 +109,7 @@ def test_command_run_audit_one_instance_error_email(self): child_group=dbgap_application.anvil_access_group, ) out = StringIO() - call_command( - "run_dbgap_audit", "--no-color", email="test@example.com", stdout=out - ) + call_command("run_dbgap_audit", "--no-color", email="test@example.com", stdout=out) self.assertIn("Running dbGaP access audit... problems found.", out.getvalue()) self.assertIn("* Verified: 0", out.getvalue()) self.assertIn("* Needs action: 0", out.getvalue()) @@ -136,12 +126,8 @@ def test_different_domain(self): site.save() with self.settings(SITE_ID=site.id): dbgap_workspace = factories.dbGaPWorkspaceFactory.create() - factories.dbGaPDataAccessRequestForWorkspaceFactory.create( - dbgap_workspace=dbgap_workspace - ) + factories.dbGaPDataAccessRequestForWorkspaceFactory.create(dbgap_workspace=dbgap_workspace) out = StringIO() call_command("run_dbgap_audit", "--no-color", stdout=out) - self.assertIn( - "Running dbGaP access audit... problems found.", out.getvalue() - ) + self.assertIn("Running dbGaP access audit... problems found.", out.getvalue()) self.assertIn("https://foobar.com", out.getvalue()) diff --git a/primed/dbgap/tests/test_forms.py b/primed/dbgap/tests/test_forms.py index 96eeba23..88fac8b8 100644 --- a/primed/dbgap/tests/test_forms.py +++ b/primed/dbgap/tests/test_forms.py @@ -579,13 +579,7 @@ def setUp(self): def test_valid(self): """Form is valid with necessary input.""" form_data = { - "dbgap_dar_data": json.dumps( - [ - factories.dbGaPJSONProjectFactory( - dbgap_application=self.dbgap_application - ) - ] - ), + "dbgap_dar_data": json.dumps([factories.dbGaPJSONProjectFactory(dbgap_application=self.dbgap_application)]), "dbgap_application": self.dbgap_application, } form = self.form_class(data=form_data) @@ -593,9 +587,7 @@ def test_valid(self): def test_missing_dbgap_application(self): """Form is invalid when dbgap_application is missing.""" - form = self.form_class( - data={"dbgap_dar_data": json.dumps([factories.dbGaPJSONProjectFactory()])} - ) + form = self.form_class(data={"dbgap_dar_data": json.dumps([factories.dbGaPJSONProjectFactory()])}) from django.core.exceptions import ObjectDoesNotExist with self.assertRaises(ObjectDoesNotExist): @@ -679,9 +671,7 @@ def test_dbgap_dar_data_missing_dbgap_project_id(self): def test_dbgap_dar_data_missing_studies(self): """Form is invalid when studies is missing from the JSON.""" - project_json = factories.dbGaPJSONProjectFactory.create( - dbgap_application=self.dbgap_application - ) + project_json = factories.dbGaPJSONProjectFactory.create(dbgap_application=self.dbgap_application) project_json.pop("studies") form_data = { "dbgap_dar_data": json.dumps([project_json]), @@ -697,9 +687,7 @@ def test_dbgap_dar_data_missing_studies(self): def test_dbgap_dar_data_missing_study_accession(self): """Form is invalid when study_accession is missing from the JSON.""" - project_json = factories.dbGaPJSONProjectFactory.create( - dbgap_application=self.dbgap_application - ) + project_json = factories.dbGaPJSONProjectFactory.create(dbgap_application=self.dbgap_application) project_json["studies"][0].pop("study_accession") form_data = { "dbgap_dar_data": json.dumps([project_json]), @@ -835,9 +823,7 @@ def test_dbgap_dar_data_missing_DAC_abbrev(self): def test_dbgap_project_id_does_not_match(self): """Form is not valid when the dbgap_project_id does not match.""" form_data = { - "dbgap_dar_data": json.dumps( - [factories.dbGaPJSONProjectFactory(Project_id=2)] - ), + "dbgap_dar_data": json.dumps([factories.dbGaPJSONProjectFactory(Project_id=2)]), "dbgap_application": self.dbgap_application, } form = self.form_class(data=form_data) @@ -856,9 +842,7 @@ class dbGaPDataAccessSnapshotMultipleFormTest(TestCase): def test_valid_one_project(self): """Form is valid with necessary input.""" dbgap_application = factories.dbGaPApplicationFactory.create() - project_json = factories.dbGaPJSONProjectFactory( - dbgap_application=dbgap_application - ) + project_json = factories.dbGaPJSONProjectFactory(dbgap_application=dbgap_application) form_data = { "dbgap_dar_data": json.dumps([project_json]), } @@ -867,13 +851,9 @@ def test_valid_one_project(self): def test_valid_two_projects(self): dbgap_application_1 = factories.dbGaPApplicationFactory.create() - project_json_1 = factories.dbGaPJSONProjectFactory( - dbgap_application=dbgap_application_1 - ) + project_json_1 = factories.dbGaPJSONProjectFactory(dbgap_application=dbgap_application_1) dbgap_application_2 = factories.dbGaPApplicationFactory.create() - project_json_2 = factories.dbGaPJSONProjectFactory( - dbgap_application=dbgap_application_2 - ) + project_json_2 = factories.dbGaPJSONProjectFactory(dbgap_application=dbgap_application_2) form_data = { "dbgap_dar_data": json.dumps([project_json_1, project_json_2]), } @@ -1075,9 +1055,7 @@ def test_two_projects_do_not_exist(self): def test_two_projects_one_does_not_exist(self): dbgap_application = factories.dbGaPApplicationFactory.create() - project_json_1 = factories.dbGaPJSONProjectFactory( - dbgap_application=dbgap_application - ) + project_json_1 = factories.dbGaPJSONProjectFactory(dbgap_application=dbgap_application) project_json_2 = factories.dbGaPJSONProjectFactory() form_data = { "dbgap_dar_data": json.dumps([project_json_1, project_json_2]), diff --git a/primed/dbgap/tests/test_models.py b/primed/dbgap/tests/test_models.py index dc3fa0c9..96377228 100644 --- a/primed/dbgap/tests/test_models.py +++ b/primed/dbgap/tests/test_models.py @@ -62,9 +62,7 @@ def test_unique_dbgap_study_accession(self): instance.full_clean() self.assertIn("dbgap_phs", e.exception.error_dict) self.assertEqual(len(e.exception.error_dict["dbgap_phs"]), 1) - self.assertIn( - "already exists", e.exception.error_dict["dbgap_phs"][0].messages[0] - ) + self.assertIn("already exists", e.exception.error_dict["dbgap_phs"][0].messages[0]) with self.assertRaises(IntegrityError): instance.save() @@ -185,18 +183,14 @@ def test_unique_dbgap_workspace(self): instance.full_clean() self.assertIn("__all__", e.exception.error_dict) self.assertEqual(len(e.exception.error_dict["__all__"]), 1) - self.assertIn( - "already exists", e.exception.error_dict["__all__"][0].messages[0] - ) + self.assertIn("already exists", e.exception.error_dict["__all__"][0].messages[0]) with self.assertRaises(IntegrityError): instance.save() def test_dbgap_study_accession_protect(self): """Cannot delete a dbGaPStudyAccession if it has an associated dbGaPWorkspace.""" dbgap_study_accession = factories.dbGaPStudyAccessionFactory.create() - factories.dbGaPWorkspaceFactory.create( - dbgap_study_accession=dbgap_study_accession - ) + factories.dbGaPWorkspaceFactory.create(dbgap_study_accession=dbgap_study_accession) with self.assertRaises(ProtectedError): dbgap_study_accession.delete() @@ -356,9 +350,7 @@ def test_get_data_access_requests_larger_participant_set(self): def test_get_data_access_requests_smaller_participant_set(self): """Does return a DAR where participant set is smaller than the workspace.""" - workspace = factories.dbGaPWorkspaceFactory.create( - dbgap_version=2, dbgap_participant_set=2 - ) + workspace = factories.dbGaPWorkspaceFactory.create(dbgap_version=2, dbgap_participant_set=2) dar = factories.dbGaPDataAccessRequestFactory.create( dbgap_phs=workspace.dbgap_study_accession.dbgap_phs, original_version=1, @@ -383,9 +375,7 @@ def test_get_data_access_requests_different_consent_code(self): def test_get_data_access_requests_one_application_one_snapshot_one_match(self): """Returns 1 results when there is one matching DARs.""" workspace = factories.dbGaPWorkspaceFactory.create() - dar = factories.dbGaPDataAccessRequestForWorkspaceFactory( - dbgap_workspace=workspace - ) + dar = factories.dbGaPDataAccessRequestForWorkspaceFactory(dbgap_workspace=workspace) results = workspace.get_data_access_requests() self.assertEqual(len(results), 1) self.assertIn(dar, results) @@ -551,9 +541,7 @@ def test_unique_dbgap_application(self): instance.full_clean() self.assertIn("dbgap_project_id", e.exception.error_dict) self.assertEqual(len(e.exception.error_dict["dbgap_project_id"]), 1) - self.assertIn( - "already exists", e.exception.error_dict["dbgap_project_id"][0].messages[0] - ) + self.assertIn("already exists", e.exception.error_dict["dbgap_project_id"][0].messages[0]) with self.assertRaises(IntegrityError): instance.save() @@ -657,9 +645,7 @@ def test_clean_invalid_json(self): def test_dbgap_application_protect(self): """Cannot delete a dbGaPApplication if it has an associated dbGaPDataAccessSnapshot.""" dbgap_application = factories.dbGaPApplicationFactory.create() - factories.dbGaPDataAccessSnapshotFactory.create( - dbgap_application=dbgap_application - ) + factories.dbGaPDataAccessSnapshotFactory.create(dbgap_application=dbgap_application) with self.assertRaises(ProtectedError): dbgap_application.delete() @@ -673,9 +659,7 @@ def test_dbgap_create_dars_from_json_one_study_one_dar(self): DAR=1234, current_DAR_status="approved", ) - study_json = factories.dbGaPJSONStudyFactory( - study_accession="phs000421", requests=[dar_json] - ) + study_json = factories.dbGaPJSONStudyFactory(study_accession="phs000421", requests=[dar_json]) project_json = factories.dbGaPJSONProjectFactory(studies=[study_json]) dbgap_snapshot = factories.dbGaPDataAccessSnapshotFactory.create( dbgap_application__dbgap_project_id=project_json["Project_id"], @@ -686,9 +670,7 @@ def test_dbgap_create_dars_from_json_one_study_one_dar(self): responses.GET, constants.DBGAP_STUDY_URL, status=302, - headers={ - "Location": constants.DBGAP_STUDY_URL + "?study_id=phs000421.v32.p18" - }, + headers={"Location": constants.DBGAP_STUDY_URL + "?study_id=phs000421.v32.p18"}, ) dars = dbgap_snapshot.create_dars_from_json() self.assertEqual(len(dars), 1) @@ -722,9 +704,7 @@ def test_dbgap_create_dars_from_json_one_study_two_dars(self): DAR=1235, current_DAR_status="approved", ) - study_json = factories.dbGaPJSONStudyFactory( - study_accession="phs000421", requests=[dar_json_1, dar_json_2] - ) + study_json = factories.dbGaPJSONStudyFactory(study_accession="phs000421", requests=[dar_json_1, dar_json_2]) project_json = factories.dbGaPJSONProjectFactory(studies=[study_json]) dbgap_snapshot = factories.dbGaPDataAccessSnapshotFactory.create( dbgap_application__dbgap_project_id=project_json["Project_id"], @@ -735,9 +715,7 @@ def test_dbgap_create_dars_from_json_one_study_two_dars(self): responses.GET, constants.DBGAP_STUDY_URL, status=302, - headers={ - "Location": constants.DBGAP_STUDY_URL + "?study_id=phs000421.v32.p18" - }, + headers={"Location": constants.DBGAP_STUDY_URL + "?study_id=phs000421.v32.p18"}, ) dars = dbgap_snapshot.create_dars_from_json() self.assertEqual(len(dars), 2) @@ -783,15 +761,9 @@ def test_dbgap_create_dars_from_json_two_studies_one_dar_each(self): DAR=1235, current_DAR_status="approved", ) - study_json_1 = factories.dbGaPJSONStudyFactory( - study_accession="phs000421", requests=[dar_json_1] - ) - study_json_2 = factories.dbGaPJSONStudyFactory( - study_accession="phs000896", requests=[dar_json_2] - ) - project_json = factories.dbGaPJSONProjectFactory( - studies=[study_json_1, study_json_2] - ) + study_json_1 = factories.dbGaPJSONStudyFactory(study_accession="phs000421", requests=[dar_json_1]) + study_json_2 = factories.dbGaPJSONStudyFactory(study_accession="phs000896", requests=[dar_json_2]) + project_json = factories.dbGaPJSONProjectFactory(studies=[study_json_1, study_json_2]) dbgap_snapshot = factories.dbGaPDataAccessSnapshotFactory.create( dbgap_application__dbgap_project_id=project_json["Project_id"], @@ -803,18 +775,14 @@ def test_dbgap_create_dars_from_json_two_studies_one_dar_each(self): constants.DBGAP_STUDY_URL, match=[responses.matchers.query_param_matcher({"study_id": "phs000421"})], status=302, - headers={ - "Location": constants.DBGAP_STUDY_URL + "?study_id=phs000421.v32.p18" - }, + headers={"Location": constants.DBGAP_STUDY_URL + "?study_id=phs000421.v32.p18"}, ) responses.add( responses.GET, constants.DBGAP_STUDY_URL, match=[responses.matchers.query_param_matcher({"study_id": "phs000896"})], status=302, - headers={ - "Location": constants.DBGAP_STUDY_URL + "?study_id=phs000896.v2.p1" - }, + headers={"Location": constants.DBGAP_STUDY_URL + "?study_id=phs000896.v2.p1"}, ) dars = dbgap_snapshot.create_dars_from_json() self.assertEqual(len(dars), 2) @@ -879,9 +847,7 @@ def test_does_include_dars_that_are_not_approved(self): DAR=1234, current_DAR_status="rejected", ) - study_json = factories.dbGaPJSONStudyFactory( - study_accession="phs000421", requests=[dar_json] - ) + study_json = factories.dbGaPJSONStudyFactory(study_accession="phs000421", requests=[dar_json]) project_json = factories.dbGaPJSONProjectFactory(studies=[study_json]) dbgap_snapshot = factories.dbGaPDataAccessSnapshotFactory.create( dbgap_application__dbgap_project_id=project_json["Project_id"], @@ -892,9 +858,7 @@ def test_does_include_dars_that_are_not_approved(self): responses.GET, constants.DBGAP_STUDY_URL, status=302, - headers={ - "Location": constants.DBGAP_STUDY_URL + "?study_id=phs000421.v32.p18" - }, + headers={"Location": constants.DBGAP_STUDY_URL + "?study_id=phs000421.v32.p18"}, ) dars = dbgap_snapshot.create_dars_from_json() self.assertEqual(len(dars), 1) @@ -913,9 +877,7 @@ def test_dbgap_create_dars_updated_dars(self): DAR=1234, current_DAR_status="approved", ) - study_json = factories.dbGaPJSONStudyFactory( - study_accession="phs000421", requests=[dar_json] - ) + study_json = factories.dbGaPJSONStudyFactory(study_accession="phs000421", requests=[dar_json]) project_json = factories.dbGaPJSONProjectFactory( Project_id=dbgap_application.dbgap_project_id, studies=[study_json] ) @@ -950,9 +912,7 @@ def test_dbgap_create_dars_updated_dars(self): self.assertEqual(updated_dar.dbgap_data_access_snapshot, second_snapshot) # These should be pulled from the original dar. self.assertEqual(updated_dar.original_version, original_dar.original_version) - self.assertEqual( - updated_dar.original_participant_set, original_dar.original_participant_set - ) + self.assertEqual(updated_dar.original_participant_set, original_dar.original_participant_set) @responses.activate def test_dbgap_create_dars_version_change_between_new_and_approved(self): @@ -965,9 +925,7 @@ def test_dbgap_create_dars_version_change_between_new_and_approved(self): DAR=1234, current_DAR_status="approved", ) - study_json = factories.dbGaPJSONStudyFactory( - study_accession="phs000421", requests=[dar_json] - ) + study_json = factories.dbGaPJSONStudyFactory(study_accession="phs000421", requests=[dar_json]) project_json = factories.dbGaPJSONProjectFactory( Project_id=dbgap_application.dbgap_project_id, studies=[study_json] ) @@ -999,9 +957,7 @@ def test_dbgap_create_dars_version_change_between_new_and_approved(self): responses.GET, constants.DBGAP_STUDY_URL, status=302, - headers={ - "Location": constants.DBGAP_STUDY_URL + "?study_id=phs000421.v33.p19" - }, + headers={"Location": constants.DBGAP_STUDY_URL + "?study_id=phs000421.v33.p19"}, ) updated_dars = second_snapshot.create_dars_from_json() self.assertEqual(len(updated_dars), 1) @@ -1025,9 +981,7 @@ def test_created_dars_from_json_assertion_error_phs(self): DAR=1234, current_DAR_status="approved", ) - study_json = factories.dbGaPJSONStudyFactory( - study_accession="phs000892", requests=[dar_json] - ) + study_json = factories.dbGaPJSONStudyFactory(study_accession="phs000892", requests=[dar_json]) project_json = factories.dbGaPJSONProjectFactory( Project_id=dbgap_application.dbgap_project_id, studies=[study_json] ) @@ -1069,9 +1023,7 @@ def test_created_dars_from_json_assertion_error_consent_code(self): DAR=1234, current_DAR_status="approved", ) - study_json = factories.dbGaPJSONStudyFactory( - study_accession="phs000421", requests=[dar_json] - ) + study_json = factories.dbGaPJSONStudyFactory(study_accession="phs000421", requests=[dar_json]) project_json = factories.dbGaPJSONProjectFactory( Project_id=dbgap_application.dbgap_project_id, studies=[study_json] ) @@ -1113,9 +1065,7 @@ def test_created_dars_from_json_assertion_error_dbgap_project_id(self): DAR=1234, current_DAR_status="approved", ) - study_json = factories.dbGaPJSONStudyFactory( - study_accession="phs000421", requests=[dar_json] - ) + study_json = factories.dbGaPJSONStudyFactory(study_accession="phs000421", requests=[dar_json]) project_json = factories.dbGaPJSONProjectFactory( Project_id=dbgap_application.dbgap_project_id, studies=[study_json] ) @@ -1185,9 +1135,7 @@ def test_unique_dbgap_dar_id(self): instance.full_clean() self.assertIn("__all__", e.exception.error_dict) self.assertEqual(len(e.exception.error_dict["__all__"]), 1) - self.assertIn( - "already exists", e.exception.error_dict["__all__"][0].messages[0] - ) + self.assertIn("already exists", e.exception.error_dict["__all__"][0].messages[0]) with self.assertRaises(IntegrityError): instance.save() @@ -1203,9 +1151,7 @@ def test_unique_dbgap_data_access_request(self): instance.full_clean() self.assertIn("__all__", e.exception.error_dict) self.assertEqual(len(e.exception.error_dict["__all__"]), 1) - self.assertIn( - "already exists", e.exception.error_dict["__all__"][0].messages[0] - ) + self.assertIn("already exists", e.exception.error_dict["__all__"][0].messages[0]) with self.assertRaises(IntegrityError): instance.save() @@ -1220,18 +1166,14 @@ def test_unique_dbgap_data_access_dar_id(self): instance.full_clean() self.assertIn("__all__", e.exception.error_dict) self.assertEqual(len(e.exception.error_dict["__all__"]), 1) - self.assertIn( - "already exists", e.exception.error_dict["__all__"][0].messages[0] - ) + self.assertIn("already exists", e.exception.error_dict["__all__"][0].messages[0]) with self.assertRaises(IntegrityError): instance.save() def test_dbgap_data_access_snapshot_protect(self): """Cannot delete a dbGaPApplication if it has an associated dbGaPDataAccessSnapshot.""" dbgap_snapshot = factories.dbGaPDataAccessSnapshotFactory.create() - dar = factories.dbGaPDataAccessRequestFactory.create( - dbgap_data_access_snapshot=dbgap_snapshot - ) + dar = factories.dbGaPDataAccessRequestFactory.create(dbgap_data_access_snapshot=dbgap_snapshot) dbgap_snapshot.delete() with self.assertRaises(models.dbGaPDataAccessSnapshot.DoesNotExist): dbgap_snapshot.refresh_from_db() @@ -1409,9 +1351,7 @@ def test_approved(self): expired_dar = factories.dbGaPDataAccessRequestFactory.create( dbgap_current_status=models.dbGaPDataAccessRequest.EXPIRED ) - new_dar = factories.dbGaPDataAccessRequestFactory.create( - dbgap_current_status=models.dbGaPDataAccessRequest.NEW - ) + new_dar = factories.dbGaPDataAccessRequestFactory.create(dbgap_current_status=models.dbGaPDataAccessRequest.NEW) qs = models.dbGaPDataAccessRequest.objects.approved() self.assertEqual(len(qs), 1) self.assertIn(approved_dar, qs) @@ -1457,9 +1397,7 @@ def test_get_dbgap_workspaces_no_study_accession(self): def test_get_dbgap_workspaces_no_matches(self): """Returns an empty queryset when there is no matching workspace.""" study_accession = factories.dbGaPStudyAccessionFactory.create() - dar = factories.dbGaPDataAccessRequestFactory.create( - dbgap_phs=study_accession.dbgap_phs - ) + dar = factories.dbGaPDataAccessRequestFactory.create(dbgap_phs=study_accession.dbgap_phs) self.assertEqual(dar.get_dbgap_workspaces().count(), 0) def test_get_dbgap_workspaces_one_match(self): @@ -1541,9 +1479,7 @@ def test_get_dbgap_workspaces_smaller_participant_set(self): def test_get_dbgap_workspaces_larger_participant_set(self): """Finds a matching workspace with a larger version and participant set.""" - workspace = factories.dbGaPWorkspaceFactory.create( - dbgap_version=2, dbgap_participant_set=2 - ) + workspace = factories.dbGaPWorkspaceFactory.create(dbgap_version=2, dbgap_participant_set=2) dar = factories.dbGaPDataAccessRequestFactory.create( dbgap_phs=workspace.dbgap_study_accession.dbgap_phs, original_version=1, @@ -1556,9 +1492,7 @@ def test_get_dbgap_workspaces_larger_participant_set(self): def test_get_dbgap_workspaces_different_dbgap_study_accession(self): """Raises ObjectNotFound for workspace with the same phs/version but different phs.""" - workspace = factories.dbGaPWorkspaceFactory.create( - dbgap_study_accession__dbgap_phs=1 - ) + workspace = factories.dbGaPWorkspaceFactory.create(dbgap_study_accession__dbgap_phs=1) dar = factories.dbGaPDataAccessRequestFactory.create( dbgap_phs=2, original_version=workspace.dbgap_version, diff --git a/primed/dbgap/tests/test_tables.py b/primed/dbgap/tests/test_tables.py index 4c901a44..8aeda44b 100644 --- a/primed/dbgap/tests/test_tables.py +++ b/primed/dbgap/tests/test_tables.py @@ -95,13 +95,9 @@ def test_number_workspaces(self): """Table shows correct count for number of workspaces.""" self.model_factory.create() dbgap_study_accession_2 = self.model_factory.create() - factories.dbGaPWorkspaceFactory.create( - dbgap_study_accession=dbgap_study_accession_2 - ) + factories.dbGaPWorkspaceFactory.create(dbgap_study_accession=dbgap_study_accession_2) dbgap_study_accession_3 = self.model_factory.create() - factories.dbGaPWorkspaceFactory.create_batch( - 2, dbgap_study_accession=dbgap_study_accession_3 - ) + factories.dbGaPWorkspaceFactory.create_batch(2, dbgap_study_accession=dbgap_study_accession_3) table = self.table_class(self.model.objects.all()) self.assertEqual(table.rows[0].get_cell("number_workspaces"), 0) self.assertEqual(table.rows[1].get_cell("number_workspaces"), 1) @@ -257,9 +253,7 @@ def test_principal_investigator(self): def test_number_approved_dars_zero(self): """Table shows correct count for number of approved DARs when an application has a snapshot but no DARs.""" dbgap_application = self.model_factory.create() - factories.dbGaPDataAccessSnapshotFactory.create( - dbgap_application=dbgap_application - ) + factories.dbGaPDataAccessSnapshotFactory.create(dbgap_application=dbgap_application) table = self.table_class(self.model.objects.all()) self.assertEqual(table.rows[0].get_cell_value("number_approved_dars"), "0") @@ -272,9 +266,7 @@ def test_number_approved_dars_zero_no_snapshot(self): def test_number_approved_dars_one(self): """Table shows correct count for number of approved DARs when there is one.""" dbgap_application = self.model_factory.create() - dbgap_snapshot = factories.dbGaPDataAccessSnapshotFactory.create( - dbgap_application=dbgap_application - ) + dbgap_snapshot = factories.dbGaPDataAccessSnapshotFactory.create(dbgap_application=dbgap_application) factories.dbGaPDataAccessRequestFactory.create( dbgap_data_access_snapshot=dbgap_snapshot, dbgap_current_status=models.dbGaPDataAccessRequest.APPROVED, @@ -285,9 +277,7 @@ def test_number_approved_dars_one(self): def test_number_approved_dars_two(self): """Table shows correct count for number of approved DARs when there are two.""" dbgap_application = self.model_factory.create() - dbgap_snapshot = factories.dbGaPDataAccessSnapshotFactory.create( - dbgap_application=dbgap_application - ) + dbgap_snapshot = factories.dbGaPDataAccessSnapshotFactory.create(dbgap_application=dbgap_application) factories.dbGaPDataAccessRequestFactory.create_batch( 2, dbgap_data_access_snapshot=dbgap_snapshot, @@ -299,9 +289,7 @@ def test_number_approved_dars_two(self): def test_number_approved_dars_other(self): """Number of approved DARs does not include DARs with status that is not "approved".""" dbgap_application = self.model_factory.create() - dbgap_snapshot = factories.dbGaPDataAccessSnapshotFactory.create( - dbgap_application=dbgap_application - ) + dbgap_snapshot = factories.dbGaPDataAccessSnapshotFactory.create(dbgap_application=dbgap_application) factories.dbGaPDataAccessRequestFactory.create( dbgap_data_access_snapshot=dbgap_snapshot, dbgap_current_status=models.dbGaPDataAccessRequest.APPROVED, @@ -332,18 +320,14 @@ def test_number_approved_dars_other(self): def test_number_approved_dars_two_applications(self): """Number of approved DARs is correct for two applications.""" dbgap_application_1 = self.model_factory.create() - dbgap_snapshot_1 = factories.dbGaPDataAccessSnapshotFactory.create( - dbgap_application=dbgap_application_1 - ) + dbgap_snapshot_1 = factories.dbGaPDataAccessSnapshotFactory.create(dbgap_application=dbgap_application_1) factories.dbGaPDataAccessRequestFactory.create_batch( 2, dbgap_data_access_snapshot=dbgap_snapshot_1, dbgap_current_status=models.dbGaPDataAccessRequest.APPROVED, ) dbgap_application_2 = self.model_factory.create() - dbgap_snapshot_2 = factories.dbGaPDataAccessSnapshotFactory.create( - dbgap_application=dbgap_application_2 - ) + dbgap_snapshot_2 = factories.dbGaPDataAccessSnapshotFactory.create(dbgap_application=dbgap_application_2) factories.dbGaPDataAccessRequestFactory.create( dbgap_data_access_snapshot=dbgap_snapshot_2, dbgap_current_status=models.dbGaPDataAccessRequest.APPROVED, @@ -355,9 +339,7 @@ def test_number_approved_dars_two_applications(self): def test_number_requested_dars_zero(self): """Table shows correct count for number of requested DARs when an application has a snapshot but no DARs.""" dbgap_application = self.model_factory.create() - factories.dbGaPDataAccessSnapshotFactory.create( - dbgap_application=dbgap_application - ) + factories.dbGaPDataAccessSnapshotFactory.create(dbgap_application=dbgap_application) table = self.table_class(self.model.objects.all()) self.assertEqual(table.rows[0].get_cell_value("number_requested_dars"), "0") @@ -370,9 +352,7 @@ def test_number_requested_dars_zero_no_snapshot(self): def test_number_requested_dars(self): """Table shows correct count for number of requested DARs when there is one.""" dbgap_application = self.model_factory.create() - dbgap_snapshot = factories.dbGaPDataAccessSnapshotFactory.create( - dbgap_application=dbgap_application - ) + dbgap_snapshot = factories.dbGaPDataAccessSnapshotFactory.create(dbgap_application=dbgap_application) factories.dbGaPDataAccessRequestFactory.create( dbgap_data_access_snapshot=dbgap_snapshot, dbgap_current_status=models.dbGaPDataAccessRequest.APPROVED, @@ -399,17 +379,13 @@ def test_number_requested_dars(self): def test_number_requested_dars_two_applications(self): """Number of requested DARs is correct for two applications.""" dbgap_application_1 = self.model_factory.create() - dbgap_snapshot_1 = factories.dbGaPDataAccessSnapshotFactory.create( - dbgap_application=dbgap_application_1 - ) + dbgap_snapshot_1 = factories.dbGaPDataAccessSnapshotFactory.create(dbgap_application=dbgap_application_1) factories.dbGaPDataAccessRequestFactory.create_batch( 2, dbgap_data_access_snapshot=dbgap_snapshot_1, ) dbgap_application_2 = self.model_factory.create() - dbgap_snapshot_2 = factories.dbGaPDataAccessSnapshotFactory.create( - dbgap_application=dbgap_application_2 - ) + dbgap_snapshot_2 = factories.dbGaPDataAccessSnapshotFactory.create(dbgap_application=dbgap_application_2) factories.dbGaPDataAccessRequestFactory.create( dbgap_data_access_snapshot=dbgap_snapshot_2, ) @@ -426,29 +402,21 @@ def test_last_update_no_snapshot(self): def test_last_update_one_snapshot(self): """Last update shows correct date with one snapshot.""" dbgap_application = self.model_factory.create() - snapshot = factories.dbGaPDataAccessSnapshotFactory.create( - dbgap_application=dbgap_application - ) + snapshot = factories.dbGaPDataAccessSnapshotFactory.create(dbgap_application=dbgap_application) table = self.table_class(self.model.objects.all()) self.assertIsNotNone(table.rows[0].get_cell_value("last_update")) - self.assertIn( - snapshot.get_absolute_url(), table.rows[0].get_cell("last_update") - ) + self.assertIn(snapshot.get_absolute_url(), table.rows[0].get_cell("last_update")) def test_last_update_two_snapshots(self): """Last update shows correct date with two snapshots.""" dbgap_application = self.model_factory.create() last_month = timezone.now() - timedelta(weeks=4) - factories.dbGaPDataAccessSnapshotFactory.create( - dbgap_application=dbgap_application, created=last_month - ) + factories.dbGaPDataAccessSnapshotFactory.create(dbgap_application=dbgap_application, created=last_month) latest_snapshot = factories.dbGaPDataAccessSnapshotFactory.create( dbgap_application=dbgap_application, created=timezone.now() ) table = self.table_class(self.model.objects.all()) - self.assertIn( - latest_snapshot.get_absolute_url(), table.rows[0].get_cell("last_update") - ) + self.assertIn(latest_snapshot.get_absolute_url(), table.rows[0].get_cell("last_update")) def test_ordering(self): """Instances are ordered alphabetically by dbgap_project_id.""" @@ -582,12 +550,8 @@ def test_row_count_with_two_objects(self): def test_ordering(self): """Instances are ordered alphabetically by dbgap_application and dbgap_dar_id.""" - dbgap_application_1 = factories.dbGaPApplicationFactory.create( - dbgap_project_id=2 - ) - dbgap_application_2 = factories.dbGaPApplicationFactory.create( - dbgap_project_id=1 - ) + dbgap_application_1 = factories.dbGaPApplicationFactory.create(dbgap_project_id=2) + dbgap_application_2 = factories.dbGaPApplicationFactory.create(dbgap_project_id=1) instance_1 = self.model_factory.create( dbgap_dar_id=4, dbgap_data_access_snapshot__dbgap_application=dbgap_application_1, @@ -638,16 +602,12 @@ def test_ordering(self): instance_1 = self.model_factory.create( dbgap_data_access_snapshot=dbgap_snapshot_1, ) - dbgap_snapshot_2 = factories.dbGaPDataAccessSnapshotFactory.create( - created=timezone.now() - timedelta(weeks=4) - ) + dbgap_snapshot_2 = factories.dbGaPDataAccessSnapshotFactory.create(created=timezone.now() - timedelta(weeks=4)) instance_2 = self.model_factory.create( dbgap_dar_id=instance_1.dbgap_dar_id, dbgap_data_access_snapshot=dbgap_snapshot_2, ) - dbgap_snapshot_3 = factories.dbGaPDataAccessSnapshotFactory.create( - created=timezone.now() - timedelta(weeks=3) - ) + dbgap_snapshot_3 = factories.dbGaPDataAccessSnapshotFactory.create(created=timezone.now() - timedelta(weeks=3)) instance_3 = self.model_factory.create( dbgap_dar_id=instance_1.dbgap_dar_id, dbgap_data_access_snapshot=dbgap_snapshot_3, @@ -680,9 +640,7 @@ def test_row_count_with_two_objects(self): def test_one_matching_workspace_with_access(self): """Table works if there is a matching workspace with access.""" workspace = factories.dbGaPWorkspaceFactory.create() - dar = factories.dbGaPDataAccessRequestForWorkspaceFactory( - dbgap_workspace=workspace - ) + dar = factories.dbGaPDataAccessRequestForWorkspaceFactory(dbgap_workspace=workspace) GroupGroupMembershipFactory.create( parent_group=workspace.workspace.authorization_domains.first(), child_group=dar.dbgap_data_access_snapshot.dbgap_application.anvil_access_group, @@ -696,9 +654,7 @@ def test_one_matching_workspace_with_access(self): def test_one_matching_workspace_without_access(self): """Table works if there is a matching workspace with access.""" workspace = factories.dbGaPWorkspaceFactory.create() - dar = factories.dbGaPDataAccessRequestForWorkspaceFactory( - dbgap_workspace=workspace - ) + dar = factories.dbGaPDataAccessRequestForWorkspaceFactory(dbgap_workspace=workspace) table = self.table_class([dar]) value = table.render_matching_workspaces(dar.get_dbgap_workspaces(), dar) self.assertIn(workspace.workspace.name, value) @@ -740,15 +696,12 @@ def test_ordering(self): class dbGaPDataAccessRequestSummaryTable(TestCase): - model = models.dbGaPDataAccessRequest model_factory = factories.dbGaPDataAccessRequestFactory table_class = tables.dbGaPDataAccessRequestSummaryTable def annotate(self, qs): - return qs.values("dbgap_dac", "dbgap_current_status").annotate( - total=Count("pk") - ) + return qs.values("dbgap_dac", "dbgap_current_status").annotate(total=Count("pk")) def test_row_count_with_no_objects(self): table = self.table_class(self.annotate(self.model.objects.all())) @@ -760,9 +713,7 @@ def test_row_count_with_one_row(self): self.assertEqual(len(table.rows), 1) def test_row_count_with_two_dacs(self): - self.model_factory.create( - dbgap_dac="FOO", dbgap_current_status=self.model.APPROVED - ) + self.model_factory.create(dbgap_dac="FOO", dbgap_current_status=self.model.APPROVED) self.model_factory.create(dbgap_dac="BAR", dbgap_current_status=self.model.NEW) table = self.table_class(self.annotate(self.model.objects.all())) self.assertEqual(len(table.rows), 2) diff --git a/primed/dbgap/tests/test_views.py b/primed/dbgap/tests/test_views.py index a2ebf614..e668b5f0 100644 --- a/primed/dbgap/tests/test_views.py +++ b/primed/dbgap/tests/test_views.py @@ -52,9 +52,7 @@ class dbGaPResponseTestMixin: def setUp(self): super().setUp() - self.dbgap_response_mock = responses.RequestsMock( - assert_all_requests_are_fired=True - ) + self.dbgap_response_mock = responses.RequestsMock(assert_all_requests_are_fired=True) self.dbgap_response_mock.start() def tearDown(self): @@ -79,9 +77,7 @@ def test_links_for_staff_view(self): """Returns successful response code.""" user = User.objects.create_user(username="test", password="test") user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.client.force_login(user) response = self.client.get(self.get_url()) @@ -90,22 +86,16 @@ def test_links_for_staff_view(self): # Links to add dbGaP info. self.assertNotContains(response, reverse("dbgap:dbgap_study_accessions:new")) self.assertNotContains(response, reverse("dbgap:dbgap_applications:new")) - self.assertNotContains( - response, reverse("dbgap:dbgap_applications:update_dars") - ) + self.assertNotContains(response, reverse("dbgap:dbgap_applications:update_dars")) def test_links_for_staff_edit(self): """Returns successful response code.""" user = User.objects.create_user(username="test", password="test") user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) self.client.force_login(user) response = self.client.get(self.get_url()) @@ -126,9 +116,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -157,9 +145,7 @@ def test_status_code_with_user_permission(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url()) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -171,9 +157,7 @@ def test_table_class(self): request.user = self.user response = self.get_view()(request) self.assertIn("table", response.context_data) - self.assertIsInstance( - response.context_data["table"], tables.dbGaPStudyAccessionTable - ) + self.assertIsInstance(response.context_data["table"], tables.dbGaPStudyAccessionTable) def test_workspace_table_none(self): """No rows are shown if there are no dbGaPStudyAccession objects.""" @@ -209,9 +193,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) # Create an object test this with. self.obj = factories.dbGaPStudyAccessionFactory.create() @@ -230,9 +212,7 @@ def test_view_redirect_not_logged_in(self): response = self.client.get(self.get_url(self.obj.dbgap_phs)) self.assertRedirects( response, - resolve_url(settings.LOGIN_URL) - + "?next=" - + self.get_url(self.obj.dbgap_phs), + resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(self.obj.dbgap_phs), ) def test_status_code_with_user_permission(self): @@ -244,9 +224,7 @@ def test_status_code_with_user_permission(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url(self.obj.dbgap_phs)) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -272,9 +250,7 @@ def test_workspace_table(self): request.user = self.user response = self.get_view()(request, dbgap_phs=self.obj.dbgap_phs) self.assertIn("workspace_table", response.context_data) - self.assertIsInstance( - response.context_data["workspace_table"], tables.dbGaPWorkspaceStaffTable - ) + self.assertIsInstance(response.context_data["workspace_table"], tables.dbGaPWorkspaceStaffTable) def test_workspace_table_none(self): """No workspaces are shown if the dbGaPStudyAccession does not have any workspaces.""" @@ -305,9 +281,7 @@ def test_workspace_table_two(self): def test_shows_workspace_for_only_this_dbGaPStudyAccession(self): """Only shows workspaces for this dbGaPStudyAccession.""" other_dbgap_study_accession = factories.dbGaPStudyAccessionFactory.create() - factories.dbGaPWorkspaceFactory.create( - dbgap_study_accession=other_dbgap_study_accession - ) + factories.dbGaPWorkspaceFactory.create(dbgap_study_accession=other_dbgap_study_accession) request = self.factory.get(self.get_url(self.obj.dbgap_phs)) request.user = self.user response = self.get_view()(request, dbgap_phs=self.obj.dbgap_phs) @@ -317,12 +291,8 @@ def test_shows_workspace_for_only_this_dbGaPStudyAccession(self): def test_context_show_edit_links_with_edit_permission(self): edit_user = User.objects.create_user(username="edit", password="test") edit_user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ), - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ), + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME), + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME), ) self.client.force_login(edit_user) account = factories.dbGaPStudyAccessionFactory.create() @@ -340,9 +310,7 @@ def test_context_show_edit_links_with_edit_permission(self): def test_context_show_edit_links_with_view_permission(self): view_user = User.objects.create_user(username="edit", password="test") view_user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ), + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME), ) self.client.force_login(view_user) account = factories.dbGaPStudyAccessionFactory.create() @@ -368,14 +336,10 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -390,9 +354,7 @@ def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." # Need a client for redirects. response = self.client.get(self.get_url()) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url() - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url()) def test_status_code_with_user_permission_edit(self): """Returns successful response code.""" @@ -403,9 +365,7 @@ def test_status_code_with_user_permission_edit(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url()) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -413,13 +373,9 @@ def test_access_without_user_permission(self): def test_access_without_user_permission_view(self): """Raises permission denied if user has no permissions.""" - user_view_perm = User.objects.create_user( - username="test-none", password="test-none" - ) + user_view_perm = User.objects.create_user(username="test-none", password="test-none") user_view_perm.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user_view_perm @@ -438,17 +394,13 @@ def test_form_class(self): request = self.factory.get(self.get_url()) request.user = self.user response = self.get_view()(request) - self.assertIsInstance( - response.context_data["form"], forms.dbGaPStudyAccessionForm - ) + self.assertIsInstance(response.context_data["form"], forms.dbGaPStudyAccessionForm) def test_can_create_object(self): """Can create an object.""" self.client.force_login(self.user) study = StudyFactory.create() - response = self.client.post( - self.get_url(), {"studies": [study.pk], "dbgap_phs": 1} - ) + response = self.client.post(self.get_url(), {"studies": [study.pk], "dbgap_phs": 1}) self.assertEqual(response.status_code, 302) # A new object was created. self.assertEqual(models.dbGaPStudyAccession.objects.count(), 1) @@ -461,9 +413,7 @@ def test_redirect_url(self): """Redirects to successful url.""" self.client.force_login(self.user) study = StudyFactory.create() - response = self.client.post( - self.get_url(), {"studies": [study.pk], "dbgap_phs": 1} - ) + response = self.client.post(self.get_url(), {"studies": [study.pk], "dbgap_phs": 1}) new_object = models.dbGaPStudyAccession.objects.latest("pk") self.assertRedirects(response, new_object.get_absolute_url()) @@ -479,9 +429,7 @@ def test_success_message(self): self.assertIn("messages", response.context) messages = list(response.context["messages"]) self.assertEqual(len(messages), 1) - self.assertEqual( - views.dbGaPStudyAccessionCreate.success_message, str(messages[0]) - ) + self.assertEqual(views.dbGaPStudyAccessionCreate.success_message, str(messages[0])) def test_error_missing_studies(self): """Form shows an error when studies is missing.""" @@ -565,14 +513,10 @@ def setUp(self): # Create a user with both view and edit permissions. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -586,9 +530,7 @@ def get_view(self): def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." response = self.client.get(self.get_url(1)) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(1) - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(1)) def test_status_code_with_user_permission(self): """Returns successful response code.""" @@ -600,13 +542,9 @@ def test_status_code_with_user_permission(self): def test_access_with_view_permission(self): """Raises permission denied if user has only view permission.""" instance = factories.dbGaPStudyAccessionFactory.create() - user_with_view_perm = User.objects.create_user( - username="test-other", password="test-other" - ) + user_with_view_perm = User.objects.create_user(username="test-other", password="test-other") user_with_view_perm.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url(instance.dbgap_phs)) request.user = user_with_view_perm @@ -616,9 +554,7 @@ def test_access_with_view_permission(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" instance = factories.dbGaPStudyAccessionFactory.create() - user_no_perms = User.objects.create_user( - username="test-other", password="test-other" - ) + user_no_perms = User.objects.create_user(username="test-other", password="test-other") request = self.factory.get(self.get_url(instance.dbgap_phs)) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -644,9 +580,7 @@ def test_can_modify_studies(self): study_2 = StudyFactory.create() instance = factories.dbGaPStudyAccessionFactory.create(studies=[study_1]) self.client.force_login(self.user) - response = self.client.post( - self.get_url(instance.dbgap_phs), {"studies": [study_1.pk, study_2.pk]} - ) + response = self.client.post(self.get_url(instance.dbgap_phs), {"studies": [study_1.pk, study_2.pk]}) self.assertEqual(response.status_code, 302) instance.refresh_from_db() self.assertEqual(instance.studies.count(), 2) @@ -656,13 +590,9 @@ def test_can_modify_studies(self): def test_does_not_modify_phs(self): """Does not modify phs when updating a dbGaPStudyAccession.""" study = StudyFactory.create() - instance = factories.dbGaPStudyAccessionFactory.create( - dbgap_phs=1234, studies=[study] - ) + instance = factories.dbGaPStudyAccessionFactory.create(dbgap_phs=1234, studies=[study]) self.client.force_login(self.user) - response = self.client.post( - self.get_url(instance.dbgap_phs), {"dbgap_phs": 2345, "studies": [study.pk]} - ) + response = self.client.post(self.get_url(instance.dbgap_phs), {"dbgap_phs": 2345, "studies": [study.pk]}) self.assertEqual(response.status_code, 302) instance.refresh_from_db() self.assertEqual(instance.dbgap_phs, 1234) @@ -670,30 +600,20 @@ def test_does_not_modify_phs(self): def test_success_message(self): """Response includes a success message if successful.""" study = StudyFactory.create() - instance = factories.dbGaPStudyAccessionFactory.create( - dbgap_phs=1234, studies=[study] - ) + instance = factories.dbGaPStudyAccessionFactory.create(dbgap_phs=1234, studies=[study]) self.client.force_login(self.user) - response = self.client.post( - self.get_url(instance.dbgap_phs), {"studies": [study.pk]}, follow=True - ) + response = self.client.post(self.get_url(instance.dbgap_phs), {"studies": [study.pk]}, follow=True) self.assertIn("messages", response.context) messages = list(response.context["messages"]) self.assertEqual(len(messages), 1) - self.assertEqual( - views.dbGaPStudyAccessionUpdate.success_message, str(messages[0]) - ) + self.assertEqual(views.dbGaPStudyAccessionUpdate.success_message, str(messages[0])) def test_redirects_to_object_detail(self): """After successfully creating an object, view redirects to the object's detail page.""" study = StudyFactory.create() - instance = factories.dbGaPStudyAccessionFactory.create( - dbgap_phs=1234, studies=[study] - ) + instance = factories.dbGaPStudyAccessionFactory.create(dbgap_phs=1234, studies=[study]) self.client.force_login(self.user) - response = self.client.post( - self.get_url(instance.dbgap_phs), {"studies": [study.pk]} - ) + response = self.client.post(self.get_url(instance.dbgap_phs), {"studies": [study.pk]}) self.assertRedirects(response, instance.get_absolute_url()) @@ -704,9 +624,7 @@ def setUp(self): # Create a user with the correct permissions. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -721,9 +639,7 @@ def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." # Need a client for redirects. response = self.client.get(self.get_url()) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url() - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url()) def test_status_code_with_user_permission(self): """Returns successful response code.""" @@ -733,9 +649,7 @@ def test_status_code_with_user_permission(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url()) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -746,14 +660,9 @@ def test_returns_all_objects(self): objects = factories.dbGaPStudyAccessionFactory.create_batch(10) self.client.force_login(self.user) response = self.client.get(self.get_url()) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + returned_ids = [int(x["id"]) for x in json.loads(response.content.decode("utf-8"))["results"]] self.assertEqual(len(returned_ids), 10) - self.assertEqual( - sorted(returned_ids), sorted([object.pk for object in objects]) - ) + self.assertEqual(sorted(returned_ids), sorted([object.pk for object in objects])) def test_returns_correct_object_match(self): """Queryset returns the correct objects when query matches the phs.""" @@ -761,10 +670,7 @@ def test_returns_correct_object_match(self): factories.dbGaPStudyAccessionFactory.create(dbgap_phs=8) self.client.force_login(self.user) response = self.client.get(self.get_url(), {"q": "7"}) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + returned_ids = [int(x["id"]) for x in json.loads(response.content.decode("utf-8"))["results"]] self.assertEqual(len(returned_ids), 1) self.assertEqual(returned_ids[0], object.pk) @@ -774,10 +680,7 @@ def test_returns_correct_object_starting_with_query(self): factories.dbGaPStudyAccessionFactory.create(dbgap_phs=8) self.client.force_login(self.user) response = self.client.get(self.get_url(), {"q": "7"}) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + returned_ids = [int(x["id"]) for x in json.loads(response.content.decode("utf-8"))["results"]] self.assertEqual(len(returned_ids), 1) self.assertEqual(returned_ids[0], object.pk) @@ -787,10 +690,7 @@ def test_returns_correct_object_containing_query(self): factories.dbGaPStudyAccessionFactory.create(dbgap_phs=754) self.client.force_login(self.user) response = self.client.get(self.get_url(), {"q": "6"}) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + returned_ids = [int(x["id"]) for x in json.loads(response.content.decode("utf-8"))["results"]] self.assertEqual(len(returned_ids), 1) self.assertEqual(returned_ids[0], object.pk) @@ -799,10 +699,7 @@ def test_ignores_phs_in_query(self): object = factories.dbGaPStudyAccessionFactory.create(dbgap_phs=7) self.client.force_login(self.user) response = self.client.get(self.get_url(), {"q": "phs7"}) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + returned_ids = [int(x["id"]) for x in json.loads(response.content.decode("utf-8"))["results"]] self.assertEqual(len(returned_ids), 1) self.assertEqual(returned_ids[0], object.pk) @@ -811,10 +708,7 @@ def test_removes_leading_zeros(self): object = factories.dbGaPStudyAccessionFactory.create(dbgap_phs=7) self.client.force_login(self.user) response = self.client.get(self.get_url(), {"q": "0007"}) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + returned_ids = [int(x["id"]) for x in json.loads(response.content.decode("utf-8"))["results"]] self.assertEqual(len(returned_ids), 1) self.assertEqual(returned_ids[0], object.pk) @@ -824,10 +718,7 @@ def test_does_not_remove_trailing_zeros(self): factories.dbGaPStudyAccessionFactory.create(dbgap_phs=71) self.client.force_login(self.user) response = self.client.get(self.get_url(), {"q": "700"}) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + returned_ids = [int(x["id"]) for x in json.loads(response.content.decode("utf-8"))["results"]] self.assertEqual(len(returned_ids), 1) self.assertEqual(returned_ids[0], object.pk) @@ -841,9 +732,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.workspace_type = "dbgap" @@ -861,9 +750,7 @@ def test_view_has_correct_table_class(self): request.user = self.user response = self.get_view()(request, workspace_type=self.workspace_type) self.assertIn("table", response.context_data) - self.assertIsInstance( - response.context_data["table"], tables.dbGaPWorkspaceStaffTable - ) + self.assertIsInstance(response.context_data["table"], tables.dbGaPWorkspaceStaffTable) class dbGaPWorkspaceDetailTest(TestCase): @@ -874,9 +761,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) def test_status_code_with_user_permission(self): @@ -920,9 +805,7 @@ def test_response_contains_dbgap_link(self): def test_links_audit_access_staff_view(self): user = UserFactory.create() user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) obj = factories.dbGaPWorkspaceFactory.create() self.client.force_login(user) @@ -937,11 +820,7 @@ def test_links_audit_access_staff_view(self): def test_links_audit_access_view_permission(self): user = UserFactory.create() - user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) - ) + user.user_permissions.add(Permission.objects.get(codename=AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME)) obj = factories.dbGaPWorkspaceFactory.create() self.client.force_login(user) response = self.client.get(obj.get_absolute_url()) @@ -956,11 +835,7 @@ def test_links_audit_access_view_permission(self): def test_associated_data_prep_view_user(self): """View users do not see the associated data prep section""" user = User.objects.create_user(username="test-view", password="test-view") - user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) - ) + user.user_permissions.add(Permission.objects.get(codename=AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME)) obj = factories.dbGaPWorkspaceFactory.create() DataPrepWorkspaceFactory.create(target_workspace=obj.workspace) @@ -988,15 +863,11 @@ def test_associated_data_prep_workspaces_context_exists(self): def test_only_show_one_associated_data_prep_workspace(self): dbGaP_obj = factories.dbGaPWorkspaceFactory.create() - dataPrep_obj = DataPrepWorkspaceFactory.create( - target_workspace=dbGaP_obj.workspace - ) + dataPrep_obj = DataPrepWorkspaceFactory.create(target_workspace=dbGaP_obj.workspace) self.client.force_login(self.user) response = self.client.get(dbGaP_obj.get_absolute_url()) self.assertIn("associated_data_prep_workspaces", response.context_data) - self.assertEqual( - len(response.context_data["associated_data_prep_workspaces"].rows), 1 - ) + self.assertEqual(len(response.context_data["associated_data_prep_workspaces"].rows), 1) self.assertIn( dataPrep_obj.workspace, response.context_data["associated_data_prep_workspaces"].data, @@ -1004,18 +875,12 @@ def test_only_show_one_associated_data_prep_workspace(self): def test_show_two_associated_data_prep_workspaces(self): dbGaP_obj = factories.dbGaPWorkspaceFactory.create() - dataPrep_obj1 = DataPrepWorkspaceFactory.create( - target_workspace=dbGaP_obj.workspace - ) - dataPrep_obj2 = DataPrepWorkspaceFactory.create( - target_workspace=dbGaP_obj.workspace - ) + dataPrep_obj1 = DataPrepWorkspaceFactory.create(target_workspace=dbGaP_obj.workspace) + dataPrep_obj2 = DataPrepWorkspaceFactory.create(target_workspace=dbGaP_obj.workspace) self.client.force_login(self.user) response = self.client.get(dbGaP_obj.get_absolute_url()) self.assertIn("associated_data_prep_workspaces", response.context_data) - self.assertEqual( - len(response.context_data["associated_data_prep_workspaces"].rows), 2 - ) + self.assertEqual(len(response.context_data["associated_data_prep_workspaces"].rows), 2) self.assertIn( dataPrep_obj1.workspace, response.context_data["associated_data_prep_workspaces"].data, @@ -1034,9 +899,7 @@ def test_context_data_prep_active_with_no_prep_workspace(self): def test_context_data_prep_active_with_one_inactive_prep_workspace(self): instance = factories.dbGaPWorkspaceFactory.create() - DataPrepWorkspaceFactory.create( - target_workspace=instance.workspace, is_active=False - ) + DataPrepWorkspaceFactory.create(target_workspace=instance.workspace, is_active=False) self.client.force_login(self.user) response = self.client.get(instance.get_absolute_url()) self.assertIn("data_prep_active", response.context_data) @@ -1044,9 +907,7 @@ def test_context_data_prep_active_with_one_inactive_prep_workspace(self): def test_context_data_prep_active_with_one_active_prep_workspace(self): instance = factories.dbGaPWorkspaceFactory.create() - DataPrepWorkspaceFactory.create( - target_workspace=instance.workspace, is_active=True - ) + DataPrepWorkspaceFactory.create(target_workspace=instance.workspace, is_active=True) self.client.force_login(self.user) response = self.client.get(instance.get_absolute_url()) self.assertIn("data_prep_active", response.context_data) @@ -1054,12 +915,8 @@ def test_context_data_prep_active_with_one_active_prep_workspace(self): def test_context_data_prep_active_with_one_active_one_inactive_prep_workspace(self): instance = factories.dbGaPWorkspaceFactory.create() - DataPrepWorkspaceFactory.create( - target_workspace=instance.workspace, is_active=True - ) - DataPrepWorkspaceFactory.create( - target_workspace=instance.workspace, is_active=True - ) + DataPrepWorkspaceFactory.create(target_workspace=instance.workspace, is_active=True) + DataPrepWorkspaceFactory.create(target_workspace=instance.workspace, is_active=True) self.client.force_login(self.user) response = self.client.get(instance.get_absolute_url()) self.assertIn("data_prep_active", response.context_data) @@ -1078,14 +935,10 @@ def setUp(self): # Create a user with both view and edit permissions. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) self.requester = UserFactory.create() self.workspace_type = "dbgap" @@ -1096,13 +949,7 @@ def get_url(self, *args): def get_api_url(self, billing_project_name, workspace_name): """Return the Terra API url for a given billing project and workspace.""" - return ( - self.api_client.rawls_entry_point - + "/api/workspaces/" - + billing_project_name - + "/" - + workspace_name - ) + return self.api_client.rawls_entry_point + "/api/workspaces/" + billing_project_name + "/" + workspace_name def test_creates_upload_workspace_without_duos(self): """Posting valid data to the form creates a workspace data object when using a custom adapter.""" @@ -1151,9 +998,7 @@ def test_creates_upload_workspace_without_duos(self): self.assertEqual(models.dbGaPWorkspace.objects.count(), 1) new_workspace_data = models.dbGaPWorkspace.objects.latest("pk") self.assertEqual(new_workspace_data.workspace, new_workspace) - self.assertEqual( - new_workspace_data.dbgap_study_accession, dbgap_study_accession - ) + self.assertEqual(new_workspace_data.dbgap_study_accession, dbgap_study_accession) self.assertEqual(new_workspace_data.dbgap_version, 2) self.assertEqual(new_workspace_data.dbgap_participant_set, 3) self.assertEqual(new_workspace_data.dbgap_consent_abbreviation, "GRU-TEST") @@ -1230,14 +1075,10 @@ def setUp(self): # Create a user with both view and edit permissions. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) self.requester = UserFactory.create() self.workspace_type = "dbgap" @@ -1248,25 +1089,15 @@ def get_url(self, *args): def get_api_url(self, billing_project_name, workspace_name): """Return the Terra API url for a given billing project and workspace.""" - return ( - self.api_client.rawls_entry_point - + "/api/workspaces/" - + billing_project_name - + "/" - + workspace_name - ) + return self.api_client.rawls_entry_point + "/api/workspaces/" + billing_project_name + "/" + workspace_name - def get_api_json_response( - self, billing_project, workspace, authorization_domains=[], access="OWNER" - ): + def get_api_json_response(self, billing_project, workspace, authorization_domains=[], access="OWNER"): """Return a pared down version of the json response from the AnVIL API with only fields we need.""" json_data = { "accessLevel": access, "owners": [], "workspace": { - "authorizationDomain": [ - {"membersGroupName": x} for x in authorization_domains - ], + "authorizationDomain": [{"membersGroupName": x} for x in authorization_domains], "name": workspace, "namespace": billing_project, "isLocked": False, @@ -1287,9 +1118,7 @@ def test_creates_dbgap_workspace_without_duos(self): responses.GET, workspace_list_url, match=[ - responses.matchers.query_param_matcher( - {"fields": "workspace.namespace,workspace.name,accessLevel"} - ) + responses.matchers.query_param_matcher({"fields": "workspace.namespace,workspace.name,accessLevel"}) ], status=200, json=[self.get_api_json_response(billing_project.name, workspace_name)], @@ -1353,9 +1182,7 @@ def test_creates_dbgap_workspace_without_duos(self): self.assertEqual(models.dbGaPWorkspace.objects.count(), 1) new_workspace_data = models.dbGaPWorkspace.objects.latest("pk") self.assertEqual(new_workspace_data.workspace, new_workspace) - self.assertEqual( - new_workspace_data.dbgap_study_accession, dbgap_study_accession - ) + self.assertEqual(new_workspace_data.dbgap_study_accession, dbgap_study_accession) self.assertEqual(new_workspace_data.dbgap_version, 2) self.assertEqual(new_workspace_data.dbgap_participant_set, 3) self.assertEqual(new_workspace_data.dbgap_consent_abbreviation, "GRU-TEST") @@ -1380,9 +1207,7 @@ def test_creates_dbgap_workspace_with_duos(self): responses.GET, workspace_list_url, match=[ - responses.matchers.query_param_matcher( - {"fields": "workspace.namespace,workspace.name,accessLevel"} - ) + responses.matchers.query_param_matcher({"fields": "workspace.namespace,workspace.name,accessLevel"}) ], status=200, json=[self.get_api_json_response(billing_project.name, workspace_name)], @@ -1461,9 +1286,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -1492,9 +1315,7 @@ def test_status_code_with_user_permission(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url()) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -1506,9 +1327,7 @@ def test_table_class(self): request.user = self.user response = self.get_view()(request) self.assertIn("table", response.context_data) - self.assertIsInstance( - response.context_data["table"], tables.dbGaPApplicationTable - ) + self.assertIsInstance(response.context_data["table"], tables.dbGaPApplicationTable) class dbGaPApplicationDetailTest(TestCase): @@ -1518,9 +1337,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) # Create an object test this with. self.obj = factories.dbGaPApplicationFactory.create() @@ -1539,9 +1356,7 @@ def test_view_redirect_not_logged_in(self): response = self.client.get(self.get_url(self.obj.dbgap_project_id)) self.assertRedirects( response, - resolve_url(settings.LOGIN_URL) - + "?next=" - + self.get_url(self.obj.dbgap_project_id), + resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(self.obj.dbgap_project_id), ) def test_status_code_with_user_permission(self): @@ -1553,9 +1368,7 @@ def test_status_code_with_user_permission(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url(self.obj.dbgap_project_id)) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -1577,9 +1390,7 @@ def test_view_status_code_with_invalid_pk(self): def test_staff_edit_links(self): self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) self.client.force_login(self.user) response = self.client.get(self.get_url(self.obj.dbgap_project_id)) @@ -1629,9 +1440,7 @@ def test_snapshot_table_none(self): request.user = self.user response = self.get_view()(request, dbgap_project_id=self.obj.dbgap_project_id) self.assertIn("data_access_snapshot_table", response.context_data) - self.assertEqual( - len(response.context_data["data_access_snapshot_table"].rows), 0 - ) + self.assertEqual(len(response.context_data["data_access_snapshot_table"].rows), 0) def test_snapshot_table_one(self): """One snapshots is shown if the dbGaPApplication has one snapshots.""" @@ -1640,37 +1449,27 @@ def test_snapshot_table_one(self): request.user = self.user response = self.get_view()(request, dbgap_project_id=self.obj.dbgap_project_id) self.assertIn("data_access_snapshot_table", response.context_data) - self.assertEqual( - len(response.context_data["data_access_snapshot_table"].rows), 1 - ) + self.assertEqual(len(response.context_data["data_access_snapshot_table"].rows), 1) def test_snapshot_table_two(self): """Two snapshots are shown if the dbGaPApplication has two snapshots.""" - factories.dbGaPDataAccessSnapshotFactory.create( - dbgap_application=self.obj, is_most_recent=False - ) + factories.dbGaPDataAccessSnapshotFactory.create(dbgap_application=self.obj, is_most_recent=False) factories.dbGaPDataAccessSnapshotFactory.create(dbgap_application=self.obj) request = self.factory.get(self.get_url(self.obj.dbgap_project_id)) request.user = self.user response = self.get_view()(request, dbgap_project_id=self.obj.dbgap_project_id) self.assertIn("data_access_snapshot_table", response.context_data) - self.assertEqual( - len(response.context_data["data_access_snapshot_table"].rows), 2 - ) + self.assertEqual(len(response.context_data["data_access_snapshot_table"].rows), 2) def test_shows_snapshots_for_only_this_application(self): """Only shows snapshots for this dbGaPApplication.""" other_dbgap_application = factories.dbGaPApplicationFactory.create() - factories.dbGaPDataAccessSnapshotFactory.create( - dbgap_application=other_dbgap_application - ) + factories.dbGaPDataAccessSnapshotFactory.create(dbgap_application=other_dbgap_application) request = self.factory.get(self.get_url(self.obj.dbgap_project_id)) request.user = self.user response = self.get_view()(request, dbgap_project_id=self.obj.dbgap_project_id) self.assertIn("data_access_snapshot_table", response.context_data) - self.assertEqual( - len(response.context_data["data_access_snapshot_table"].rows), 0 - ) + self.assertEqual(len(response.context_data["data_access_snapshot_table"].rows), 0) def test_context_latest_snapshot_no_snapshot(self): """latest_snapshot is None in context when there are no dbGaPDataAccessSnapshots for this application.""" @@ -1682,9 +1481,7 @@ def test_context_latest_snapshot_no_snapshot(self): def test_context_latest_snapshot_one_snapshot(self): """latest_snapshot is correct in context when there is one dbGaPDataAccessSnapshot for this application.""" - dbgap_snapshot = factories.dbGaPDataAccessSnapshotFactory.create( - dbgap_application=self.obj - ) + dbgap_snapshot = factories.dbGaPDataAccessSnapshotFactory.create(dbgap_application=self.obj) request = self.factory.get(self.get_url(self.obj.dbgap_project_id)) request.user = self.user response = self.get_view()(request, dbgap_project_id=self.obj.dbgap_project_id) @@ -1714,9 +1511,7 @@ def test_table_default_ordering(self): created=timezone.now() - timedelta(weeks=4), is_most_recent=False, ) - snapshot_2 = factories.dbGaPDataAccessSnapshotFactory.create( - dbgap_application=self.obj, created=timezone.now() - ) + snapshot_2 = factories.dbGaPDataAccessSnapshotFactory.create(dbgap_application=self.obj, created=timezone.now()) request = self.factory.get(self.get_url(self.obj.dbgap_project_id)) request.user = self.user response = self.get_view()(request, dbgap_project_id=self.obj.dbgap_project_id) @@ -1736,14 +1531,10 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) # Create the admin group. self.cc_admin_group = ManagedGroupFactory.create(name="TEST_PRIMED_CC_ADMINS") @@ -1760,9 +1551,7 @@ def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." # Need a client for redirects. response = self.client.get(self.get_url()) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url() - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url()) def test_status_code_with_user_permission_edit(self): """Returns successful response code.""" @@ -1773,9 +1562,7 @@ def test_status_code_with_user_permission_edit(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url()) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -1783,13 +1570,9 @@ def test_access_without_user_permission(self): def test_access_without_user_permission_view(self): """Raises permission denied if user has no permissions.""" - user_view_perm = User.objects.create_user( - username="test-none", password="test-none" - ) + user_view_perm = User.objects.create_user(username="test-none", password="test-none") user_view_perm.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user_view_perm @@ -1815,13 +1598,8 @@ def test_can_create_object(self): self.client.force_login(self.user) pi = UserFactory.create() # API response to create the associated anvil_access_group. - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_DBGAP_ACCESS_1" - ) - self.anvil_response_mock.add( - responses.POST, api_url, status=201, json={"message": "mock message"} - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_DBGAP_ACCESS_1" + self.anvil_response_mock.add(responses.POST, api_url, status=201, json={"message": "mock message"}) # CC admins group membership. self.anvil_response_mock.add( responses.PUT, @@ -1829,9 +1607,7 @@ def test_can_create_object(self): + "/api/groups/v1/TEST_PRIMED_DBGAP_ACCESS_1/admin/TEST_PRIMED_CC_ADMINS@firecloud.org", status=204, ) - response = self.client.post( - self.get_url(), {"principal_investigator": pi.pk, "dbgap_project_id": 1} - ) + response = self.client.post(self.get_url(), {"principal_investigator": pi.pk, "dbgap_project_id": 1}) self.assertEqual(response.status_code, 302) # A new object was created. self.assertEqual(models.dbGaPApplication.objects.count(), 1) @@ -1844,22 +1620,15 @@ def test_redirect_url(self): self.client.force_login(self.user) pi = UserFactory.create() # API response to create the associated anvil_access_group. - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_DBGAP_ACCESS_1" - ) - self.anvil_response_mock.add( - responses.POST, api_url, status=201, json={"message": "mock message"} - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_DBGAP_ACCESS_1" + self.anvil_response_mock.add(responses.POST, api_url, status=201, json={"message": "mock message"}) # CC admins group membership. self.anvil_response_mock.add( responses.PUT, api_url + "/admin/TEST_PRIMED_CC_ADMINS@firecloud.org", status=204, ) - response = self.client.post( - self.get_url(), {"principal_investigator": pi.pk, "dbgap_project_id": 1} - ) + response = self.client.post(self.get_url(), {"principal_investigator": pi.pk, "dbgap_project_id": 1}) new_object = models.dbGaPApplication.objects.latest("pk") self.assertRedirects(response, new_object.get_absolute_url()) @@ -1868,13 +1637,8 @@ def test_success_message(self): self.client.force_login(self.user) pi = UserFactory.create() # API response to create the associated anvil_access_group. - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_DBGAP_ACCESS_1" - ) - self.anvil_response_mock.add( - responses.POST, api_url, status=201, json={"message": "mock message"} - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_DBGAP_ACCESS_1" + self.anvil_response_mock.add(responses.POST, api_url, status=201, json={"message": "mock message"}) # CC admins group membership. self.anvil_response_mock.add( responses.PUT, @@ -1989,22 +1753,15 @@ def test_creates_anvil_access_group(self): self.client.force_login(self.user) pi = UserFactory.create() # API response to create the associated anvil_access_group. - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_DBGAP_ACCESS_12498" - ) - self.anvil_response_mock.add( - responses.POST, api_url, status=201, json={"message": "mock message"} - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_DBGAP_ACCESS_12498" + self.anvil_response_mock.add(responses.POST, api_url, status=201, json={"message": "mock message"}) # CC admins group membership. self.anvil_response_mock.add( responses.PUT, api_url + "/admin/TEST_PRIMED_CC_ADMINS@firecloud.org", status=204, ) - response = self.client.post( - self.get_url(), {"principal_investigator": pi.pk, "dbgap_project_id": 12498} - ) + response = self.client.post(self.get_url(), {"principal_investigator": pi.pk, "dbgap_project_id": 12498}) self.assertEqual(response.status_code, 302) new_object = models.dbGaPApplication.objects.latest("pk") # A new group was created. @@ -2027,21 +1784,15 @@ def test_creates_anvil_access_group_different_setting_data_access_group_prefix( self.client.force_login(self.user) pi = UserFactory.create() # API response to create the associated anvil_access_group. - api_url = ( - self.api_client.sam_entry_point + "/api/groups/v1/foo_DBGAP_ACCESS_12498" - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/foo_DBGAP_ACCESS_12498" # CC admins group membership. self.anvil_response_mock.add( responses.PUT, api_url + "/admin/TEST_PRIMED_CC_ADMINS@firecloud.org", status=204, ) - self.anvil_response_mock.add( - responses.POST, api_url, status=201, json={"message": "mock message"} - ) - response = self.client.post( - self.get_url(), {"principal_investigator": pi.pk, "dbgap_project_id": 12498} - ) + self.anvil_response_mock.add(responses.POST, api_url, status=201, json={"message": "mock message"}) + response = self.client.post(self.get_url(), {"principal_investigator": pi.pk, "dbgap_project_id": 12498}) self.assertEqual(response.status_code, 302) new_object = models.dbGaPApplication.objects.latest("pk") # A new group was created. @@ -2063,22 +1814,15 @@ def test_creates_anvil_access_group_different_setting_cc_admin_group(self): self.client.force_login(self.user) pi = UserFactory.create() # API response to create the associated anvil_access_group. - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_DBGAP_ACCESS_12498" - ) - self.anvil_response_mock.add( - responses.POST, api_url, status=201, json={"message": "mock message"} - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_DBGAP_ACCESS_12498" + self.anvil_response_mock.add(responses.POST, api_url, status=201, json={"message": "mock message"}) # CC admins group membership. self.anvil_response_mock.add( responses.PUT, api_url + "/admin/foo@firecloud.org", status=204, ) - response = self.client.post( - self.get_url(), {"principal_investigator": pi.pk, "dbgap_project_id": 12498} - ) + response = self.client.post(self.get_url(), {"principal_investigator": pi.pk, "dbgap_project_id": 12498}) self.assertEqual(response.status_code, 302) new_object = models.dbGaPApplication.objects.latest("pk") # A new group was created. @@ -2098,16 +1842,9 @@ def test_manage_group_create_api_error(self): self.client.force_login(self.user) pi = UserFactory.create() # API response to create the associated anvil_access_group. - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_DBGAP_ACCESS_1" - ) - self.anvil_response_mock.add( - responses.POST, api_url, status=500, json={"message": "other error"} - ) - response = self.client.post( - self.get_url(), {"principal_investigator": pi.pk, "dbgap_project_id": 1} - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_DBGAP_ACCESS_1" + self.anvil_response_mock.add(responses.POST, api_url, status=500, json={"message": "other error"}) + response = self.client.post(self.get_url(), {"principal_investigator": pi.pk, "dbgap_project_id": 1}) self.assertEqual(response.status_code, 200) # The form is valid... form = response.context["form"] @@ -2126,9 +1863,7 @@ def test_managed_group_already_exists_in_app(self): pi = UserFactory.create() # Create a group with the same name. ManagedGroupFactory.create(name="TEST_PRIMED_DBGAP_ACCESS_1") - response = self.client.post( - self.get_url(), {"principal_investigator": pi.pk, "dbgap_project_id": 1} - ) + response = self.client.post(self.get_url(), {"principal_investigator": pi.pk, "dbgap_project_id": 1}) self.assertEqual(response.status_code, 200) # The form is valid... form = response.context["form"] @@ -2136,9 +1871,7 @@ def test_managed_group_already_exists_in_app(self): # ...but there was an error with the group name. messages = list(response.context["messages"]) self.assertEqual(len(messages), 1) - self.assertEqual( - views.dbGaPApplicationCreate.ERROR_CREATING_GROUP, str(messages[0]) - ) + self.assertEqual(views.dbGaPApplicationCreate.ERROR_CREATING_GROUP, str(messages[0])) # No dbGaPApplication was created. self.assertEqual(models.dbGaPApplication.objects.count(), 0) @@ -2147,13 +1880,8 @@ def test_admin_group_membership_api_error(self): self.client.force_login(self.user) pi = UserFactory.create() # API response to create the associated anvil_access_group. - api_url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/TEST_PRIMED_DBGAP_ACCESS_1" - ) - self.anvil_response_mock.add( - responses.POST, api_url, status=201, json={"message": "other error"} - ) + api_url = self.api_client.sam_entry_point + "/api/groups/v1/TEST_PRIMED_DBGAP_ACCESS_1" + self.anvil_response_mock.add(responses.POST, api_url, status=201, json={"message": "other error"}) # CC admins group membership. self.anvil_response_mock.add( responses.PUT, @@ -2161,9 +1889,7 @@ def test_admin_group_membership_api_error(self): status=404, json={"message": "other error"}, ) - response = self.client.post( - self.get_url(), {"principal_investigator": pi.pk, "dbgap_project_id": 1} - ) + response = self.client.post(self.get_url(), {"principal_investigator": pi.pk, "dbgap_project_id": 1}) self.assertEqual(response.status_code, 200) # The form is valid... form = response.context["form"] @@ -2188,14 +1914,10 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) self.dbgap_application = factories.dbGaPApplicationFactory.create() self.pi_name = fake.name() @@ -2214,99 +1936,63 @@ def get_view(self): def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." # Need a client for redirects. - response = self.client.get( - self.get_url(self.dbgap_application.dbgap_project_id) - ) + response = self.client.get(self.get_url(self.dbgap_application.dbgap_project_id)) self.assertRedirects( response, - resolve_url(settings.LOGIN_URL) - + "?next=" - + self.get_url(self.dbgap_application.dbgap_project_id), + resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(self.dbgap_application.dbgap_project_id), ) def test_status_code_with_user_permission_edit(self): """Returns successful response code.""" - request = self.factory.get( - self.get_url(self.dbgap_application.dbgap_project_id) - ) + request = self.factory.get(self.get_url(self.dbgap_application.dbgap_project_id)) request.user = self.user - response = self.get_view()( - request, dbgap_project_id=self.dbgap_application.dbgap_project_id - ) + response = self.get_view()(request, dbgap_project_id=self.dbgap_application.dbgap_project_id) self.assertEqual(response.status_code, 200) def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) - request = self.factory.get( - self.get_url(self.dbgap_application.dbgap_project_id) - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") + request = self.factory.get(self.get_url(self.dbgap_application.dbgap_project_id)) request.user = user_no_perms with self.assertRaises(PermissionDenied): - self.get_view()( - request, dbgap_project_id=self.dbgap_application.dbgap_project_id - ) + self.get_view()(request, dbgap_project_id=self.dbgap_application.dbgap_project_id) def test_access_without_user_permission_view(self): """Raises permission denied if user has no permissions.""" - user_view_perm = User.objects.create_user( - username="test-none", password="test-none" - ) + user_view_perm = User.objects.create_user(username="test-none", password="test-none") user_view_perm.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) - ) - request = self.factory.get( - self.get_url(self.dbgap_application.dbgap_project_id) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) + request = self.factory.get(self.get_url(self.dbgap_application.dbgap_project_id)) request.user = user_view_perm with self.assertRaises(PermissionDenied): - self.get_view()( - request, dbgap_project_id=self.dbgap_application.dbgap_project_id - ) + self.get_view()(request, dbgap_project_id=self.dbgap_application.dbgap_project_id) def test_has_form_in_context(self): """Response includes a form.""" - request = self.factory.get( - self.get_url(self.dbgap_application.dbgap_project_id) - ) + request = self.factory.get(self.get_url(self.dbgap_application.dbgap_project_id)) request.user = self.user - response = self.get_view()( - request, dbgap_project_id=self.dbgap_application.dbgap_project_id - ) + response = self.get_view()(request, dbgap_project_id=self.dbgap_application.dbgap_project_id) self.assertTrue("form" in response.context_data) def test_form_class(self): """Form is the expected class.""" - request = self.factory.get( - self.get_url(self.dbgap_application.dbgap_project_id) - ) + request = self.factory.get(self.get_url(self.dbgap_application.dbgap_project_id)) request.user = self.user - response = self.get_view()( - request, dbgap_project_id=self.dbgap_application.dbgap_project_id - ) - self.assertIsInstance( - response.context_data["form"], forms.dbGaPDataAccessSnapshotForm - ) + response = self.get_view()(request, dbgap_project_id=self.dbgap_application.dbgap_project_id) + self.assertIsInstance(response.context_data["form"], forms.dbGaPDataAccessSnapshotForm) def test_can_create_object(self): """Can create a dbGaPSnapshot and related dbGaPDataAccessRequests for this dbGaPApplication.""" phs = "phs{phs:06d}".format(phs=fake.random_int()) study_json = factories.dbGaPJSONStudyFactory(study_accession=phs) - project_json = factories.dbGaPJSONProjectFactory( - dbgap_application=self.dbgap_application, studies=[study_json] - ) + project_json = factories.dbGaPJSONProjectFactory(dbgap_application=self.dbgap_application, studies=[study_json]) self.dbgap_response_mock.add( responses.GET, constants.DBGAP_STUDY_URL, match=[responses.matchers.query_param_matcher({"study_id": phs})], status=302, - headers={ - "Location": constants.DBGAP_STUDY_URL + "?study_id=" + phs + ".v1.p1" - }, + headers={"Location": constants.DBGAP_STUDY_URL + "?study_id=" + phs + ".v1.p1"}, ) self.client.force_login(self.user) response = self.client.post( @@ -2336,21 +2022,15 @@ def test_can_create_object_and_related_dars(self): current_DAR_status="approved", was_approved="yes", ) - study_json = factories.dbGaPJSONStudyFactory( - study_accession="phs000421", requests=[dar_json] - ) - project_json = factories.dbGaPJSONProjectFactory( - dbgap_application=self.dbgap_application, studies=[study_json] - ) + study_json = factories.dbGaPJSONStudyFactory(study_accession="phs000421", requests=[dar_json]) + project_json = factories.dbGaPJSONProjectFactory(dbgap_application=self.dbgap_application, studies=[study_json]) # Add responses with the study version and participant_set. self.dbgap_response_mock.add( responses.GET, constants.DBGAP_STUDY_URL, match=[responses.matchers.query_param_matcher({"study_id": "phs000421"})], status=302, - headers={ - "Location": constants.DBGAP_STUDY_URL + "?study_id=phs000421.v32.p18" - }, + headers={"Location": constants.DBGAP_STUDY_URL + "?study_id=phs000421.v32.p18"}, ) self.client.force_login(self.user) response = self.client.post( @@ -2393,10 +2073,7 @@ def test_redirect_url(self): constants.DBGAP_STUDY_URL, match=[responses.matchers.query_param_matcher({"study_id": phs})], status=302, - headers={ - "Location": constants.DBGAP_STUDY_URL - + "?study_id={}.v32.p18".format(phs) - }, + headers={"Location": constants.DBGAP_STUDY_URL + "?study_id={}.v32.p18".format(phs)}, ) self.client.force_login(self.user) response = self.client.post( @@ -2422,10 +2099,7 @@ def test_success_message(self): constants.DBGAP_STUDY_URL, match=[responses.matchers.query_param_matcher({"study_id": phs})], status=302, - headers={ - "Location": constants.DBGAP_STUDY_URL - + "?study_id={}.v32.p18".format(phs) - }, + headers={"Location": constants.DBGAP_STUDY_URL + "?study_id={}.v32.p18".format(phs)}, ) self.client.force_login(self.user) response = self.client.post( @@ -2440,9 +2114,7 @@ def test_success_message(self): self.assertIn("messages", response.context) messages = list(response.context["messages"]) self.assertEqual(len(messages), 1) - self.assertEqual( - views.dbGaPDataAccessSnapshotCreate.success_message, str(messages[0]) - ) + self.assertEqual(views.dbGaPDataAccessSnapshotCreate.success_message, str(messages[0])) def test_error_missing_json(self): """Form shows an error when dbgap_dar_data is missing.""" @@ -2491,9 +2163,7 @@ def test_has_form_when_one_snapshot_exists(self): current_DAR_status="approved", DAC_abbrev="FOOBAR", ) - study_json = factories.dbGaPJSONStudyFactory( - study_accession=phs, requests=[request_json] - ) + study_json = factories.dbGaPJSONStudyFactory(study_accession=phs, requests=[request_json]) project_json = factories.dbGaPJSONProjectFactory( dbgap_application=self.dbgap_application, studies=[study_json], @@ -2517,9 +2187,7 @@ def test_has_form_when_one_snapshot_exists(self): ) # Now try to load the page again. self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.dbgap_application.dbgap_project_id) - ) + response = self.client.get(self.get_url(self.dbgap_application.dbgap_project_id)) self.assertEqual(response.status_code, 200) self.assertTrue("form" in response.context_data) @@ -2534,9 +2202,7 @@ def test_updates_existing_snapshot_is_most_recent(self): current_DAR_status="approved", DAC_abbrev="FOOBAR", ) - study_json = factories.dbGaPJSONStudyFactory( - study_accession=phs, requests=[request_json] - ) + study_json = factories.dbGaPJSONStudyFactory(study_accession=phs, requests=[request_json]) project_json = factories.dbGaPJSONProjectFactory( dbgap_application=self.dbgap_application, studies=[study_json], @@ -2589,9 +2255,7 @@ def test_can_add_a_second_snapshot_with_dars(self): current_DAR_status="approved", DAC_abbrev="FOOBAR", ) - study_json = factories.dbGaPJSONStudyFactory( - study_accession=phs, requests=[request_json] - ) + study_json = factories.dbGaPJSONStudyFactory(study_accession=phs, requests=[request_json]) project_json = factories.dbGaPJSONProjectFactory( dbgap_application=self.dbgap_application, studies=[study_json], @@ -2638,9 +2302,7 @@ def test_can_add_a_second_snapshot_with_dars(self): self.assertEqual(new_dar.dbgap_current_status, "approved") # These should be obtained from the original dar. self.assertEqual(new_dar.original_version, original_dar.original_version) - self.assertEqual( - new_dar.original_participant_set, original_dar.original_participant_set - ) + self.assertEqual(new_dar.original_participant_set, original_dar.original_participant_set) def test_post_invalid_json(self): """JSON is invalid.""" @@ -2667,9 +2329,7 @@ def test_post_invalid_json(self): def test_json_project_id_does_not_match(self): """Error message when project_id in JSON does not match project_id in dbGaPApplication.""" - project_json = factories.dbGaPJSONProjectFactory( - Project_id=self.dbgap_application.dbgap_project_id + 1 - ) + project_json = factories.dbGaPJSONProjectFactory(Project_id=self.dbgap_application.dbgap_project_id + 1) self.client.force_login(self.user) response = self.client.post( self.get_url(self.dbgap_application.dbgap_project_id), @@ -2695,17 +2355,11 @@ def test_json_project_id_does_not_match(self): def test_context_includes_dbgap_application(self): """Response context data includes the dbGaP application.""" - request = self.factory.get( - self.get_url(self.dbgap_application.dbgap_project_id) - ) + request = self.factory.get(self.get_url(self.dbgap_application.dbgap_project_id)) request.user = self.user - response = self.get_view()( - request, dbgap_project_id=self.dbgap_application.dbgap_project_id - ) + response = self.get_view()(request, dbgap_project_id=self.dbgap_application.dbgap_project_id) self.assertTrue("dbgap_application" in response.context_data) - self.assertEqual( - response.context_data["dbgap_application"], self.dbgap_application - ) + self.assertEqual(response.context_data["dbgap_application"], self.dbgap_application) def test_snapshot_not_created_if_http404(self): """The dbGaPDataAccessSnapshot is not created if DARs cannot be created due to a HTTP 404 response.""" @@ -2718,9 +2372,7 @@ def test_snapshot_not_created_if_http404(self): current_DAR_status="approved", DAC_abbrev="FOOBAR", ) - study_json = factories.dbGaPJSONStudyFactory( - study_accession=phs, requests=[request_json] - ) + study_json = factories.dbGaPJSONStudyFactory(study_accession=phs, requests=[request_json]) project_json = factories.dbGaPJSONProjectFactory( dbgap_application=self.dbgap_application, studies=[study_json], @@ -2749,9 +2401,7 @@ def test_snapshot_not_created_if_http404(self): self.assertIn("messages", response.context) messages = list(response.context["messages"]) self.assertEqual(len(messages), 1) - self.assertEqual( - views.dbGaPDataAccessSnapshotCreate.ERROR_CREATING_DARS, str(messages[0]) - ) + self.assertEqual(views.dbGaPDataAccessSnapshotCreate.ERROR_CREATING_DARS, str(messages[0])) def test_existing_snapshot_not_updated_http404(self): """The dbGaPDataAccessSnapshot is not created if there is an HTTP 404 error.""" @@ -2764,9 +2414,7 @@ def test_existing_snapshot_not_updated_http404(self): current_DAR_status="approved", DAC_abbrev="FOOBAR", ) - study_json = factories.dbGaPJSONStudyFactory( - study_accession=phs, requests=[request_json] - ) + study_json = factories.dbGaPJSONStudyFactory(study_accession=phs, requests=[request_json]) project_json = factories.dbGaPJSONProjectFactory( dbgap_application=self.dbgap_application, studies=[study_json], @@ -2816,9 +2464,7 @@ def test_snapshot_not_created_if_dar_error(self): current_DAR_status="approved", DAC_abbrev="FOOBAR", ) - study_json = factories.dbGaPJSONStudyFactory( - study_accession=phs, requests=[request_json_1, request_json_2] - ) + study_json = factories.dbGaPJSONStudyFactory(study_accession=phs, requests=[request_json_1, request_json_2]) project_json = factories.dbGaPJSONProjectFactory( dbgap_application=self.dbgap_application, studies=[study_json], @@ -2829,9 +2475,7 @@ def test_snapshot_not_created_if_dar_error(self): constants.DBGAP_STUDY_URL, match=[responses.matchers.query_param_matcher({"study_id": phs})], status=302, - headers={ - "Location": constants.DBGAP_STUDY_URL + "?study_id=phs000421.v32.p18" - }, + headers={"Location": constants.DBGAP_STUDY_URL + "?study_id=phs000421.v32.p18"}, ) self.client.force_login(self.user) response = self.client.post( @@ -2864,9 +2508,7 @@ def test_existing_snapshot_is_most_recent_with_dar_errors(self): current_DAR_status="approved", DAC_abbrev="FOOBAR", ) - study_json = factories.dbGaPJSONStudyFactory( - study_accession=phs, requests=[request_json_1, request_json_2] - ) + study_json = factories.dbGaPJSONStudyFactory(study_accession=phs, requests=[request_json_1, request_json_2]) project_json = factories.dbGaPJSONProjectFactory( dbgap_application=self.dbgap_application, studies=[study_json], @@ -2877,9 +2519,7 @@ def test_existing_snapshot_is_most_recent_with_dar_errors(self): constants.DBGAP_STUDY_URL, match=[responses.matchers.query_param_matcher({"study_id": phs})], status=302, - headers={ - "Location": constants.DBGAP_STUDY_URL + "?study_id=phs000421.v32.p18" - }, + headers={"Location": constants.DBGAP_STUDY_URL + "?study_id=phs000421.v32.p18"}, ) # Create an existing snapshot. existing_snapshot = factories.dbGaPDataAccessSnapshotFactory.create( @@ -2914,14 +2554,10 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) def tearDown(self): @@ -2956,9 +2592,7 @@ def test_status_code_with_user_permission_edit(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url()) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -2966,13 +2600,9 @@ def test_access_without_user_permission(self): def test_access_without_user_permission_view(self): """Raises permission denied if user has no permissions.""" - user_view_perm = User.objects.create_user( - username="test-none", password="test-none" - ) + user_view_perm = User.objects.create_user(username="test-none", password="test-none") user_view_perm.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user_view_perm @@ -2989,9 +2619,7 @@ def test_form_class(self): """Form is the expected class.""" self.client.force_login(self.user) response = self.client.get(self.get_url()) - self.assertIsInstance( - response.context_data["form"], forms.dbGaPDataAccessSnapshotMultipleForm - ) + self.assertIsInstance(response.context_data["form"], forms.dbGaPDataAccessSnapshotMultipleForm) def test_context_dbgap_dar_json_url(self): """Response context includes dbgap_dar_json_url.""" @@ -3001,23 +2629,17 @@ def test_context_dbgap_dar_json_url(self): def test_updates_one_application(self): dbgap_application = factories.dbGaPApplicationFactory.create() - project_json = factories.dbGaPJSONProjectFactory( - dbgap_application=dbgap_application - ) + project_json = factories.dbGaPJSONProjectFactory(dbgap_application=dbgap_application) phs = project_json["studies"][0]["study_accession"] self.dbgap_response_mock.add( responses.GET, constants.DBGAP_STUDY_URL, match=[responses.matchers.query_param_matcher({"study_id": phs})], status=302, - headers={ - "Location": constants.DBGAP_STUDY_URL + "?study_id=" + phs + ".v1.p1" - }, + headers={"Location": constants.DBGAP_STUDY_URL + "?study_id=" + phs + ".v1.p1"}, ) self.client.force_login(self.user) - response = self.client.post( - self.get_url(), {"dbgap_dar_data": json.dumps([project_json])} - ) + response = self.client.post(self.get_url(), {"dbgap_dar_data": json.dumps([project_json])}) self.assertEqual(response.status_code, 302) dbgap_application.refresh_from_db() self.assertEqual(dbgap_application.dbgapdataaccesssnapshot_set.count(), 1) @@ -3027,33 +2649,25 @@ def test_updates_one_application(self): def test_updates_two_applications(self): # First application and associated JSON. dbgap_application_1 = factories.dbGaPApplicationFactory.create() - project_json_1 = factories.dbGaPJSONProjectFactory( - dbgap_application=dbgap_application_1 - ) + project_json_1 = factories.dbGaPJSONProjectFactory(dbgap_application=dbgap_application_1) phs_1 = project_json_1["studies"][0]["study_accession"] self.dbgap_response_mock.add( responses.GET, constants.DBGAP_STUDY_URL, match=[responses.matchers.query_param_matcher({"study_id": phs_1})], status=302, - headers={ - "Location": constants.DBGAP_STUDY_URL + "?study_id=" + phs_1 + ".v1.p1" - }, + headers={"Location": constants.DBGAP_STUDY_URL + "?study_id=" + phs_1 + ".v1.p1"}, ) # Second application and associated JSON. dbgap_application_2 = factories.dbGaPApplicationFactory.create() - project_json_2 = factories.dbGaPJSONProjectFactory( - dbgap_application=dbgap_application_2 - ) + project_json_2 = factories.dbGaPJSONProjectFactory(dbgap_application=dbgap_application_2) phs_2 = project_json_2["studies"][0]["study_accession"] self.dbgap_response_mock.add( responses.GET, constants.DBGAP_STUDY_URL, match=[responses.matchers.query_param_matcher({"study_id": phs_2})], status=302, - headers={ - "Location": constants.DBGAP_STUDY_URL + "?study_id=" + phs_2 + ".v2.p2" - }, + headers={"Location": constants.DBGAP_STUDY_URL + "?study_id=" + phs_2 + ".v2.p2"}, ) self.client.force_login(self.user) response = self.client.post( @@ -3075,45 +2689,33 @@ def test_updates_two_applications(self): def test_redirect_url(self): """Redirects to successful url.""" dbgap_application = factories.dbGaPApplicationFactory.create() - project_json = factories.dbGaPJSONProjectFactory( - dbgap_application=dbgap_application - ) + project_json = factories.dbGaPJSONProjectFactory(dbgap_application=dbgap_application) phs = project_json["studies"][0]["study_accession"] self.dbgap_response_mock.add( responses.GET, constants.DBGAP_STUDY_URL, match=[responses.matchers.query_param_matcher({"study_id": phs})], status=302, - headers={ - "Location": constants.DBGAP_STUDY_URL + "?study_id=" + phs + ".v1.p1" - }, + headers={"Location": constants.DBGAP_STUDY_URL + "?study_id=" + phs + ".v1.p1"}, ) self.client.force_login(self.user) - response = self.client.post( - self.get_url(), {"dbgap_dar_data": json.dumps([project_json])} - ) + response = self.client.post(self.get_url(), {"dbgap_dar_data": json.dumps([project_json])}) self.assertRedirects(response, reverse("dbgap:dbgap_applications:list")) def test_success_message(self): """Redirects to successful url.""" dbgap_application = factories.dbGaPApplicationFactory.create() - project_json = factories.dbGaPJSONProjectFactory( - dbgap_application=dbgap_application - ) + project_json = factories.dbGaPJSONProjectFactory(dbgap_application=dbgap_application) phs = project_json["studies"][0]["study_accession"] self.dbgap_response_mock.add( responses.GET, constants.DBGAP_STUDY_URL, match=[responses.matchers.query_param_matcher({"study_id": phs})], status=302, - headers={ - "Location": constants.DBGAP_STUDY_URL + "?study_id=" + phs + ".v1.p1" - }, + headers={"Location": constants.DBGAP_STUDY_URL + "?study_id=" + phs + ".v1.p1"}, ) self.client.force_login(self.user) - response = self.client.post( - self.get_url(), {"dbgap_dar_data": json.dumps([project_json])}, follow=True - ) + response = self.client.post(self.get_url(), {"dbgap_dar_data": json.dumps([project_json])}, follow=True) self.assertIn("messages", response.context) messages = list(response.context["messages"]) self.assertEqual(len(messages), 1) @@ -3142,9 +2744,7 @@ def test_dbgap_application_does_not_exist(self): """Shows an error when the dbGaP application does not exist.""" project_json = factories.dbGaPJSONProjectFactory() self.client.force_login(self.user) - response = self.client.post( - self.get_url(), {"dbgap_dar_data": json.dumps([project_json])} - ) + response = self.client.post(self.get_url(), {"dbgap_dar_data": json.dumps([project_json])}) self.assertEqual(response.status_code, 200) # Form has errors in the correct field. self.assertIn("form", response.context_data) @@ -3161,9 +2761,7 @@ def test_dbgap_application_does_not_exist(self): def test_second_dbgap_application_does_not_exist(self): """Shows an error when one dbGaP application does not exist.""" dbgap_application_1 = factories.dbGaPApplicationFactory.create() - project_json_1 = factories.dbGaPJSONProjectFactory( - dbgap_application=dbgap_application_1 - ) + project_json_1 = factories.dbGaPJSONProjectFactory(dbgap_application=dbgap_application_1) project_json_2 = factories.dbGaPJSONProjectFactory() self.client.force_login(self.user) response = self.client.post( @@ -3186,9 +2784,7 @@ def test_second_dbgap_application_does_not_exist(self): def test_updates_existing_snapshot_is_most_recent(self): """Updates the is_most_recent for older snapshots.""" dbgap_application = factories.dbGaPApplicationFactory.create() - project_json = factories.dbGaPJSONProjectFactory( - dbgap_application=dbgap_application - ) + project_json = factories.dbGaPJSONProjectFactory(dbgap_application=dbgap_application) phs = project_json["studies"][0]["study_accession"] existing_snapshot = factories.dbGaPDataAccessSnapshotFactory.create( dbgap_application=dbgap_application, @@ -3201,15 +2797,11 @@ def test_updates_existing_snapshot_is_most_recent(self): constants.DBGAP_STUDY_URL, match=[responses.matchers.query_param_matcher({"study_id": phs})], status=302, - headers={ - "Location": constants.DBGAP_STUDY_URL + "?study_id=" + phs + ".v1.p1" - }, + headers={"Location": constants.DBGAP_STUDY_URL + "?study_id=" + phs + ".v1.p1"}, ) # Now add a new snapshot. self.client.force_login(self.user) - response = self.client.post( - self.get_url(), {"dbgap_dar_data": json.dumps([project_json])} - ) + response = self.client.post(self.get_url(), {"dbgap_dar_data": json.dumps([project_json])}) self.client.force_login(self.user) self.assertEqual(response.status_code, 302) self.assertEqual(models.dbGaPDataAccessSnapshot.objects.count(), 2) @@ -3224,9 +2816,7 @@ def test_updates_existing_snapshot_is_most_recent(self): def test_can_add_a_second_snapshot_with_dars(self): """Can add a second snapshot and new DARs.""" dbgap_application = factories.dbGaPApplicationFactory.create() - project_json = factories.dbGaPJSONProjectFactory( - dbgap_application=dbgap_application - ) + project_json = factories.dbGaPJSONProjectFactory(dbgap_application=dbgap_application) phs = project_json["studies"][0]["study_accession"] factories.dbGaPDataAccessSnapshotFactory.create( dbgap_application=dbgap_application, @@ -3239,15 +2829,11 @@ def test_can_add_a_second_snapshot_with_dars(self): constants.DBGAP_STUDY_URL, match=[responses.matchers.query_param_matcher({"study_id": phs})], status=302, - headers={ - "Location": constants.DBGAP_STUDY_URL + "?study_id=" + phs + ".v1.p1" - }, + headers={"Location": constants.DBGAP_STUDY_URL + "?study_id=" + phs + ".v1.p1"}, ) # Now add a new snapshot. self.client.force_login(self.user) - response = self.client.post( - self.get_url(), {"dbgap_dar_data": json.dumps([project_json])} - ) + response = self.client.post(self.get_url(), {"dbgap_dar_data": json.dumps([project_json])}) self.assertEqual(response.status_code, 302) self.assertEqual(models.dbGaPDataAccessSnapshot.objects.count(), 2) new_snapshot = models.dbGaPDataAccessSnapshot.objects.latest("pk") @@ -3277,9 +2863,7 @@ def test_post_invalid_json(self): def test_snapshot_not_created_if_http404(self): """The dbGaPDataAccessSnapshot is not created if DARs cannot be created due to a HTTP 404 response.""" dbgap_application = factories.dbGaPApplicationFactory.create() - project_json = factories.dbGaPJSONProjectFactory( - dbgap_application=dbgap_application - ) + project_json = factories.dbGaPJSONProjectFactory(dbgap_application=dbgap_application) phs = project_json["studies"][0]["study_accession"] # Add responses with the study version and participant_set. self.dbgap_response_mock.add( @@ -3314,9 +2898,7 @@ def test_snapshot_not_created_if_http404(self): def test_existing_snapshot_not_updated_http404(self): """The dbGaPDataAccessSnapshot is not created if there is an HTTP 404 error.""" dbgap_application = factories.dbGaPApplicationFactory.create() - project_json = factories.dbGaPJSONProjectFactory( - dbgap_application=dbgap_application - ) + project_json = factories.dbGaPJSONProjectFactory(dbgap_application=dbgap_application) phs = project_json["studies"][0]["study_accession"] existing_snapshot = factories.dbGaPDataAccessSnapshotFactory.create( dbgap_application=dbgap_application, @@ -3359,12 +2941,8 @@ def test_snapshot_not_created_if_dar_validation_error(self): dbgap_application = factories.dbGaPApplicationFactory.create() request_json_1 = factories.dbGaPJSONRequestFactory(DAR=12345) request_json_2 = factories.dbGaPJSONRequestFactory(DAR=12345) - study_json = factories.dbGaPJSONStudyFactory( - requests=[request_json_1, request_json_2] - ) - project_json = factories.dbGaPJSONProjectFactory( - dbgap_application=dbgap_application, studies=[study_json] - ) + study_json = factories.dbGaPJSONStudyFactory(requests=[request_json_1, request_json_2]) + project_json = factories.dbGaPJSONProjectFactory(dbgap_application=dbgap_application, studies=[study_json]) phs = project_json["studies"][0]["study_accession"] # Add responses with the study version and participant_set. self.dbgap_response_mock.add( @@ -3372,9 +2950,7 @@ def test_snapshot_not_created_if_dar_validation_error(self): constants.DBGAP_STUDY_URL, match=[responses.matchers.query_param_matcher({"study_id": phs})], status=302, - headers={ - "Location": constants.DBGAP_STUDY_URL + "?study_id=" + phs + ".v32.p18" - }, + headers={"Location": constants.DBGAP_STUDY_URL + "?study_id=" + phs + ".v32.p18"}, ) self.client.force_login(self.user) response = self.client.post( @@ -3404,12 +2980,8 @@ def test_existing_snapshot_is_most_recent_with_dar_validation_error(self): dbgap_application = factories.dbGaPApplicationFactory.create() request_json_1 = factories.dbGaPJSONRequestFactory(DAR=12345) request_json_2 = factories.dbGaPJSONRequestFactory(DAR=12345) - study_json = factories.dbGaPJSONStudyFactory( - requests=[request_json_1, request_json_2] - ) - project_json = factories.dbGaPJSONProjectFactory( - dbgap_application=dbgap_application, studies=[study_json] - ) + study_json = factories.dbGaPJSONStudyFactory(requests=[request_json_1, request_json_2]) + project_json = factories.dbGaPJSONProjectFactory(dbgap_application=dbgap_application, studies=[study_json]) phs = project_json["studies"][0]["study_accession"] existing_snapshot = factories.dbGaPDataAccessSnapshotFactory.create( @@ -3423,9 +2995,7 @@ def test_existing_snapshot_is_most_recent_with_dar_validation_error(self): constants.DBGAP_STUDY_URL, match=[responses.matchers.query_param_matcher({"study_id": phs})], status=302, - headers={ - "Location": constants.DBGAP_STUDY_URL + "?study_id=" + phs + ".v32.p18" - }, + headers={"Location": constants.DBGAP_STUDY_URL + "?study_id=" + phs + ".v32.p18"}, ) self.client.force_login(self.user) response = self.client.post( @@ -3461,14 +3031,10 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.application = factories.dbGaPApplicationFactory.create() - self.snapshot = factories.dbGaPDataAccessSnapshotFactory.create( - dbgap_application=self.application - ) + self.snapshot = factories.dbGaPDataAccessSnapshotFactory.create(dbgap_application=self.application) def tearDown(self): super().tearDown() @@ -3489,9 +3055,7 @@ def get_view(self): def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." # Need a client for redirects. - response = self.client.get( - self.get_url(self.application.dbgap_project_id, self.snapshot.pk) - ) + response = self.client.get(self.get_url(self.application.dbgap_project_id, self.snapshot.pk)) self.assertRedirects( response, resolve_url(settings.LOGIN_URL) @@ -3501,9 +3065,7 @@ def test_view_redirect_not_logged_in(self): def test_status_code_with_user_permission_view(self): """Returns successful response code if the user has view permission.""" - request = self.factory.get( - self.get_url(self.application.dbgap_project_id, self.snapshot.pk) - ) + request = self.factory.get(self.get_url(self.application.dbgap_project_id, self.snapshot.pk)) request.user = self.user response = self.get_view()( request, @@ -3514,12 +3076,8 @@ def test_status_code_with_user_permission_view(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) - request = self.factory.get( - self.get_url(self.application.dbgap_project_id, self.snapshot.pk) - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") + request = self.factory.get(self.get_url(self.application.dbgap_project_id, self.snapshot.pk)) request.user = user_no_perms with self.assertRaises(PermissionDenied): self.get_view()( @@ -3530,9 +3088,7 @@ def test_access_without_user_permission(self): def test_invalid_dbgap_application_pk(self): """Raises a 404 error with an invalid object dbgap_application_pk.""" - request = self.factory.get( - self.get_url(self.application.dbgap_project_id + 1, self.snapshot.pk) - ) + request = self.factory.get(self.get_url(self.application.dbgap_project_id + 1, self.snapshot.pk)) request.user = self.user with self.assertRaises(Http404): self.get_view()( @@ -3543,9 +3099,7 @@ def test_invalid_dbgap_application_pk(self): def test_invalid_dbgap_data_access_snapshot_pk(self): """Raises a 404 error with an invalid object dbgap_data_access_snapshot_pk.""" - request = self.factory.get( - self.get_url(self.application.dbgap_project_id, self.snapshot.pk + 1) - ) + request = self.factory.get(self.get_url(self.application.dbgap_project_id, self.snapshot.pk + 1)) request.user = self.user with self.assertRaises(Http404): self.get_view()( @@ -3557,9 +3111,7 @@ def test_invalid_dbgap_data_access_snapshot_pk(self): def test_mismatch_application_snapshot(self): """Raises a 404 error when dbgap application and snapshot pk don't match.""" other_snapshot = factories.dbGaPDataAccessSnapshotFactory.create() - request = self.factory.get( - self.get_url(self.application.dbgap_project_id, other_snapshot.pk) - ) + request = self.factory.get(self.get_url(self.application.dbgap_project_id, other_snapshot.pk)) request.user = self.user with self.assertRaises(Http404): self.get_view()( @@ -3571,9 +3123,7 @@ def test_mismatch_application_snapshot(self): def test_context_dar_table(self): """The data_access_request_table exists in the context.""" self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.application.dbgap_project_id, self.snapshot.pk) - ) + response = self.client.get(self.get_url(self.application.dbgap_project_id, self.snapshot.pk)) self.assertIn("data_access_request_table", response.context_data) self.assertIsInstance( response.context_data["data_access_request_table"], @@ -3583,75 +3133,45 @@ def test_context_dar_table(self): def test_context_dar_table_none(self): """The data_access_request_table works with one DAR.""" self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.application.dbgap_project_id, self.snapshot.pk) - ) + response = self.client.get(self.get_url(self.application.dbgap_project_id, self.snapshot.pk)) self.assertIn("data_access_request_table", response.context_data) - self.assertEqual( - len(response.context_data["data_access_request_table"].rows), 0 - ) + self.assertEqual(len(response.context_data["data_access_request_table"].rows), 0) def test_context_dar_table_one(self): """The data_access_request_table works with one DAR.""" - dar = factories.dbGaPDataAccessRequestFactory.create( - dbgap_data_access_snapshot=self.snapshot - ) + dar = factories.dbGaPDataAccessRequestFactory.create(dbgap_data_access_snapshot=self.snapshot) self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.application.dbgap_project_id, self.snapshot.pk) - ) + response = self.client.get(self.get_url(self.application.dbgap_project_id, self.snapshot.pk)) self.assertIn("data_access_request_table", response.context_data) - self.assertEqual( - len(response.context_data["data_access_request_table"].rows), 1 - ) + self.assertEqual(len(response.context_data["data_access_request_table"].rows), 1) self.assertIn(dar, response.context_data["data_access_request_table"].data) def test_context_dar_table_two(self): """The data_access_request_table works with one DAR.""" - dars = factories.dbGaPDataAccessRequestFactory.create_batch( - 2, dbgap_data_access_snapshot=self.snapshot - ) + dars = factories.dbGaPDataAccessRequestFactory.create_batch(2, dbgap_data_access_snapshot=self.snapshot) self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.application.dbgap_project_id, self.snapshot.pk) - ) + response = self.client.get(self.get_url(self.application.dbgap_project_id, self.snapshot.pk)) self.assertIn("data_access_request_table", response.context_data) - self.assertEqual( - len(response.context_data["data_access_request_table"].rows), 2 - ) + self.assertEqual(len(response.context_data["data_access_request_table"].rows), 2) self.assertIn(dars[0], response.context_data["data_access_request_table"].data) self.assertIn(dars[1], response.context_data["data_access_request_table"].data) def test_context_dar_table_only_shows_dars_for_this_snapshot(self): """The data_access_request_table only shows DARs associated with this snapshot.""" - dar = factories.dbGaPDataAccessRequestFactory.create( - dbgap_data_access_snapshot=self.snapshot - ) - other_snapshot = factories.dbGaPDataAccessSnapshotFactory.create( - dbgap_application=self.application - ) - other_dar = factories.dbGaPDataAccessRequestFactory.create( - dbgap_data_access_snapshot=other_snapshot - ) + dar = factories.dbGaPDataAccessRequestFactory.create(dbgap_data_access_snapshot=self.snapshot) + other_snapshot = factories.dbGaPDataAccessSnapshotFactory.create(dbgap_application=self.application) + other_dar = factories.dbGaPDataAccessRequestFactory.create(dbgap_data_access_snapshot=other_snapshot) self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.application.dbgap_project_id, self.snapshot.pk) - ) + response = self.client.get(self.get_url(self.application.dbgap_project_id, self.snapshot.pk)) self.assertIn("data_access_request_table", response.context_data) - self.assertEqual( - len(response.context_data["data_access_request_table"].rows), 1 - ) + self.assertEqual(len(response.context_data["data_access_request_table"].rows), 1) self.assertIn(dar, response.context_data["data_access_request_table"].data) - self.assertNotIn( - other_dar, response.context_data["data_access_request_table"].data - ) + self.assertNotIn(other_dar, response.context_data["data_access_request_table"].data) def test_context_summary_table(self): """The data_access_request_table exists in the context.""" self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.application.dbgap_project_id, self.snapshot.pk) - ) + response = self.client.get(self.get_url(self.application.dbgap_project_id, self.snapshot.pk)) self.assertIn("summary_table", response.context_data) self.assertIsInstance( response.context_data["summary_table"], @@ -3661,9 +3181,7 @@ def test_context_summary_table(self): def test_context_summary_table_none(self): """The data_access_request_table works with no DARs.""" self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.application.dbgap_project_id, self.snapshot.pk) - ) + response = self.client.get(self.get_url(self.application.dbgap_project_id, self.snapshot.pk)) self.assertIn("summary_table", response.context_data) self.assertEqual(len(response.context_data["summary_table"].rows), 0) @@ -3697,9 +3215,7 @@ def test_context_summary_table_contents(self): dbgap_current_status=models.dbGaPDataAccessRequest.NEW, ) self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.application.dbgap_project_id, self.snapshot.pk) - ) + response = self.client.get(self.get_url(self.application.dbgap_project_id, self.snapshot.pk)) self.assertIn("summary_table", response.context_data) table = response.context_data["summary_table"] @@ -3733,18 +3249,14 @@ def test_context_summary_table_contents(self): def test_context_summary_table_only_shows_dars_for_this_snapshot(self): """The data_access_request_table only shows DARs associated with this snapshot.""" - other_snapshot = factories.dbGaPDataAccessSnapshotFactory.create( - dbgap_application=self.application - ) + other_snapshot = factories.dbGaPDataAccessSnapshotFactory.create(dbgap_application=self.application) factories.dbGaPDataAccessRequestFactory.create( dbgap_data_access_snapshot=other_snapshot, dbgap_current_status=models.dbGaPDataAccessRequest.APPROVED, dbgap_dac="FOO", ) self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.application.dbgap_project_id, self.snapshot.pk) - ) + response = self.client.get(self.get_url(self.application.dbgap_project_id, self.snapshot.pk)) self.assertIn("summary_table", response.context_data) table = response.context_data["summary_table"] self.assertEqual(len(table.rows), 0) @@ -3752,12 +3264,8 @@ def test_context_summary_table_only_shows_dars_for_this_snapshot(self): def test_no_alert_for_most_recent_snapshot(self): """No alert is shown when this is the most recent snapshot for an application.""" self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.application.dbgap_project_id, self.snapshot.pk) - ) - self.assertNotContains( - response, "not the most recent snapshot", status_code=200 - ) + response = self.client.get(self.get_url(self.application.dbgap_project_id, self.snapshot.pk)) + self.assertNotContains(response, "not the most recent snapshot", status_code=200) def test_alert_when_not_most_recent_snapshot(self): """An alert is shown when this is not the most recent snapshot for an application.""" @@ -3767,9 +3275,7 @@ def test_alert_when_not_most_recent_snapshot(self): is_most_recent=False, ) self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.application.dbgap_project_id, old_snapshot.pk) - ) + response = self.client.get(self.get_url(self.application.dbgap_project_id, old_snapshot.pk)) self.assertContains(response, "not the most recent snapshot", status_code=200) @@ -3780,9 +3286,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -3811,9 +3315,7 @@ def test_status_code_with_user_permission(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url()) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -3824,9 +3326,7 @@ def test_table_class(self): self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertIn("table", response.context_data) - self.assertIsInstance( - response.context_data["table"], tables.dbGaPDataAccessRequestTable - ) + self.assertIsInstance(response.context_data["table"], tables.dbGaPDataAccessRequestTable) def test_one_dar(self): """Table displays one dar.""" @@ -3845,9 +3345,7 @@ def test_two_dars(self): self.assertIn(dar_2, response.context_data["table"].data) def test_only_current_dars_shown(self): - dar = factories.dbGaPDataAccessRequestFactory.create( - dbgap_data_access_snapshot__is_most_recent=False - ) + dar = factories.dbGaPDataAccessRequestFactory.create(dbgap_data_access_snapshot__is_most_recent=False) self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertNotIn(dar, response.context_data["table"].data) @@ -3863,9 +3361,7 @@ def test_export(self): self.assertIn("Content-Type", response) self.assertEqual(response["Content-Type"], "text/tsv; charset=utf-8") self.assertIn("Content-Disposition", response) - self.assertEqual( - response["Content-Disposition"], 'attachment; filename="dars_table.tsv"' - ) + self.assertEqual(response["Content-Disposition"], 'attachment; filename="dars_table.tsv"') class dbGaPDataAccessRequestHistoryTest(TestCase): @@ -3875,9 +3371,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -3906,9 +3400,7 @@ def test_status_code_with_user_permission(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url(1)) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -3927,9 +3419,7 @@ def test_table_class(self): self.client.force_login(self.user) response = self.client.get(self.get_url(instance.dbgap_dar_id)) self.assertIn("table", response.context_data) - self.assertIsInstance( - response.context_data["table"], tables.dbGaPDataAccessRequestHistoryTable - ) + self.assertIsInstance(response.context_data["table"], tables.dbGaPDataAccessRequestHistoryTable) def test_one_dars(self): """Table displays two dars.""" @@ -3965,16 +3455,12 @@ def test_table_ordering(self): created=timezone.now() - timedelta(weeks=5), is_most_recent=False, ) - dar_1 = factories.dbGaPDataAccessRequestFactory.create( - dbgap_dar_id=1, dbgap_data_access_snapshot=old_snapshot - ) + dar_1 = factories.dbGaPDataAccessRequestFactory.create(dbgap_dar_id=1, dbgap_data_access_snapshot=old_snapshot) new_snapshot = factories.dbGaPDataAccessSnapshotFactory.create( created=timezone.now() - timedelta(weeks=1), is_most_recent=True, ) - dar_2 = factories.dbGaPDataAccessRequestFactory.create( - dbgap_dar_id=1, dbgap_data_access_snapshot=new_snapshot - ) + dar_2 = factories.dbGaPDataAccessRequestFactory.create(dbgap_dar_id=1, dbgap_data_access_snapshot=new_snapshot) self.client.force_login(self.user) response = self.client.get(self.get_url(1)) self.assertEqual(len(response.context_data["table"].rows), 2) @@ -3991,14 +3477,10 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.application = factories.dbGaPApplicationFactory.create() - self.snapshot = factories.dbGaPDataAccessSnapshotFactory.create( - dbgap_application=self.application - ) + self.snapshot = factories.dbGaPDataAccessSnapshotFactory.create(dbgap_application=self.application) def get_url(self, *args): """Get the url for the view being tested.""" @@ -4017,25 +3499,19 @@ def test_view_redirect_not_logged_in(self): response = self.client.get(self.get_url(self.application.dbgap_project_id)) self.assertRedirects( response, - resolve_url(settings.LOGIN_URL) - + "?next=" - + self.get_url(self.application.dbgap_project_id), + resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(self.application.dbgap_project_id), ) def test_status_code_with_user_permission_view(self): """Returns successful response code if the user has view permission.""" request = self.factory.get(self.get_url(self.application.dbgap_project_id)) request.user = self.user - response = self.get_view()( - request, dbgap_project_id=self.application.dbgap_project_id - ) + response = self.get_view()(request, dbgap_project_id=self.application.dbgap_project_id) self.assertEqual(response.status_code, 200) def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url(self.application.dbgap_project_id)) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -4068,16 +3544,12 @@ def test_context_data_access_audit_does_not_include_other_applications(self): response = self.client.get(self.get_url(self.application.dbgap_project_id)) data_access_audit = response.context_data["data_access_audit"] self.assertEqual(data_access_audit.dbgap_application_queryset.count(), 1) - self.assertNotIn( - other_application, data_access_audit.dbgap_application_queryset - ) + self.assertNotIn(other_application, data_access_audit.dbgap_application_queryset) def test_context_verified_table_access(self): """verified_table shows a record when audit has verified access.""" # Add a verified workspace. - workspace = factories.dbGaPWorkspaceFactory.create( - dbgap_study_accession__dbgap_phs=1 - ) + workspace = factories.dbGaPWorkspaceFactory.create(dbgap_study_accession__dbgap_phs=1) dar = factories.dbGaPDataAccessRequestForWorkspaceFactory.create( dbgap_data_access_snapshot=self.snapshot, dbgap_workspace=workspace ) @@ -4126,9 +3598,7 @@ def test_context_verified_table_no_access(self): def test_context_needs_action_table_grant(self): """needs_action_table shows a record when audit finds that access needs to be granted.""" - workspace = factories.dbGaPWorkspaceFactory.create( - created=timezone.now() - timedelta(weeks=4) - ) + workspace = factories.dbGaPWorkspaceFactory.create(created=timezone.now() - timedelta(weeks=4)) dar = factories.dbGaPDataAccessRequestForWorkspaceFactory.create( dbgap_data_access_snapshot=self.snapshot, dbgap_workspace=workspace ) @@ -4262,9 +3732,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.dbgap_workspace = factories.dbGaPWorkspaceFactory.create() @@ -4306,9 +3774,7 @@ def test_status_code_with_user_permission_view(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get( self.get_url( self.dbgap_workspace.workspace.billing_project.name, @@ -4325,9 +3791,7 @@ def test_access_without_user_permission(self): def test_invalid_billing_project_name(self): """Raises a 404 error with an invalid object dbgap_application_pk.""" - request = self.factory.get( - self.get_url("foo", self.dbgap_workspace.workspace.name) - ) + request = self.factory.get(self.get_url("foo", self.dbgap_workspace.workspace.name)) request.user = self.user with self.assertRaises(Http404): self.get_view()( @@ -4338,9 +3802,7 @@ def test_invalid_billing_project_name(self): def test_invalid_workspace_name(self): """Raises a 404 error with an invalid object dbgap_application_pk.""" - request = self.factory.get( - self.get_url(self.dbgap_workspace.workspace.name, "foo") - ) + request = self.factory.get(self.get_url(self.dbgap_workspace.workspace.name, "foo")) request.user = self.user with self.assertRaises(Http404): self.get_view()( @@ -4385,9 +3847,7 @@ def test_context_data_access_audit_does_not_include_other_applications(self): def test_context_verified_table_access(self): """verified_table shows a record when audit has verified access.""" # Add a verified workspace. - dar = factories.dbGaPDataAccessRequestForWorkspaceFactory.create( - dbgap_workspace=self.dbgap_workspace - ) + dar = factories.dbGaPDataAccessRequestForWorkspaceFactory.create(dbgap_workspace=self.dbgap_workspace) GroupGroupMembershipFactory.create( parent_group=self.dbgap_workspace.workspace.authorization_domains.first(), child_group=dar.dbgap_data_access_snapshot.dbgap_application.anvil_access_group, @@ -4407,9 +3867,7 @@ def test_context_verified_table_access(self): audit.dbGaPAccessAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual( - table.rows[0].get_cell_value("workspace"), self.dbgap_workspace - ) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.dbgap_workspace) self.assertEqual(table.rows[0].get_cell_value("data_access_request"), dar) self.assertEqual( table.rows[0].get_cell_value("note"), @@ -4435,9 +3893,7 @@ def test_context_verified_table_no_snapshot(self): audit.dbGaPAccessAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual( - table.rows[0].get_cell_value("workspace"), self.dbgap_workspace - ) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.dbgap_workspace) self.assertIsNone(table.rows[0].get_cell_value("data_access_request")) self.assertEqual( table.rows[0].get_cell_value("note"), @@ -4463,9 +3919,7 @@ def test_context_verified_table_no_dar(self): audit.dbGaPAccessAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual( - table.rows[0].get_cell_value("workspace"), self.dbgap_workspace - ) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.dbgap_workspace) self.assertIsNone(table.rows[0].get_cell_value("data_access_request")) self.assertEqual( table.rows[0].get_cell_value("note"), @@ -4495,9 +3949,7 @@ def test_context_verified_table_other_dar(self): audit.dbGaPAccessAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual( - table.rows[0].get_cell_value("workspace"), self.dbgap_workspace - ) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.dbgap_workspace) self.assertIsNone(table.rows[0].get_cell_value("data_access_request")) self.assertEqual( table.rows[0].get_cell_value("note"), @@ -4526,9 +3978,7 @@ def test_context_verified_table_dar_not_approved(self): audit.dbGaPAccessAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual( - table.rows[0].get_cell_value("workspace"), self.dbgap_workspace - ) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.dbgap_workspace) self.assertEqual(table.rows[0].get_cell_value("data_access_request"), dar) self.assertEqual( table.rows[0].get_cell_value("note"), @@ -4538,9 +3988,7 @@ def test_context_verified_table_dar_not_approved(self): def test_context_needs_action_table_grant(self): """needs_action_table shows a record when audit finds that access needs to be granted.""" - dar = factories.dbGaPDataAccessRequestForWorkspaceFactory.create( - dbgap_workspace=self.dbgap_workspace - ) + dar = factories.dbGaPDataAccessRequestForWorkspaceFactory.create(dbgap_workspace=self.dbgap_workspace) # Check the table in the context. self.client.force_login(self.user) response = self.client.get( @@ -4556,9 +4004,7 @@ def test_context_needs_action_table_grant(self): audit.dbGaPAccessAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual( - table.rows[0].get_cell_value("workspace"), self.dbgap_workspace - ) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.dbgap_workspace) self.assertEqual(table.rows[0].get_cell_value("data_access_request"), dar) self.assertEqual( table.rows[0].get_cell_value("note"), @@ -4603,9 +4049,7 @@ def test_context_needs_action_table_remove(self): audit.dbGaPAccessAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual( - table.rows[0].get_cell_value("workspace"), self.dbgap_workspace - ) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.dbgap_workspace) self.assertEqual(table.rows[0].get_cell_value("data_access_request"), dar) self.assertEqual( table.rows[0].get_cell_value("note"), @@ -4640,9 +4084,7 @@ def test_context_error_table_has_access(self): audit.dbGaPAccessAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual( - table.rows[0].get_cell_value("workspace"), self.dbgap_workspace - ) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.dbgap_workspace) self.assertEqual(table.rows[0].get_cell_value("data_access_request"), dar) self.assertEqual( table.rows[0].get_cell_value("note"), @@ -4673,9 +4115,7 @@ def test_context_errors_table_no_snapshot_has_access(self): audit.dbGaPAccessAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual( - table.rows[0].get_cell_value("workspace"), self.dbgap_workspace - ) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.dbgap_workspace) self.assertIsNone(table.rows[0].get_cell_value("data_access_request")) self.assertEqual( table.rows[0].get_cell_value("note"), @@ -4706,9 +4146,7 @@ def test_context_errors_table_no_dar_has_access(self): audit.dbGaPAccessAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual( - table.rows[0].get_cell_value("workspace"), self.dbgap_workspace - ) + self.assertEqual(table.rows[0].get_cell_value("workspace"), self.dbgap_workspace) self.assertIsNone(table.rows[0].get_cell_value("data_access_request")) self.assertEqual( table.rows[0].get_cell_value("note"), @@ -4726,9 +4164,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -4760,11 +4196,7 @@ def test_status_code_with_user_permission_staff_view(self): def test_status_code_with_user_permission_view(self): """Returns successful response code if the user has view permission.""" user = User.objects.create_user(username="test-none", password="test-none") - user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) - ) + user.user_permissions.add(Permission.objects.get(codename=AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME)) request = self.factory.get(self.get_url()) request.user = user with self.assertRaises(PermissionDenied): @@ -4772,9 +4204,7 @@ def test_status_code_with_user_permission_view(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url()) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -4854,9 +4284,7 @@ def test_context_verified_table_access(self): """verified_table shows a record when audit has verified access.""" # Add a verified workspace. workspace = factories.dbGaPWorkspaceFactory.create() - dar = factories.dbGaPDataAccessRequestForWorkspaceFactory.create( - dbgap_workspace=workspace - ) + dar = factories.dbGaPDataAccessRequestForWorkspaceFactory.create(dbgap_workspace=workspace) GroupGroupMembershipFactory.create( parent_group=workspace.workspace.authorization_domains.first(), child_group=dar.dbgap_data_access_snapshot.dbgap_application.anvil_access_group, @@ -4893,9 +4321,7 @@ def test_context_verified_table_no_access(self): audit.dbGaPAccessAuditTable, ) self.assertEqual(len(table.rows), 1) - self.assertEqual( - table.rows[0].get_cell_value("application"), snapshot.dbgap_application - ) + self.assertEqual(table.rows[0].get_cell_value("application"), snapshot.dbgap_application) self.assertEqual(table.rows[0].get_cell_value("workspace"), workspace) self.assertIsNone(table.rows[0].get_cell_value("data_access_request")) self.assertEqual( @@ -4906,12 +4332,8 @@ def test_context_verified_table_no_access(self): def test_context_needs_action_table_grant(self): """needs_action_table shows a record when audit finds that access needs to be granted.""" - workspace = factories.dbGaPWorkspaceFactory.create( - created=timezone.now() - timedelta(weeks=4) - ) - dar = factories.dbGaPDataAccessRequestForWorkspaceFactory.create( - dbgap_workspace=workspace - ) + workspace = factories.dbGaPWorkspaceFactory.create(created=timezone.now() - timedelta(weeks=4)) + dar = factories.dbGaPDataAccessRequestForWorkspaceFactory.create(dbgap_workspace=workspace) # Check the table in the context. self.client.force_login(self.user) response = self.client.get(self.get_url()) @@ -5018,14 +4440,10 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -5066,9 +4484,7 @@ def test_status_code_with_user_permission_staff_view(self): """Returns 403 response code if the user has staff view permission.""" user_view = User.objects.create_user(username="test-view", password="test-view") user_view.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.client.force_login(self.user) request = self.factory.get(self.get_url(1, "foo", "bar")) @@ -5079,11 +4495,7 @@ def test_status_code_with_user_permission_staff_view(self): def test_status_code_with_user_permission_view(self): """Returns forbidden response code if the user has view permission.""" user = User.objects.create_user(username="test-none", password="test-none") - user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) - ) + user.user_permissions.add(Permission.objects.get(codename=AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME)) request = self.factory.get(self.get_url(1, "foo", "bar")) request.user = user with self.assertRaises(PermissionDenied): @@ -5091,9 +4503,7 @@ def test_status_code_with_user_permission_view(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url(1, "foo", "bar")) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -5129,11 +4539,7 @@ def test_billing_project_does_not_exist(self): def test_workspace_does_not_exist(self): dbgap_application = factories.dbGaPApplicationFactory.create() billing_project = BillingProjectFactory.create() - request = self.factory.get( - self.get_url( - dbgap_application.dbgap_project_id, billing_project.name, "foo" - ) - ) + request = self.factory.get(self.get_url(dbgap_application.dbgap_project_id, billing_project.name, "foo")) request.user = self.user with self.assertRaises(Http404): self.get_view()(request) @@ -5190,9 +4596,7 @@ def test_get_verified_access(self): """Get request with verified access.""" # Add a verified workspace. workspace = factories.dbGaPWorkspaceFactory.create() - dar = factories.dbGaPDataAccessRequestForWorkspaceFactory.create( - dbgap_workspace=workspace - ) + dar = factories.dbGaPDataAccessRequestForWorkspaceFactory.create(dbgap_workspace=workspace) GroupGroupMembershipFactory.create( parent_group=workspace.workspace.authorization_domains.first(), child_group=dar.dbgap_data_access_snapshot.dbgap_application.anvil_access_group, @@ -5246,12 +4650,8 @@ def test_get_verified_no_access(self): def test_get_grant_access(self): """needs_action_table shows a record when audit finds that access needs to be granted.""" - workspace = factories.dbGaPWorkspaceFactory.create( - created=timezone.now() - timedelta(weeks=4) - ) - dar = factories.dbGaPDataAccessRequestForWorkspaceFactory.create( - dbgap_workspace=workspace - ) + workspace = factories.dbGaPWorkspaceFactory.create(created=timezone.now() - timedelta(weeks=4)) + dar = factories.dbGaPDataAccessRequestForWorkspaceFactory.create(dbgap_workspace=workspace) self.client.force_login(self.user) response = self.client.get( self.get_url( @@ -5322,9 +4722,7 @@ def test_post_verified_access(self): """post with VerifiedAccess audit result.""" # Add a verified workspace. workspace = factories.dbGaPWorkspaceFactory.create() - dar = factories.dbGaPDataAccessRequestForWorkspaceFactory.create( - dbgap_workspace=workspace - ) + dar = factories.dbGaPDataAccessRequestForWorkspaceFactory.create(dbgap_workspace=workspace) date_created = timezone.now() - timedelta(weeks=3) with freeze_time(date_created): membership = GroupGroupMembershipFactory.create( @@ -5344,9 +4742,7 @@ def test_post_verified_access(self): # Membership hasn't changed. membership.refresh_from_db() self.assertEqual(membership.created, date_created) - self.assertEqual( - membership.parent_group, workspace.workspace.authorization_domains.first() - ) + self.assertEqual(membership.parent_group, workspace.workspace.authorization_domains.first()) self.assertEqual( membership.child_group, dar.dbgap_data_access_snapshot.dbgap_application.anvil_access_group, @@ -5377,13 +4773,8 @@ def test_post_grant_access(self): ) # Add API response # Note that the auth domain group is created automatically by the factory using the workspace name. - group_name = ( - dar.dbgap_data_access_snapshot.dbgap_application.anvil_access_group.name - ) - api_url = ( - self.api_client.sam_entry_point - + f"/api/groups/v1/auth_TEST_DBGAP/member/{group_name}@firecloud.org" - ) + group_name = dar.dbgap_data_access_snapshot.dbgap_application.anvil_access_group.name + api_url = self.api_client.sam_entry_point + f"/api/groups/v1/auth_TEST_DBGAP/member/{group_name}@firecloud.org" self.anvil_response_mock.add( responses.PUT, api_url, @@ -5414,13 +4805,8 @@ def test_post_grant_access_htmx(self): ) # Add API response # Note that the auth domain group is created automatically by the factory using the workspace name. - group_name = ( - dar.dbgap_data_access_snapshot.dbgap_application.anvil_access_group.name - ) - api_url = ( - self.api_client.sam_entry_point - + f"/api/groups/v1/auth_TEST_DBGAP/member/{group_name}@firecloud.org" - ) + group_name = dar.dbgap_data_access_snapshot.dbgap_application.anvil_access_group.name + api_url = self.api_client.sam_entry_point + f"/api/groups/v1/auth_TEST_DBGAP/member/{group_name}@firecloud.org" self.anvil_response_mock.add( responses.PUT, api_url, @@ -5437,9 +4823,7 @@ def test_post_grant_access_htmx(self): {}, **header, ) - self.assertEqual( - response.content.decode(), views.dbGaPAuditResolve.htmx_success - ) + self.assertEqual(response.content.decode(), views.dbGaPAuditResolve.htmx_success) # Membership has been created. membership = GroupGroupMembership.objects.get( parent_group=workspace.workspace.authorization_domains.first(), @@ -5469,13 +4853,8 @@ def test_post_remove_access(self): ) # Add API response # Note that the auth domain group is created automatically by the factory using the workspace name. - group_name = ( - dar.dbgap_data_access_snapshot.dbgap_application.anvil_access_group.name - ) - api_url = ( - self.api_client.sam_entry_point - + f"/api/groups/v1/auth_TEST_DBGAP/member/{group_name}@firecloud.org" - ) + group_name = dar.dbgap_data_access_snapshot.dbgap_application.anvil_access_group.name + api_url = self.api_client.sam_entry_point + f"/api/groups/v1/auth_TEST_DBGAP/member/{group_name}@firecloud.org" self.anvil_response_mock.add( responses.DELETE, api_url, @@ -5503,13 +4882,8 @@ def test_anvil_api_error_grant(self): ) # Add API response # Note that the auth domain group is created automatically by the factory using the workspace name. - group_name = ( - dar.dbgap_data_access_snapshot.dbgap_application.anvil_access_group.name - ) - api_url = ( - self.api_client.sam_entry_point - + f"/api/groups/v1/auth_TEST_DBGAP/member/{group_name}@firecloud.org" - ) + group_name = dar.dbgap_data_access_snapshot.dbgap_application.anvil_access_group.name + api_url = self.api_client.sam_entry_point + f"/api/groups/v1/auth_TEST_DBGAP/member/{group_name}@firecloud.org" self.anvil_response_mock.add( responses.PUT, api_url, @@ -5545,13 +4919,8 @@ def test_anvil_api_error_grant_htmx(self): ) # Add API response # Note that the auth domain group is created automatically by the factory using the workspace name. - group_name = ( - dar.dbgap_data_access_snapshot.dbgap_application.anvil_access_group.name - ) - api_url = ( - self.api_client.sam_entry_point - + f"/api/groups/v1/auth_TEST_DBGAP/member/{group_name}@firecloud.org" - ) + group_name = dar.dbgap_data_access_snapshot.dbgap_application.anvil_access_group.name + api_url = self.api_client.sam_entry_point + f"/api/groups/v1/auth_TEST_DBGAP/member/{group_name}@firecloud.org" self.anvil_response_mock.add( responses.PUT, api_url, @@ -5599,13 +4968,8 @@ def test_anvil_api_error_remove(self): ) # Add API response # Note that the auth domain group is created automatically by the factory using the workspace name. - group_name = ( - dar.dbgap_data_access_snapshot.dbgap_application.anvil_access_group.name - ) - api_url = ( - self.api_client.sam_entry_point - + f"/api/groups/v1/auth_TEST_DBGAP/member/{group_name}@firecloud.org" - ) + group_name = dar.dbgap_data_access_snapshot.dbgap_application.anvil_access_group.name + api_url = self.api_client.sam_entry_point + f"/api/groups/v1/auth_TEST_DBGAP/member/{group_name}@firecloud.org" self.anvil_response_mock.add( responses.DELETE, api_url, @@ -5655,13 +5019,8 @@ def test_anvil_api_error_remove_htmx(self): ) # Add API response # Note that the auth domain group is created automatically by the factory using the workspace name. - group_name = ( - dar.dbgap_data_access_snapshot.dbgap_application.anvil_access_group.name - ) - api_url = ( - self.api_client.sam_entry_point - + f"/api/groups/v1/auth_TEST_DBGAP/member/{group_name}@firecloud.org" - ) + group_name = dar.dbgap_data_access_snapshot.dbgap_application.anvil_access_group.name + api_url = self.api_client.sam_entry_point + f"/api/groups/v1/auth_TEST_DBGAP/member/{group_name}@firecloud.org" self.anvil_response_mock.add( responses.DELETE, api_url, @@ -5751,9 +5110,7 @@ def test_table_class(self): self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertIn("table", response.context_data) - self.assertIsInstance( - response.context_data["table"], tables.dbGaPApplicationRecordsTable - ) + self.assertIsInstance(response.context_data["table"], tables.dbGaPApplicationRecordsTable) def test_table_no_rows(self): """No rows are shown if there are no dbGaPApplications objects.""" diff --git a/primed/dbgap/urls.py b/primed/dbgap/urls.py index 0aea48d2..fb302b47 100644 --- a/primed/dbgap/urls.py +++ b/primed/dbgap/urls.py @@ -13,9 +13,7 @@ views.dbGaPStudyAccessionAutocomplete.as_view(), name="autocomplete", ), - path( - "", views.dbGaPStudyAccessionDetail.as_view(), name="detail" - ), + path("", views.dbGaPStudyAccessionDetail.as_view(), name="detail"), path( "/update/", views.dbGaPStudyAccessionUpdate.as_view(), diff --git a/primed/dbgap/views.py b/primed/dbgap/views.py index f9f59185..f4ebfa2a 100644 --- a/primed/dbgap/views.py +++ b/primed/dbgap/views.py @@ -39,9 +39,7 @@ logger = logging.getLogger(__name__) -class dbGaPStudyAccessionDetail( - AnVILConsortiumManagerStaffViewRequired, SingleTableMixin, DetailView -): +class dbGaPStudyAccessionDetail(AnVILConsortiumManagerStaffViewRequired, SingleTableMixin, DetailView): """View to show details about a `dbGaPStudyAccession`.""" model = models.dbGaPStudyAccession @@ -53,8 +51,7 @@ def get_object(self, queryset=None): obj = queryset.get(dbgap_phs=self.kwargs.get("dbgap_phs")) except queryset.model.DoesNotExist: raise Http404( - "No %(verbose_name)s found matching the query" - % {"verbose_name": queryset.model._meta.verbose_name} + "No %(verbose_name)s found matching the query" % {"verbose_name": queryset.model._meta.verbose_name} ) return obj @@ -70,12 +67,8 @@ def get_table(self): def get_context_data(self, **kwargs): """Add show_edit_links to context data.""" context = super().get_context_data(**kwargs) - edit_permission_codename = ( - AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) - context["show_edit_links"] = self.request.user.has_perm( - "anvil_consortium_manager." + edit_permission_codename - ) + edit_permission_codename = AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME + context["show_edit_links"] = self.request.user.has_perm("anvil_consortium_manager." + edit_permission_codename) return context @@ -86,9 +79,7 @@ class dbGaPStudyAccessionList(AnVILConsortiumManagerStaffViewRequired, SingleTab table_class = tables.dbGaPStudyAccessionTable -class dbGaPStudyAccessionCreate( - AnVILConsortiumManagerStaffEditRequired, SuccessMessageMixin, CreateView -): +class dbGaPStudyAccessionCreate(AnVILConsortiumManagerStaffEditRequired, SuccessMessageMixin, CreateView): """View to create a new dbGaPStudyAccession.""" model = models.dbGaPStudyAccession @@ -97,9 +88,7 @@ class dbGaPStudyAccessionCreate( template_name = "dbgap/dbgapstudyaccession_create.html" -class dbGaPStudyAccessionUpdate( - AnVILConsortiumManagerStaffEditRequired, SuccessMessageMixin, UpdateView -): +class dbGaPStudyAccessionUpdate(AnVILConsortiumManagerStaffEditRequired, SuccessMessageMixin, UpdateView): """View to update a dbGaPStudyAccession.""" model = models.dbGaPStudyAccession @@ -113,15 +102,12 @@ def get_object(self, queryset=None): obj = queryset.get(dbgap_phs=self.kwargs.get("dbgap_phs")) except queryset.model.DoesNotExist: raise Http404( - "No %(verbose_name)s found matching the query" - % {"verbose_name": queryset.model._meta.verbose_name} + "No %(verbose_name)s found matching the query" % {"verbose_name": queryset.model._meta.verbose_name} ) return obj -class dbGaPStudyAccessionAutocomplete( - AnVILConsortiumManagerStaffViewRequired, autocomplete.Select2QuerySetView -): +class dbGaPStudyAccessionAutocomplete(AnVILConsortiumManagerStaffViewRequired, autocomplete.Select2QuerySetView): """View to provide autocompletion for dbGaPStudyAccessions.""" def get_queryset(self): @@ -138,9 +124,7 @@ def get_queryset(self): return qs -class dbGaPApplicationDetail( - AnVILConsortiumManagerStaffViewRequired, SingleTableMixin, DetailView -): +class dbGaPApplicationDetail(AnVILConsortiumManagerStaffViewRequired, SingleTableMixin, DetailView): """View to show details about a `dbGaPApplication`.""" model = models.dbGaPApplication @@ -153,8 +137,7 @@ def get_object(self, queryset=None): obj = queryset.get(dbgap_project_id=self.kwargs.get("dbgap_project_id")) except queryset.model.DoesNotExist: raise Http404( - "No %(verbose_name)s found matching the query" - % {"verbose_name": queryset.model._meta.verbose_name} + "No %(verbose_name)s found matching the query" % {"verbose_name": queryset.model._meta.verbose_name} ) return obj @@ -171,9 +154,7 @@ def get_latest_snapshot(self): return None def get_table_data(self): - return models.dbGaPDataAccessSnapshot.objects.filter( - dbgap_application=self.object - ).order_by("-created") + return models.dbGaPDataAccessSnapshot.objects.filter(dbgap_application=self.object).order_by("-created") def get_context_data(self, *args, **kwargs): """Add to the context. @@ -196,9 +177,7 @@ class dbGaPApplicationList(AnVILConsortiumManagerStaffViewRequired, SingleTableV table_class = tables.dbGaPApplicationTable -class dbGaPApplicationCreate( - AnVILConsortiumManagerStaffEditRequired, SuccessMessageMixin, CreateView -): +class dbGaPApplicationCreate(AnVILConsortiumManagerStaffEditRequired, SuccessMessageMixin, CreateView): """View to create a new dbGaPApplication.""" model = models.dbGaPApplication @@ -210,25 +189,17 @@ class dbGaPApplicationCreate( def form_valid(self, form): """Create a managed group in the app on AnVIL and link it to this application.""" project_id = form.cleaned_data["dbgap_project_id"] - group_name = "{}_DBGAP_ACCESS_{}".format( - settings.ANVIL_DATA_ACCESS_GROUP_PREFIX, project_id - ) - managed_group = ManagedGroup( - name=group_name, email=group_name + "@firecloud.org" - ) + group_name = "{}_DBGAP_ACCESS_{}".format(settings.ANVIL_DATA_ACCESS_GROUP_PREFIX, project_id) + managed_group = ManagedGroup(name=group_name, email=group_name + "@firecloud.org") try: managed_group.full_clean() except ValidationError: - messages.add_message( - self.request, messages.ERROR, self.ERROR_CREATING_GROUP - ) + messages.add_message(self.request, messages.ERROR, self.ERROR_CREATING_GROUP) return self.render_to_response(self.get_context_data(form=form)) try: managed_group.anvil_create() except AnVILAPIError as e: - messages.add_message( - self.request, messages.ERROR, "AnVIL API Error: " + str(e) - ) + messages.add_message(self.request, messages.ERROR, "AnVIL API Error: " + str(e)) return self.render_to_response(self.get_context_data(form=form)) # Need to wrap this entire block in a transaction because we are creating multiple objects, and don't want # any of them to be saved if the API call fails. @@ -236,9 +207,7 @@ def form_valid(self, form): with transaction.atomic(): managed_group.save() # Create the dbgap access group. - cc_admins_group = ManagedGroup.objects.get( - name=settings.ANVIL_CC_ADMINS_GROUP_NAME - ) + cc_admins_group = ManagedGroup.objects.get(name=settings.ANVIL_CC_ADMINS_GROUP_NAME) membership = GroupGroupMembership.objects.create( parent_group=managed_group, child_group=cc_admins_group, @@ -248,37 +217,24 @@ def form_valid(self, form): membership.anvil_create() membership.save() except AnVILAPIError as e: - messages.add_message( - self.request, messages.ERROR, "AnVIL API Error: " + str(e) - ) + messages.add_message(self.request, messages.ERROR, "AnVIL API Error: " + str(e)) return self.render_to_response(self.get_context_data(form=form)) form.instance.anvil_access_group = managed_group return super().form_valid(form) -class dbGaPDataAccessSnapshotCreate( - AnVILConsortiumManagerStaffEditRequired, SuccessMessageMixin, FormView -): - +class dbGaPDataAccessSnapshotCreate(AnVILConsortiumManagerStaffEditRequired, SuccessMessageMixin, FormView): form_class = forms.dbGaPDataAccessSnapshotForm template_name = "dbgap/dbgapdataaccesssnapshot_form.html" - ERROR_DARS_ALREADY_ADDED = ( - "Data Access Requests have already been added for this application." - ) - ERROR_PROJECT_ID_DOES_NOT_MATCH = ( - "Project id in JSON does not match dbGaP application project id." - ) + ERROR_DARS_ALREADY_ADDED = "Data Access Requests have already been added for this application." + ERROR_PROJECT_ID_DOES_NOT_MATCH = "Project id in JSON does not match dbGaP application project id." ERROR_STUDY_ACCESSION_NOT_FOUND = "Study accession(s) not found in app." ERROR_CREATING_DARS = "Error creating Data Access Requests." - success_message = ( - "Successfully added Data Access Requests for this dbGaP application." - ) + success_message = "Successfully added Data Access Requests for this dbGaP application." def get_dbgap_application(self): try: - dbgap_application = models.dbGaPApplication.objects.get( - dbgap_project_id=self.kwargs["dbgap_project_id"] - ) + dbgap_application = models.dbGaPApplication.objects.get(dbgap_project_id=self.kwargs["dbgap_project_id"]) except models.dbGaPApplication.DoesNotExist: raise Http404( "No %(verbose_name)s found matching the query" @@ -344,10 +300,7 @@ def get_context_data(self, *args, **kwargs): return super().get_context_data(*args, **kwargs) -class dbGaPDataAccessSnapshotCreateMultiple( - AnVILConsortiumManagerStaffEditRequired, SuccessMessageMixin, FormView -): - +class dbGaPDataAccessSnapshotCreateMultiple(AnVILConsortiumManagerStaffEditRequired, SuccessMessageMixin, FormView): form_class = forms.dbGaPDataAccessSnapshotMultipleForm template_name = "dbgap/dbgapdataaccesssnapshot_form_multiple.html" # ERROR_DARS_ALREADY_ADDED = ( @@ -364,12 +317,7 @@ def get_context_data(self, **kwargs): """Add to the context data.""" context = super().get_context_data(**kwargs) # The URL for updating all applications. - project_ids = [ - x - for x in models.dbGaPApplication.objects.values_list( - "dbgap_project_id", flat=True - ) - ] + project_ids = [x for x in models.dbGaPApplication.objects.values_list("dbgap_project_id", flat=True)] context["dbgap_dar_json_url"] = helpers.get_dbgap_dar_json_url(project_ids) return context @@ -386,9 +334,7 @@ def form_valid(self, form): # Loop over projects. for project_json in dbgap_dar_data: dbgap_project_id = project_json["Project_id"] - dbgap_application = models.dbGaPApplication.objects.get( - dbgap_project_id=dbgap_project_id - ) + dbgap_application = models.dbGaPApplication.objects.get(dbgap_project_id=dbgap_project_id) try: previous_snapshot = models.dbGaPDataAccessSnapshot.objects.get( dbgap_application=dbgap_application, @@ -455,9 +401,7 @@ def form_valid(self, form): return super().form_valid(form) -class dbGaPDataAccessSnapshotDetail( - AnVILConsortiumManagerStaffViewRequired, DetailView -): +class dbGaPDataAccessSnapshotDetail(AnVILConsortiumManagerStaffViewRequired, DetailView): """View to show details about a `dbGaPDataAccessSnapshot`.""" model = models.dbGaPDataAccessSnapshot @@ -466,9 +410,7 @@ class dbGaPDataAccessSnapshotDetail( def get_dbgap_application(self): model = models.dbGaPApplication try: - application = model.objects.get( - dbgap_project_id=self.kwargs.get("dbgap_project_id") - ) + application = model.objects.get(dbgap_project_id=self.kwargs.get("dbgap_project_id")) except model.DoesNotExist: raise Http404( "No %(verbose_name)s found matching the query" @@ -483,15 +425,11 @@ def get_object(self, queryset=None): self.dbgap_application = self.get_dbgap_application() if not queryset: queryset = self.model.objects - return super().get_object( - queryset=queryset.filter(dbgap_application=self.dbgap_application) - ) + return super().get_object(queryset=queryset.filter(dbgap_application=self.dbgap_application)) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context[ - "data_access_request_table" - ] = tables.dbGaPDataAccessRequestBySnapshotTable( + context["data_access_request_table"] = tables.dbGaPDataAccessRequestBySnapshotTable( self.object.dbgapdataaccessrequest_set.all() ) context["summary_table"] = tables.dbGaPDataAccessRequestSummaryTable( @@ -503,9 +441,7 @@ def get_context_data(self, **kwargs): return context -class dbGaPDataAccessRequestList( - AnVILConsortiumManagerStaffViewRequired, ExportMixin, SingleTableView -): +class dbGaPDataAccessRequestList(AnVILConsortiumManagerStaffViewRequired, ExportMixin, SingleTableView): """View to show current DARs.""" model = models.dbGaPDataAccessRequest @@ -513,14 +449,10 @@ class dbGaPDataAccessRequestList( export_name = "dars_table" def get_table_data(self): - return self.get_queryset().filter( - dbgap_data_access_snapshot__is_most_recent=True - ) + return self.get_queryset().filter(dbgap_data_access_snapshot__is_most_recent=True) -class dbGaPDataAccessRequestHistory( - AnVILConsortiumManagerStaffViewRequired, ExportMixin, SingleTableView -): +class dbGaPDataAccessRequestHistory(AnVILConsortiumManagerStaffViewRequired, ExportMixin, SingleTableView): """View to show the history of a given DAR.""" model = models.dbGaPDataAccessRequest @@ -582,8 +514,7 @@ def get_object(self, queryset=None): obj = queryset.get(dbgap_project_id=self.kwargs.get("dbgap_project_id")) except queryset.model.DoesNotExist: raise Http404( - "No %(verbose_name)s found matching the query" - % {"verbose_name": queryset.model._meta.verbose_name} + "No %(verbose_name)s found matching the query" % {"verbose_name": queryset.model._meta.verbose_name} ) return obj @@ -641,8 +572,7 @@ def get_object(self, queryset=None): obj = queryset.get() except queryset.model.DoesNotExist: raise Http404( - _("No %(verbose_name)s found matching the query") - % {"verbose_name": queryset.model._meta.verbose_name} + _("No %(verbose_name)s found matching the query") % {"verbose_name": queryset.model._meta.verbose_name} ) return obj @@ -661,7 +591,6 @@ def get_context_data(self, **kwargs): class dbGaPAuditResolve(AnVILConsortiumManagerStaffEditRequired, FormView): - form_class = Form template_name = "dbgap/audit_resolve.html" htmx_success = """ Handled!""" @@ -681,29 +610,22 @@ def get_dbgap_workspace(self): obj = queryset.get() except queryset.model.DoesNotExist: raise Http404( - _("No %(verbose_name)s found matching the query") - % {"verbose_name": queryset.model._meta.verbose_name} + _("No %(verbose_name)s found matching the query") % {"verbose_name": queryset.model._meta.verbose_name} ) return obj def get_dbgap_application(self, queryset=None): """Look up the dbGaPApplication by dbgap_project_id.""" try: - obj = models.dbGaPApplication.objects.get( - dbgap_project_id=self.kwargs.get("dbgap_project_id") - ) + obj = models.dbGaPApplication.objects.get(dbgap_project_id=self.kwargs.get("dbgap_project_id")) except models.dbGaPApplication.DoesNotExist: raise Http404("No dbGaPApplications found matching the query") return obj def get_audit_result(self): instance = audit.dbGaPAccessAudit( - dbgap_workspace_queryset=models.dbGaPWorkspace.objects.filter( - pk=self.dbgap_workspace.pk - ), - dbgap_application_queryset=models.dbGaPApplication.objects.filter( - pk=self.dbgap_application.pk - ), + dbgap_workspace_queryset=models.dbGaPWorkspace.objects.filter(pk=self.dbgap_workspace.pk), + dbgap_application_queryset=models.dbGaPApplication.objects.filter(pk=self.dbgap_application.pk), ) instance.run_audit() return instance.get_all_results()[0] diff --git a/primed/drupal_oauth_provider/provider.py b/primed/drupal_oauth_provider/provider.py index f9f112ab..92c84dd0 100644 --- a/primed/drupal_oauth_provider/provider.py +++ b/primed/drupal_oauth_provider/provider.py @@ -24,7 +24,6 @@ class CustomAccount(ProviderAccount): class CustomProvider(OAuth2Provider): - id = "drupal_oauth_provider" name = OVERRIDE_NAME account_class = CustomAccount @@ -74,9 +73,7 @@ def get_provider_scope_config(self): ) if not isinstance(gregor_oauth_scopes, list): - raise ImproperlyConfigured( - "[get_provider_scope_config] provider setting SCOPES should be a list" - ) + raise ImproperlyConfigured("[get_provider_scope_config] provider setting SCOPES should be a list") return gregor_oauth_scopes diff --git a/primed/drupal_oauth_provider/views.py b/primed/drupal_oauth_provider/views.py index eb8fc82b..c8a78575 100644 --- a/primed/drupal_oauth_provider/views.py +++ b/primed/drupal_oauth_provider/views.py @@ -50,7 +50,6 @@ def _get_public_key_jwk(self, headers): return keys[0] def get_public_key(self, headers): - provider_settings = app_settings.PROVIDERS.get(self.provider_id, {}) config_public_key = provider_settings.get("PUBLIC_KEY") @@ -59,9 +58,7 @@ def get_public_key(self, headers): public_key_jwk = self._get_public_key_jwk(headers) try: - public_key = jwt.algorithms.RSAAlgorithm.from_jwk( - json.dumps(public_key_jwk) - ) + public_key = jwt.algorithms.RSAAlgorithm.from_jwk(json.dumps(public_key_jwk)) except Exception as e: logger.error(f"[get_public_key] failed to convert jwk to public key {e}") else: @@ -89,9 +86,7 @@ def get_scopes_from_token(self, id_token, headers): logger.error(f"Invalid id_token {e} {id_token.token}") raise OAuth2Error("Invalid id_token") from e except Exception as e: - logger.error( - f"Other exception parsing token {e} header {unverified_header} token {id_token}" - ) + logger.error(f"Other exception parsing token {e} header {unverified_header} token {id_token}") raise OAuth2Error("Error when decoding token {e}") else: scopes = token_payload.get("scope") @@ -102,9 +97,7 @@ def complete_login(self, request, app, token, **kwargs): headers = {"Authorization": "Bearer {0}".format(token.token)} scopes_granted = self.get_scopes_from_token(token, headers) - managed_scope_status = self.get_provider().get_provider_managed_scope_status( - scopes_granted - ) + managed_scope_status = self.get_provider().get_provider_managed_scope_status(scopes_granted) resp = requests.get(self.profile_url, headers=headers) resp.raise_for_status() @@ -116,9 +109,7 @@ def complete_login(self, request, app, token, **kwargs): ) extra_data["scopes_granted"] = scopes_granted extra_data["managed_scope_status"] = managed_scope_status - social_login = self.get_provider().sociallogin_from_response( - request, extra_data - ) + social_login = self.get_provider().sociallogin_from_response(request, extra_data) return social_login diff --git a/primed/duo/management/commands/load_duo.py b/primed/duo/management/commands/load_duo.py index 1668ddf3..9f67f787 100644 --- a/primed/duo/management/commands/load_duo.py +++ b/primed/duo/management/commands/load_duo.py @@ -34,21 +34,14 @@ def add_arguments(self, parser): def handle(self, *args, **options): # Error if anything is loaded into either model. - if ( - models.DataUsePermission.objects.exists() - or models.DataUseModifier.objects.exists() - ): - raise CommandError( - "At least one DataUsePermission or DataUseModifier already exists." - ) + if models.DataUsePermission.objects.exists() or models.DataUseModifier.objects.exists(): + raise CommandError("At least one DataUsePermission or DataUseModifier already exists.") duo_file = options["duo_file"] if not duo_file: # Use the default. tmppath = os.path.dirname(os.path.realpath(__file__)) - duo_file = os.path.join( - tmppath, os.pardir, os.pardir, "fixtures", "duo-basic.owl" - ) + duo_file = os.path.join(tmppath, os.pardir, os.pardir, "fixtures", "duo-basic.owl") self.stdout.write("Loading DUO terms from {}".format(duo_file)) # Read in the ontology. @@ -57,9 +50,7 @@ def handle(self, *args, **options): # Check that specified terms are in the file. permissions_code = options["permissions_code"] if permissions_code not in duo.terms(): - msg = "permissions-code '{}' not in available terms.".format( - permissions_code - ) + msg = "permissions-code '{}' not in available terms.".format(permissions_code) raise CommandError(self.style.ERROR(msg)) modifiers_code = options["modifiers_code"] @@ -84,9 +75,7 @@ def handle(self, *args, **options): def _get_term_abbreviation(self, term): """Return the abbreviation for the term.""" - abbreviation = [ - a.literal for a in term.annotations if "shorthand" in a.property - ] + abbreviation = [a.literal for a in term.annotations if "shorthand" in a.property] if len(abbreviation) != 1: import ipdb diff --git a/primed/duo/models.py b/primed/duo/models.py index 9b3414e9..558a1dfa 100644 --- a/primed/duo/models.py +++ b/primed/duo/models.py @@ -39,9 +39,7 @@ def __str__(self): return "{}".format(self.term) def get_ols_url(self): - return "http://purl.obolibrary.org/obo/{}".format( - self.identifier.replace("DUO:", "DUO_") - ) + return "http://purl.obolibrary.org/obo/{}".format(self.identifier.replace("DUO:", "DUO_")) def get_short_definition(self): text = re.sub(r"This .+? indicates that ", "", self.definition) @@ -103,8 +101,7 @@ def clean(self): if hasattr(self, "data_use_permission") and self.data_use_permission: if self.data_use_permission.requires_disease_term and not self.disease_term: raise ValidationError( - "`disease_term` must not be None " - "because data_use_permission requires a disease restriction." + "`disease_term` must not be None " "because data_use_permission requires a disease restriction." ) if not self.data_use_permission.requires_disease_term and self.disease_term: raise ValidationError( diff --git a/primed/duo/tests/test_commands.py b/primed/duo/tests/test_commands.py index a2abe6f7..02423483 100644 --- a/primed/duo/tests/test_commands.py +++ b/primed/duo/tests/test_commands.py @@ -29,9 +29,7 @@ def test_command_permissions_code_not_in_ontology(self): """Raises exception when specified permissions-code is not in the ontology.""" with self.assertRaises(CommandError) as e: call_command("load_duo", permissions_code="foo") - self.assertIn( - "permissions-code 'foo' not in available terms.", str(e.exception) - ) + self.assertIn("permissions-code 'foo' not in available terms.", str(e.exception)) def test_command_modifiers_code_not_in_ontology(self): """Raises exception when specified modifiers-code is not in the ontology.""" @@ -49,6 +47,4 @@ def test_command_output(self): """Correct output.""" out = StringIO() call_command("load_duo", stdout=out) - self.assertIn( - "5 DataUsePermissions and 18 DataUseModifiers loaded.", out.getvalue() - ) + self.assertIn("5 DataUsePermissions and 18 DataUseModifiers loaded.", out.getvalue()) diff --git a/primed/duo/tests/test_models.py b/primed/duo/tests/test_models.py index baeb1416..42c63206 100644 --- a/primed/duo/tests/test_models.py +++ b/primed/duo/tests/test_models.py @@ -27,9 +27,7 @@ def test_model_saving(self): def test_str_method(self): """The custom __str__ method returns the correct string.""" - instance = factories.DataUsePermissionFactory.create( - term="test group", identifier="foo" - ) + instance = factories.DataUsePermissionFactory.create(term="test group", identifier="foo") instance.save() self.assertIsInstance(instance.__str__(), str) self.assertEqual(instance.__str__(), "test group") @@ -81,28 +79,20 @@ def test_unique_identifier(self): instance2.full_clean() self.assertIn("identifier", e.exception.error_dict) self.assertEqual(len(e.exception.error_dict["identifier"]), 1) - self.assertIn( - "already exists", e.exception.error_dict["identifier"][0].messages[0] - ) + self.assertIn("already exists", e.exception.error_dict["identifier"][0].messages[0]) with self.assertRaises(IntegrityError): instance2.save() def test_get_short_definition(self): - instance = factories.DataUsePermissionFactory.create( - definition="Test definition" - ) + instance = factories.DataUsePermissionFactory.create(definition="Test definition") self.assertEqual(instance.get_short_definition(), "Test definition") def test_get_short_definition_re_sub(self): - instance = factories.DataUsePermissionFactory.create( - definition="This XXX indicates that everything is fine." - ) + instance = factories.DataUsePermissionFactory.create(definition="This XXX indicates that everything is fine.") self.assertEqual(instance.get_short_definition(), "Everything is fine.") def test_get_short_definition_capitalization(self): - instance = factories.DataUsePermissionFactory.create( - definition="Test definition XyXy" - ) + instance = factories.DataUsePermissionFactory.create(definition="Test definition XyXy") self.assertEqual(instance.get_short_definition(), "Test definition XyXy") @@ -123,9 +113,7 @@ def test_model_saving(self): def test_str_method(self): """The custom __str__ method returns the correct string.""" - instance = factories.DataUseModifierFactory.create( - term="test group", identifier="foo" - ) + instance = factories.DataUseModifierFactory.create(term="test group", identifier="foo") instance.save() self.assertIsInstance(instance.__str__(), str) self.assertEqual(instance.__str__(), "test group") @@ -169,9 +157,7 @@ def test_unique_identifier(self): instance2.full_clean() self.assertIn("identifier", e.exception.error_dict) self.assertEqual(len(e.exception.error_dict["identifier"]), 1) - self.assertIn( - "already exists", e.exception.error_dict["identifier"][0].messages[0] - ) + self.assertIn("already exists", e.exception.error_dict["identifier"][0].messages[0]) with self.assertRaises(IntegrityError): instance2.save() @@ -180,9 +166,7 @@ def test_get_short_definition(self): self.assertEqual(instance.get_short_definition(), "Test definition") def test_get_short_definition_re_sub(self): - instance = factories.DataUseModifierFactory.create( - definition="This XXX indicates that use is allowed." - ) + instance = factories.DataUseModifierFactory.create(definition="This XXX indicates that use is allowed.") self.assertEqual(instance.get_short_definition(), "Use is allowed.") @@ -193,42 +177,28 @@ class DataUseOntologyTestCase(TestCase): def test_clean_requires_disease_term_false_with_no_disease_term(self): """Clean succeeds if disease_term is not set and requires_disease_term is False.""" - data_use_permission = factories.DataUsePermissionFactory.create( - requires_disease_term=False - ) - workspace = dbGaPWorkspaceFactory.create( - data_use_permission=data_use_permission - ) + data_use_permission = factories.DataUsePermissionFactory.create(requires_disease_term=False) + workspace = dbGaPWorkspaceFactory.create(data_use_permission=data_use_permission) # No errors should be raised. workspace.clean() def test_clean_requires_disease_term_true_with_disease_term(self): """Clean succeeds if disease_term is set and requires_disease_term is True.""" - data_use_permission = factories.DataUsePermissionFactory.create( - requires_disease_term=True - ) - workspace = dbGaPWorkspaceFactory.create( - data_use_permission=data_use_permission, disease_term="foo" - ) + data_use_permission = factories.DataUsePermissionFactory.create(requires_disease_term=True) + workspace = dbGaPWorkspaceFactory.create(data_use_permission=data_use_permission, disease_term="foo") workspace.clean() def test_clean_requires_disease_term_false_with_disease_term(self): """Clean fails if disease_term is set when requires_disease_term is False.""" - data_use_permission = factories.DataUsePermissionFactory.create( - requires_disease_term=False - ) - workspace = dbGaPWorkspaceFactory.create( - data_use_permission=data_use_permission, disease_term="foo" - ) + data_use_permission = factories.DataUsePermissionFactory.create(requires_disease_term=False) + workspace = dbGaPWorkspaceFactory.create(data_use_permission=data_use_permission, disease_term="foo") with self.assertRaises(ValidationError) as e: workspace.clean() self.assertIn("does not require a disease restriction", str(e.exception)) def test_clean_requires_disease_term_true_with_no_disease_term(self): """Clean fails if disease_term is not set when requires_disease_term is True.""" - data_use_permission = factories.DataUsePermissionFactory.create( - requires_disease_term=True - ) + data_use_permission = factories.DataUsePermissionFactory.create(requires_disease_term=True) workspace = dbGaPWorkspaceFactory.create( data_use_permission=data_use_permission, ) diff --git a/primed/duo/tests/test_views.py b/primed/duo/tests/test_views.py index e22ca408..45d9c787 100644 --- a/primed/duo/tests/test_views.py +++ b/primed/duo/tests/test_views.py @@ -22,9 +22,7 @@ def setUp(self): # Create a user with staff view permission. self.user = UserFactory.create(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -125,9 +123,7 @@ def setUp(self): # Create a user with view permission. self.user = UserFactory.create(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -179,9 +175,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = UserFactory.create(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -281,9 +275,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = UserFactory.create(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): diff --git a/primed/duo/views.py b/primed/duo/views.py index 308cc3e1..733b284d 100644 --- a/primed/duo/views.py +++ b/primed/duo/views.py @@ -6,7 +6,6 @@ class DataUsePermissionList(AnVILConsortiumManagerViewRequired, ListView): - model = models.DataUsePermission def get_context_data(self, **kwargs): @@ -19,7 +18,6 @@ def get_context_data(self, **kwargs): class DataUsePermissionDetail(AnVILConsortiumManagerViewRequired, DetailView): - model = models.DataUsePermission def get_object(self): @@ -27,8 +25,7 @@ def get_object(self): obj = self.model.objects.get(identifier=self.kwargs.get("id")) except self.model.DoesNotExist: raise Http404( - "No %(verbose_name)s found matching the query" - % {"verbose_name": self.model._meta.verbose_name} + "No %(verbose_name)s found matching the query" % {"verbose_name": self.model._meta.verbose_name} ) return obj @@ -39,7 +36,6 @@ def get_context_data(self, **kwargs): class DataUseModifierList(AnVILConsortiumManagerViewRequired, ListView): - model = models.DataUseModifier def get_context_data(self, **kwargs): @@ -52,7 +48,6 @@ def get_context_data(self, **kwargs): class DataUseModifierDetail(AnVILConsortiumManagerViewRequired, DetailView): - model = models.DataUseModifier def get_object(self): @@ -60,8 +55,7 @@ def get_object(self): obj = self.model.objects.get(identifier=self.kwargs.get("id")) except self.model.DoesNotExist: raise Http404( - "No %(verbose_name)s found matching the query" - % {"verbose_name": self.model._meta.verbose_name} + "No %(verbose_name)s found matching the query" % {"verbose_name": self.model._meta.verbose_name} ) return obj diff --git a/primed/miscellaneous_workspaces/adapters.py b/primed/miscellaneous_workspaces/adapters.py index 17bdfb9b..42a2d72c 100644 --- a/primed/miscellaneous_workspaces/adapters.py +++ b/primed/miscellaneous_workspaces/adapters.py @@ -22,9 +22,7 @@ class SimulatedDataWorkspaceAdapter(BaseWorkspaceAdapter): workspace_form_class = WorkspaceForm workspace_data_model = models.SimulatedDataWorkspace workspace_data_form_class = forms.SimulatedDataWorkspaceForm - workspace_detail_template_name = ( - "miscellaneous_workspaces/simulateddataworkspace_detail.html" - ) + workspace_detail_template_name = "miscellaneous_workspaces/simulateddataworkspace_detail.html" class ConsortiumDevelWorkspaceAdapter(BaseWorkspaceAdapter): @@ -60,9 +58,7 @@ class TemplateWorkspaceAdapter(BaseWorkspaceAdapter): type = "template" name = "Template workspace" - description = ( - "Template workspaces that will be cloned by the CC to create other workspaces" - ) + description = "Template workspaces that will be cloned by the CC to create other workspaces" list_table_class_staff_view = DefaultWorkspaceStaffTable list_table_class_view = DefaultWorkspaceUserTable workspace_form_class = WorkspaceForm @@ -82,9 +78,7 @@ class OpenAccessWorkspaceAdapter(BaseWorkspaceAdapter): workspace_form_class = WorkspaceForm workspace_data_model = models.OpenAccessWorkspace workspace_data_form_class = forms.OpenAccessWorkspaceForm - workspace_detail_template_name = ( - "miscellaneous_workspaces/openaccessworkspace_detail.html" - ) + workspace_detail_template_name = "miscellaneous_workspaces/openaccessworkspace_detail.html" class DataPrepWorkspaceAdapter(BaseWorkspaceAdapter): @@ -98,6 +92,4 @@ class DataPrepWorkspaceAdapter(BaseWorkspaceAdapter): workspace_form_class = WorkspaceForm workspace_data_model = models.DataPrepWorkspace workspace_data_form_class = forms.DataPrepWorkspaceForm - workspace_detail_template_name = ( - "miscellaneous_workspaces/dataprepworkspace_detail.html" - ) + workspace_detail_template_name = "miscellaneous_workspaces/dataprepworkspace_detail.html" diff --git a/primed/miscellaneous_workspaces/models.py b/primed/miscellaneous_workspaces/models.py index d702122d..97ad892d 100644 --- a/primed/miscellaneous_workspaces/models.py +++ b/primed/miscellaneous_workspaces/models.py @@ -59,16 +59,8 @@ class DataPrepWorkspace(RequesterModel, TimeStampedModel, BaseWorkspaceData): def clean(self): if hasattr(self, "target_workspace"): if self.target_workspace.workspace_type == "data_prep": - raise ValidationError( - { - "target_workspace": "target_workspace cannot be a DataPrepWorkspace." - } - ) + raise ValidationError({"target_workspace": "target_workspace cannot be a DataPrepWorkspace."}) if hasattr(self, "target_workspace") and hasattr(self, "workspace"): if self.target_workspace == self.workspace: - raise ValidationError( - { - "target_workspace": "target_workspace must be different than workspace." - } - ) + raise ValidationError({"target_workspace": "target_workspace must be different than workspace."}) diff --git a/primed/miscellaneous_workspaces/tables.py b/primed/miscellaneous_workspaces/tables.py index 014f746c..cc2b7b51 100644 --- a/primed/miscellaneous_workspaces/tables.py +++ b/primed/miscellaneous_workspaces/tables.py @@ -48,12 +48,8 @@ class DataPrepWorkspaceUserTable(tables.Table): """Class to render a table of Workspace objects with DataPrepWorkspace workspace data.""" name = tables.columns.Column(linkify=True) - dataprepworkspace__target_workspace__name = tables.columns.Column( - linkify=True, verbose_name="Target workspace" - ) - dataprepworkspace__is_active = BooleanIconColumn( - verbose_name="Active?", show_false_icon=True - ) + dataprepworkspace__target_workspace__name = tables.columns.Column(linkify=True, verbose_name="Target workspace") + dataprepworkspace__is_active = BooleanIconColumn(verbose_name="Active?", show_false_icon=True) class Meta: model = Workspace diff --git a/primed/miscellaneous_workspaces/tests/test_forms.py b/primed/miscellaneous_workspaces/tests/test_forms.py index b6dd125a..3fc86728 100644 --- a/primed/miscellaneous_workspaces/tests/test_forms.py +++ b/primed/miscellaneous_workspaces/tests/test_forms.py @@ -1,4 +1,4 @@ -""""Form tests for the `workspaces` app.""" +""" "Form tests for the `workspaces` app.""" from anvil_consortium_manager.adapters.workspace import workspace_adapter_registry from anvil_consortium_manager.tests.factories import WorkspaceFactory @@ -12,7 +12,6 @@ class SimulatedDataWorkspaceFormTest(TestCase): - form_class = forms.SimulatedDataWorkspaceForm def setUp(self): @@ -55,7 +54,6 @@ def test_invalid_missing_requester(self): class ConsortiumDevelWorkspaceFormTest(TestCase): - form_class = forms.ConsortiumDevelWorkspaceForm def setUp(self): @@ -98,7 +96,6 @@ def test_invalid_missing_requester(self): class ResourceWorkspaceFormTest(TestCase): - form_class = forms.ResourceWorkspaceForm def setUp(self): @@ -141,7 +138,6 @@ def test_invalid_missing_requester(self): class TemplateWorkspaceFormTest(TestCase): - form_class = forms.TemplateWorkspaceForm def setUp(self): @@ -196,7 +192,6 @@ def test_invalid_blank_intended_usage(self): class OpenAccessWorkspaceFormTest(TestCase): - form_class = forms.OpenAccessWorkspaceForm def setUp(self): @@ -342,7 +337,6 @@ def test_invalid_data_url_is_not_url(self): class DataPrepWorkspaceFormTest(TestCase): - form_class = forms.DataPrepWorkspaceForm def setUp(self): @@ -412,9 +406,7 @@ def test_form_all_registered_workspaces(self): # Cannot create data prep workspaces for data prep workspace target_workspaces. pass else: - target_workspace = WorkspaceFactory.create( - workspace_type=workspace_type - ) + target_workspace = WorkspaceFactory.create(workspace_type=workspace_type) form_data = { "workspace": self.workspace, "target_workspace": target_workspace, diff --git a/primed/miscellaneous_workspaces/tests/test_models.py b/primed/miscellaneous_workspaces/tests/test_models.py index c8222656..4f8ad2c3 100644 --- a/primed/miscellaneous_workspaces/tests/test_models.py +++ b/primed/miscellaneous_workspaces/tests/test_models.py @@ -1,4 +1,4 @@ -""""Model tests for the `miscellaneous_workspaces` app.""" +""" "Model tests for the `miscellaneous_workspaces` app.""" from anvil_consortium_manager.tests.factories import WorkspaceFactory from django.core.exceptions import ValidationError @@ -23,9 +23,7 @@ def test_model_saving(self): self.assertIsInstance(instance, models.SimulatedDataWorkspace) def test_str_method(self): - workspace = WorkspaceFactory.create( - billing_project__name="test-bp", name="test-ws" - ) + workspace = WorkspaceFactory.create(billing_project__name="test-bp", name="test-ws") instance = factories.SimulatedDataWorkspaceFactory.create(workspace=workspace) self.assertIsInstance(str(instance), str) self.assertEqual(str(instance), "test-bp/test-ws") @@ -38,16 +36,12 @@ def test_model_saving(self): """Creation using the model constructor and .save() works.""" workspace = WorkspaceFactory.create() user = UserFactory.create() - instance = models.ConsortiumDevelWorkspace( - workspace=workspace, requested_by=user - ) + instance = models.ConsortiumDevelWorkspace(workspace=workspace, requested_by=user) instance.save() self.assertIsInstance(instance, models.ConsortiumDevelWorkspace) def test_str_method(self): - workspace = WorkspaceFactory.create( - billing_project__name="test-bp", name="test-ws" - ) + workspace = WorkspaceFactory.create(billing_project__name="test-bp", name="test-ws") instance = factories.ConsortiumDevelWorkspaceFactory.create(workspace=workspace) self.assertIsInstance(str(instance), str) self.assertEqual(str(instance), "test-bp/test-ws") @@ -65,9 +59,7 @@ def test_model_saving(self): self.assertIsInstance(instance, models.ResourceWorkspace) def test_str_method(self): - workspace = WorkspaceFactory.create( - billing_project__name="test-bp", name="test-ws" - ) + workspace = WorkspaceFactory.create(billing_project__name="test-bp", name="test-ws") instance = factories.ResourceWorkspaceFactory.create(workspace=workspace) self.assertIsInstance(str(instance), str) self.assertEqual(str(instance), "test-bp/test-ws") @@ -84,9 +76,7 @@ def test_model_saving(self): self.assertIsInstance(instance, models.TemplateWorkspace) def test_str_method(self): - workspace = WorkspaceFactory.create( - billing_project__name="test-bp", name="test-ws" - ) + workspace = WorkspaceFactory.create(billing_project__name="test-bp", name="test-ws") instance = factories.TemplateWorkspaceFactory.create(workspace=workspace) self.assertIsInstance(str(instance), str) self.assertEqual(str(instance), "test-bp/test-ws") @@ -104,9 +94,7 @@ def test_model_saving(self): self.assertIsInstance(instance, models.OpenAccessWorkspace) def test_str_method(self): - workspace = WorkspaceFactory.create( - billing_project__name="test-bp", name="test-ws" - ) + workspace = WorkspaceFactory.create(billing_project__name="test-bp", name="test-ws") instance = factories.OpenAccessWorkspaceFactory.create(workspace=workspace) self.assertIsInstance(str(instance), str) self.assertEqual(str(instance), "test-bp/test-ws") @@ -144,9 +132,7 @@ def test_two_available_data(self): def test_data_url(self): workspace = WorkspaceFactory.create() user = UserFactory.create() - instance = models.OpenAccessWorkspace( - workspace=workspace, requested_by=user, data_url="http://www.example.com" - ) + instance = models.OpenAccessWorkspace(workspace=workspace, requested_by=user, data_url="http://www.example.com") self.assertEqual(instance.data_url, "http://www.example.com") @@ -158,28 +144,20 @@ def test_model_saving(self): workspace = WorkspaceFactory.create() target_workspace = WorkspaceFactory.create() user = UserFactory.create() - instance = models.DataPrepWorkspace( - workspace=workspace, target_workspace=target_workspace, requested_by=user - ) + instance = models.DataPrepWorkspace(workspace=workspace, target_workspace=target_workspace, requested_by=user) instance.save() self.assertIsInstance(instance, models.DataPrepWorkspace) def test_str_method(self): - workspace = WorkspaceFactory.create( - billing_project__name="test-bp", name="test-ws" - ) + workspace = WorkspaceFactory.create(billing_project__name="test-bp", name="test-ws") instance = factories.DataPrepWorkspaceFactory.create(workspace=workspace) self.assertIsInstance(str(instance), str) self.assertEqual(str(instance), "test-bp/test-ws") def test_two_update_workspaces_for_same_final_workspace(self): target_workspace = WorkspaceFactory.create() - instance_1 = factories.DataPrepWorkspaceFactory.create( - target_workspace=target_workspace - ) - instance_2 = factories.DataPrepWorkspaceFactory.create( - target_workspace=target_workspace - ) + instance_1 = factories.DataPrepWorkspaceFactory.create(target_workspace=target_workspace) + instance_2 = factories.DataPrepWorkspaceFactory.create(target_workspace=target_workspace) self.assertEqual(target_workspace.data_prep_workspaces.count(), 2) self.assertIn(instance_1, target_workspace.data_prep_workspaces.all()) self.assertIn(instance_2, target_workspace.data_prep_workspaces.all()) @@ -188,9 +166,7 @@ def test_clean_original_workspace_different_than_workspace(self): """Clean method raises ValidationError when workspace is the same as original_workspace.""" workspace = WorkspaceFactory.create() user = UserFactory.create() - instance = models.DataPrepWorkspace( - requested_by=user, workspace=workspace, target_workspace=workspace - ) + instance = models.DataPrepWorkspace(requested_by=user, workspace=workspace, target_workspace=workspace) with self.assertRaises(ValidationError) as e: instance.full_clean() self.assertEqual(len(e.exception.message_dict), 1) diff --git a/primed/miscellaneous_workspaces/tests/test_views.py b/primed/miscellaneous_workspaces/tests/test_views.py index 6e8d5916..ac351cea 100644 --- a/primed/miscellaneous_workspaces/tests/test_views.py +++ b/primed/miscellaneous_workspaces/tests/test_views.py @@ -29,9 +29,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) def test_status_code_with_user_permission(self): @@ -54,14 +52,10 @@ def setUp(self): # Create a user with both view and edit permissions. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) self.requester = UserFactory.create() self.workspace_type = "simulated_data" @@ -120,14 +114,10 @@ def setUp(self): # Create a user with both view and edit permissions. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) self.requester = UserFactory.create() self.workspace_type = "simulated_data" @@ -138,25 +128,15 @@ def get_url(self, *args): def get_api_url(self, billing_project_name, workspace_name): """Return the Terra API url for a given billing project and workspace.""" - return ( - self.api_client.rawls_entry_point - + "/api/workspaces/" - + billing_project_name - + "/" - + workspace_name - ) + return self.api_client.rawls_entry_point + "/api/workspaces/" + billing_project_name + "/" + workspace_name - def get_api_json_response( - self, billing_project, workspace, authorization_domains=[], access="OWNER" - ): + def get_api_json_response(self, billing_project, workspace, authorization_domains=[], access="OWNER"): """Return a pared down version of the json response from the AnVIL API with only fields we need.""" json_data = { "accessLevel": access, "owners": [], "workspace": { - "authorizationDomain": [ - {"membersGroupName": x} for x in authorization_domains - ], + "authorizationDomain": [{"membersGroupName": x} for x in authorization_domains], "name": workspace, "namespace": billing_project, "isLocked": False, @@ -174,9 +154,7 @@ def test_creates_workspace(self): responses.GET, workspace_list_url, match=[ - responses.matchers.query_param_matcher( - {"fields": "workspace.namespace,workspace.name,accessLevel"} - ) + responses.matchers.query_param_matcher({"fields": "workspace.namespace,workspace.name,accessLevel"}) ], status=200, json=[self.get_api_json_response(billing_project.name, workspace_name)], @@ -242,9 +220,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) def test_status_code_with_user_permission(self): @@ -267,14 +243,10 @@ def setUp(self): # Create a user with both view and edit permissions. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) self.requester = UserFactory.create() self.workspace_type = "devel" @@ -333,14 +305,10 @@ def setUp(self): # Create a user with both view and edit permissions. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) self.requester = UserFactory.create() self.workspace_type = "devel" @@ -351,25 +319,15 @@ def get_url(self, *args): def get_api_url(self, billing_project_name, workspace_name): """Return the Terra API url for a given billing project and workspace.""" - return ( - self.api_client.rawls_entry_point - + "/api/workspaces/" - + billing_project_name - + "/" - + workspace_name - ) + return self.api_client.rawls_entry_point + "/api/workspaces/" + billing_project_name + "/" + workspace_name - def get_api_json_response( - self, billing_project, workspace, authorization_domains=[], access="OWNER" - ): + def get_api_json_response(self, billing_project, workspace, authorization_domains=[], access="OWNER"): """Return a pared down version of the json response from the AnVIL API with only fields we need.""" json_data = { "accessLevel": access, "owners": [], "workspace": { - "authorizationDomain": [ - {"membersGroupName": x} for x in authorization_domains - ], + "authorizationDomain": [{"membersGroupName": x} for x in authorization_domains], "name": workspace, "namespace": billing_project, "isLocked": False, @@ -387,9 +345,7 @@ def test_creates_workspace(self): responses.GET, workspace_list_url, match=[ - responses.matchers.query_param_matcher( - {"fields": "workspace.namespace,workspace.name,accessLevel"} - ) + responses.matchers.query_param_matcher({"fields": "workspace.namespace,workspace.name,accessLevel"}) ], status=200, json=[self.get_api_json_response(billing_project.name, workspace_name)], @@ -455,9 +411,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) def test_status_code_with_user_permission(self): @@ -480,14 +434,10 @@ def setUp(self): # Create a user with both view and edit permissions. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) self.requester = UserFactory.create() self.workspace_type = "resource" @@ -546,14 +496,10 @@ def setUp(self): # Create a user with both view and edit permissions. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) self.requester = UserFactory.create() self.workspace_type = "resource" @@ -564,25 +510,15 @@ def get_url(self, *args): def get_api_url(self, billing_project_name, workspace_name): """Return the Terra API url for a given billing project and workspace.""" - return ( - self.api_client.rawls_entry_point - + "/api/workspaces/" - + billing_project_name - + "/" - + workspace_name - ) + return self.api_client.rawls_entry_point + "/api/workspaces/" + billing_project_name + "/" + workspace_name - def get_api_json_response( - self, billing_project, workspace, authorization_domains=[], access="OWNER" - ): + def get_api_json_response(self, billing_project, workspace, authorization_domains=[], access="OWNER"): """Return a pared down version of the json response from the AnVIL API with only fields we need.""" json_data = { "accessLevel": access, "owners": [], "workspace": { - "authorizationDomain": [ - {"membersGroupName": x} for x in authorization_domains - ], + "authorizationDomain": [{"membersGroupName": x} for x in authorization_domains], "name": workspace, "namespace": billing_project, "isLocked": False, @@ -600,9 +536,7 @@ def test_creates_workspace(self): responses.GET, workspace_list_url, match=[ - responses.matchers.query_param_matcher( - {"fields": "workspace.namespace,workspace.name,accessLevel"} - ) + responses.matchers.query_param_matcher({"fields": "workspace.namespace,workspace.name,accessLevel"}) ], status=200, json=[self.get_api_json_response(billing_project.name, workspace_name)], @@ -668,9 +602,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) def test_status_code_with_user_permission(self): @@ -693,14 +625,10 @@ def setUp(self): # Create a user with both view and edit permissions. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) self.workspace_type = "template" @@ -759,14 +687,10 @@ def setUp(self): # Create a user with both view and edit permissions. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) self.workspace_type = "template" @@ -776,25 +700,15 @@ def get_url(self, *args): def get_api_url(self, billing_project_name, workspace_name): """Return the Terra API url for a given billing project and workspace.""" - return ( - self.api_client.rawls_entry_point - + "/api/workspaces/" - + billing_project_name - + "/" - + workspace_name - ) + return self.api_client.rawls_entry_point + "/api/workspaces/" + billing_project_name + "/" + workspace_name - def get_api_json_response( - self, billing_project, workspace, authorization_domains=[], access="OWNER" - ): + def get_api_json_response(self, billing_project, workspace, authorization_domains=[], access="OWNER"): """Return a pared down version of the json response from the AnVIL API with only fields we need.""" json_data = { "accessLevel": access, "owners": [], "workspace": { - "authorizationDomain": [ - {"membersGroupName": x} for x in authorization_domains - ], + "authorizationDomain": [{"membersGroupName": x} for x in authorization_domains], "name": workspace, "namespace": billing_project, "isLocked": False, @@ -812,9 +726,7 @@ def test_creates_workspace(self): responses.GET, workspace_list_url, match=[ - responses.matchers.query_param_matcher( - {"fields": "workspace.namespace,workspace.name,accessLevel"} - ) + responses.matchers.query_param_matcher({"fields": "workspace.namespace,workspace.name,accessLevel"}) ], status=200, json=[self.get_api_json_response(billing_project.name, workspace_name)], @@ -881,9 +793,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) def test_status_code_with_user_permission(self): @@ -910,14 +820,10 @@ def setUp(self): # Create a user with both view and edit permissions. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) self.workspace_type = "open_access" self.requester = UserFactory.create() @@ -983,14 +889,10 @@ def setUp(self): # Create a user with both view and edit permissions. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) self.workspace_type = "open_access" self.requester = UserFactory.create() @@ -1002,25 +904,15 @@ def get_url(self, *args): def get_api_url(self, billing_project_name, workspace_name): """Return the Terra API url for a given billing project and workspace.""" - return ( - self.api_client.rawls_entry_point - + "/api/workspaces/" - + billing_project_name - + "/" - + workspace_name - ) + return self.api_client.rawls_entry_point + "/api/workspaces/" + billing_project_name + "/" + workspace_name - def get_api_json_response( - self, billing_project, workspace, authorization_domains=[], access="OWNER" - ): + def get_api_json_response(self, billing_project, workspace, authorization_domains=[], access="OWNER"): """Return a pared down version of the json response from the AnVIL API with only fields we need.""" json_data = { "accessLevel": access, "owners": [], "workspace": { - "authorizationDomain": [ - {"membersGroupName": x} for x in authorization_domains - ], + "authorizationDomain": [{"membersGroupName": x} for x in authorization_domains], "name": workspace, "namespace": billing_project, "isLocked": False, @@ -1038,9 +930,7 @@ def test_creates_workspace(self): responses.GET, workspace_list_url, match=[ - responses.matchers.query_param_matcher( - {"fields": "workspace.namespace,workspace.name,accessLevel"} - ) + responses.matchers.query_param_matcher({"fields": "workspace.namespace,workspace.name,accessLevel"}) ], status=200, json=[self.get_api_json_response(billing_project.name, workspace_name)], @@ -1112,9 +1002,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) def test_status_code_with_user_permission(self): @@ -1155,14 +1043,10 @@ def setUp(self): # Create a user with both view and edit permissions. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) self.requester = UserFactory.create() self.target_workspace = WorkspaceFactory.create() @@ -1223,14 +1107,10 @@ def setUp(self): # Create a user with both view and edit permissions. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) self.requester = UserFactory.create() self.target_workspace = WorkspaceFactory.create() @@ -1242,25 +1122,15 @@ def get_url(self, *args): def get_api_url(self, billing_project_name, workspace_name): """Return the Terra API url for a given billing project and workspace.""" - return ( - self.api_client.rawls_entry_point - + "/api/workspaces/" - + billing_project_name - + "/" - + workspace_name - ) + return self.api_client.rawls_entry_point + "/api/workspaces/" + billing_project_name + "/" + workspace_name - def get_api_json_response( - self, billing_project, workspace, authorization_domains=[], access="OWNER" - ): + def get_api_json_response(self, billing_project, workspace, authorization_domains=[], access="OWNER"): """Return a pared down version of the json response from the AnVIL API with only fields we need.""" json_data = { "accessLevel": access, "owners": [], "workspace": { - "authorizationDomain": [ - {"membersGroupName": x} for x in authorization_domains - ], + "authorizationDomain": [{"membersGroupName": x} for x in authorization_domains], "name": workspace, "namespace": billing_project, "isLocked": False, @@ -1278,9 +1148,7 @@ def test_creates_workspace(self): responses.GET, workspace_list_url, match=[ - responses.matchers.query_param_matcher( - {"fields": "workspace.namespace,workspace.name,accessLevel"} - ) + responses.matchers.query_param_matcher({"fields": "workspace.namespace,workspace.name,accessLevel"}) ], status=200, json=[self.get_api_json_response(billing_project.name, workspace_name)], diff --git a/primed/primed_anvil/adapters.py b/primed/primed_anvil/adapters.py index 8d22bdee..f62a4593 100644 --- a/primed/primed_anvil/adapters.py +++ b/primed/primed_anvil/adapters.py @@ -14,9 +14,7 @@ class AccountAdapter(BaseAccountAdapter): def get_autocomplete_queryset(self, queryset, q): """Filter to Accounts where the email or the associated user name matches the query `q`.""" if q: - queryset = queryset.filter( - Q(email__icontains=q) | Q(user__name__icontains=q) - ) + queryset = queryset.filter(Q(email__icontains=q) | Q(user__name__icontains=q)) return queryset def get_autocomplete_label(self, account): diff --git a/primed/primed_anvil/audit.py b/primed/primed_anvil/audit.py index b01ac5c0..0eca6a15 100644 --- a/primed/primed_anvil/audit.py +++ b/primed/primed_anvil/audit.py @@ -90,9 +90,7 @@ def get_all_results(self): def _check_completed(self): if not self.completed: - raise ValueError( - "Audit has not been completed. Use run_audit() to run the audit." - ) + raise ValueError("Audit has not been completed. Use run_audit() to run the audit.") def get_verified_table(self): """Return a table of verified audit results. @@ -103,9 +101,7 @@ def get_verified_table(self): results_table_class: A table of verified results. """ self._check_completed() - return self.results_table_class( - [x.get_table_dictionary() for x in self.verified] - ) + return self.results_table_class([x.get_table_dictionary() for x in self.verified]) def get_needs_action_table(self): """Return a table of needs_action audit results. @@ -116,9 +112,7 @@ def get_needs_action_table(self): results_table_class: A table of need action results. """ self._check_completed() - return self.results_table_class( - [x.get_table_dictionary() for x in self.needs_action] - ) + return self.results_table_class([x.get_table_dictionary() for x in self.needs_action]) def get_errors_table(self): """Return a table of error audit results. diff --git a/primed/primed_anvil/helpers.py b/primed/primed_anvil/helpers.py index e0f6cacf..911271f4 100644 --- a/primed/primed_anvil/helpers.py +++ b/primed/primed_anvil/helpers.py @@ -18,9 +18,7 @@ def get_summary_table_data(): # If no available data objects exist, raise ???. available_data_types = AvailableData.objects.values_list("name", flat=True) if not len(available_data_types): - raise RuntimeError( - "get_summary_table_data requires at least one AvailableData object to exist." - ) + raise RuntimeError("get_summary_table_data requires at least one AvailableData object to exist.") # This query will be used to add information about whether a study has workspaces # that are shared with the consortium. diff --git a/primed/primed_anvil/models.py b/primed/primed_anvil/models.py index 2277c9b8..87389d1b 100644 --- a/primed/primed_anvil/models.py +++ b/primed/primed_anvil/models.py @@ -8,12 +8,8 @@ class Study(TimeStampedModel, models.Model): """A model to track studies.""" - short_name = models.CharField( - max_length=31, unique=True, help_text="The short name for this Study." - ) - full_name = models.CharField( - max_length=255, help_text="The full name for this Study." - ) + short_name = models.CharField(max_length=31, unique=True, help_text="The short name for this Study.") + full_name = models.CharField(max_length=255, help_text="The full name for this Study.") history = HistoricalRecords() diff --git a/primed/primed_anvil/tables.py b/primed/primed_anvil/tables.py index 24534216..092f88fe 100644 --- a/primed/primed_anvil/tables.py +++ b/primed/primed_anvil/tables.py @@ -7,7 +7,6 @@ class BooleanIconColumn(tables.BooleanColumn): - # attrs = {"td": {"align": "center"}} # attrs = {"th": {"class": "center"}} @@ -53,9 +52,7 @@ def _get_bool_value(self, record, value, bound_column): # Check if it is a workspace if not isinstance(record, Workspace): raise ImproperlyConfigured("record must be a Workspace") - is_shared = record.workspacegroupsharing_set.filter( - group__name="PRIMED_ALL" - ).exists() + is_shared = record.workspacegroupsharing_set.filter(group__name="PRIMED_ALL").exists() return is_shared @@ -146,18 +143,11 @@ class Meta: class DataSummaryTable(tables.Table): - study = tables.Column() access_mechanism = tables.Column() - is_shared = tables.BooleanColumn( - verbose_name="Status", yesno="Shared,Preparing data" - ) + is_shared = tables.BooleanColumn(verbose_name="Status", yesno="Shared,Preparing data") def __init__(self, *args, **kwargs): - available_data_types = models.AvailableData.objects.values_list( - "name", flat=True - ) - extra_columns = [ - (x, BooleanIconColumn(default=False)) for x in available_data_types - ] + available_data_types = models.AvailableData.objects.values_list("name", flat=True) + extra_columns = [(x, BooleanIconColumn(default=False)) for x in available_data_types] super().__init__(*args, extra_columns=extra_columns, **kwargs) diff --git a/primed/primed_anvil/tests/test_adapters.py b/primed/primed_anvil/tests/test_adapters.py index b08c0551..515b4b10 100644 --- a/primed/primed_anvil/tests/test_adapters.py +++ b/primed/primed_anvil/tests/test_adapters.py @@ -30,16 +30,10 @@ def test_get_autocomplete_label_no_linked_user(self): def test_autocomplete_queryset_matches_user_name(self): """get_autocomplete_label returns correct account when user name matches.""" user_1 = UserFactory.create(name="First Last") - account_1 = AccountFactory.create( - email="test1@test.com", user=user_1, verified=True - ) + account_1 = AccountFactory.create(email="test1@test.com", user=user_1, verified=True) user_2 = UserFactory.create(name="Foo Bar") - account_2 = AccountFactory.create( - email="test2@test.com", user=user_2, verified=True - ) - queryset = adapters.AccountAdapter().get_autocomplete_queryset( - Account.objects.all(), "last" - ) + account_2 = AccountFactory.create(email="test2@test.com", user=user_2, verified=True) + queryset = adapters.AccountAdapter().get_autocomplete_queryset(Account.objects.all(), "last") self.assertEqual(len(queryset), 1) self.assertIn(account_1, queryset) self.assertNotIn(account_2, queryset) @@ -47,16 +41,10 @@ def test_autocomplete_queryset_matches_user_name(self): def test_autocomplete_queryset_matches_account_email(self): """get_autocomplete_label returns correct account when user email matches.""" user_1 = UserFactory.create(name="First Last") - account_1 = AccountFactory.create( - email="test1@test.com", user=user_1, verified=True - ) + account_1 = AccountFactory.create(email="test1@test.com", user=user_1, verified=True) user_2 = UserFactory.create(name="Foo Bar") - account_2 = AccountFactory.create( - email="username@domain.com", user=user_2, verified=True - ) - queryset = adapters.AccountAdapter().get_autocomplete_queryset( - Account.objects.all(), "test" - ) + account_2 = AccountFactory.create(email="username@domain.com", user=user_2, verified=True) + queryset = adapters.AccountAdapter().get_autocomplete_queryset(Account.objects.all(), "test") self.assertEqual(len(queryset), 1) self.assertIn(account_1, queryset) self.assertNotIn(account_2, queryset) @@ -65,9 +53,7 @@ def test_autocomplete_queryset_no_linked_user(self): """get_autocomplete_label returns correct account when user name matches.""" account_1 = AccountFactory.create(email="foo@bar.com") account_2 = AccountFactory.create(email="test@test.com") - queryset = adapters.AccountAdapter().get_autocomplete_queryset( - Account.objects.all(), "bar" - ) + queryset = adapters.AccountAdapter().get_autocomplete_queryset(Account.objects.all(), "bar") self.assertEqual(len(queryset), 1) self.assertIn(account_1, queryset) self.assertNotIn(account_2, queryset) diff --git a/primed/primed_anvil/tests/test_audit.py b/primed/primed_anvil/tests/test_audit.py index fb34965d..897d5db8 100644 --- a/primed/primed_anvil/tests/test_audit.py +++ b/primed/primed_anvil/tests/test_audit.py @@ -1,4 +1,5 @@ """Tests for the `audit.py` module.""" + from dataclasses import dataclass from unittest import TestCase @@ -9,7 +10,6 @@ @dataclass class TempAuditResult(audit.PRIMEDAuditResult): - value: str def get_table_dictionary(self): diff --git a/primed/primed_anvil/tests/test_helpers.py b/primed/primed_anvil/tests/test_helpers.py index a5bf54f1..a7ab68e8 100644 --- a/primed/primed_anvil/tests/test_helpers.py +++ b/primed/primed_anvil/tests/test_helpers.py @@ -126,9 +126,7 @@ def test_one_dbgap_workspace_one_study_shared_no_available_data(self): AvailableDataFactory.create(name="Foo") study = StudyFactory.create(short_name="TEST") workspace = dbGaPWorkspaceFactory.create(dbgap_study_accession__studies=[study]) - WorkspaceGroupSharingFactory.create( - workspace=workspace.workspace, group__name="PRIMED_ALL" - ) + WorkspaceGroupSharingFactory.create(workspace=workspace.workspace, group__name="PRIMED_ALL") res = helpers.get_summary_table_data() self.assertEqual(len(res), 1) self.assertEqual(len(res[0]), 4) @@ -164,16 +162,10 @@ def test_two_dbgap_workspaces_one_study_one_shared(self): available_data_1 = AvailableDataFactory.create(name="Foo") available_data_2 = AvailableDataFactory.create(name="Bar") study = StudyFactory.create(short_name="TEST") - workspace_1 = dbGaPWorkspaceFactory.create( - dbgap_study_accession__studies=[study] - ) + workspace_1 = dbGaPWorkspaceFactory.create(dbgap_study_accession__studies=[study]) workspace_1.available_data.add(available_data_1) - WorkspaceGroupSharingFactory.create( - workspace=workspace_1.workspace, group__name="PRIMED_ALL" - ) - workspace_2 = dbGaPWorkspaceFactory.create( - dbgap_study_accession__studies=[study] - ) + WorkspaceGroupSharingFactory.create(workspace=workspace_1.workspace, group__name="PRIMED_ALL") + workspace_2 = dbGaPWorkspaceFactory.create(dbgap_study_accession__studies=[study]) workspace_2.available_data.add(available_data_2) res = helpers.get_summary_table_data() self.assertEqual(len(res), 2) @@ -371,9 +363,7 @@ def test_one_cdsa_workspace_one_study_shared_no_available_data(self): AvailableDataFactory.create(name="Foo") study = StudyFactory.create(short_name="TEST") workspace = CDSAWorkspaceFactory.create(study=study) - WorkspaceGroupSharingFactory.create( - workspace=workspace.workspace, group__name="PRIMED_ALL" - ) + WorkspaceGroupSharingFactory.create(workspace=workspace.workspace, group__name="PRIMED_ALL") res = helpers.get_summary_table_data() self.assertEqual(len(res), 1) self.assertEqual(len(res[0]), 4) @@ -411,9 +401,7 @@ def test_two_cdsa_workspaces_one_study_one_shared(self): study = StudyFactory.create(short_name="TEST") workspace_1 = CDSAWorkspaceFactory.create(study=study) workspace_1.available_data.add(available_data_1) - WorkspaceGroupSharingFactory.create( - workspace=workspace_1.workspace, group__name="PRIMED_ALL" - ) + WorkspaceGroupSharingFactory.create(workspace=workspace_1.workspace, group__name="PRIMED_ALL") workspace_2 = CDSAWorkspaceFactory.create(study=study) workspace_2.available_data.add(available_data_2) res = helpers.get_summary_table_data() @@ -580,9 +568,7 @@ def test_one_dbgap_workspace_shared_one_study(self): workspace__name="test-ws", dbgap_study_accession__studies=[study], ) - WorkspaceGroupSharingFactory.create( - workspace=workspace.workspace, group=self.primed_all_group - ) + WorkspaceGroupSharingFactory.create(workspace=workspace.workspace, group=self.primed_all_group) res = helpers.get_workspaces_for_phenotype_inventory() self.assertEqual(len(res), 1) self.assertIn("test-bp/test-ws", res) @@ -598,9 +584,7 @@ def test_one_dbgap_workspace_shared_two_studies(self): workspace__name="test-ws", dbgap_study_accession=study_accession, ) - WorkspaceGroupSharingFactory.create( - workspace=workspace.workspace, group=self.primed_all_group - ) + WorkspaceGroupSharingFactory.create(workspace=workspace.workspace, group=self.primed_all_group) res = helpers.get_workspaces_for_phenotype_inventory() self.assertEqual(len(res), 1) self.assertIn("test-bp/test-ws", res) @@ -614,18 +598,14 @@ def test_two_dbgap_workspaces(self): workspace__name="test-ws-1", dbgap_study_accession__studies=[study_1], ) - WorkspaceGroupSharingFactory.create( - workspace=workspace_1.workspace, group=self.primed_all_group - ) + WorkspaceGroupSharingFactory.create(workspace=workspace_1.workspace, group=self.primed_all_group) study_2 = StudyFactory.create(short_name="TEST 2") workspace_2 = dbGaPWorkspaceFactory.create( workspace__billing_project__name="test-bp-2", workspace__name="test-ws-2", dbgap_study_accession__studies=[study_2], ) - WorkspaceGroupSharingFactory.create( - workspace=workspace_2.workspace, group=self.primed_all_group - ) + WorkspaceGroupSharingFactory.create(workspace=workspace_2.workspace, group=self.primed_all_group) res = helpers.get_workspaces_for_phenotype_inventory() self.assertEqual(len(res), 2) self.assertIn("test-bp-1/test-ws-1", res) @@ -647,9 +627,7 @@ def test_one_cdsa_workspace_shared_one_study(self): workspace__name="test-ws", study=study, ) - WorkspaceGroupSharingFactory.create( - workspace=workspace.workspace, group=self.primed_all_group - ) + WorkspaceGroupSharingFactory.create(workspace=workspace.workspace, group=self.primed_all_group) res = helpers.get_workspaces_for_phenotype_inventory() self.assertEqual(len(res), 1) self.assertIn("test-bp/test-ws", res) @@ -663,18 +641,14 @@ def test_two_cdsa_workspaces(self): workspace__name="test-ws-1", study=study_1, ) - WorkspaceGroupSharingFactory.create( - workspace=workspace_1.workspace, group=self.primed_all_group - ) + WorkspaceGroupSharingFactory.create(workspace=workspace_1.workspace, group=self.primed_all_group) study_2 = StudyFactory.create(short_name="TEST 2") workspace_2 = CDSAWorkspaceFactory.create( workspace__billing_project__name="test-bp-2", workspace__name="test-ws-2", study=study_2, ) - WorkspaceGroupSharingFactory.create( - workspace=workspace_2.workspace, group=self.primed_all_group - ) + WorkspaceGroupSharingFactory.create(workspace=workspace_2.workspace, group=self.primed_all_group) res = helpers.get_workspaces_for_phenotype_inventory() self.assertEqual(len(res), 2) self.assertIn("test-bp-1/test-ws-1", res) @@ -694,9 +668,7 @@ def test_one_open_access_workspace_shared_no_study(self): workspace__billing_project__name="test-bp", workspace__name="test-ws", ) - WorkspaceGroupSharingFactory.create( - workspace=workspace.workspace, group=self.primed_all_group - ) + WorkspaceGroupSharingFactory.create(workspace=workspace.workspace, group=self.primed_all_group) res = helpers.get_workspaces_for_phenotype_inventory() self.assertEqual(len(res), 1) self.assertIn("test-bp/test-ws", res) @@ -710,9 +682,7 @@ def test_one_open_access_workspace_shared_one_study(self): workspace__name="test-ws", ) workspace.studies.add(study) - WorkspaceGroupSharingFactory.create( - workspace=workspace.workspace, group=self.primed_all_group - ) + WorkspaceGroupSharingFactory.create(workspace=workspace.workspace, group=self.primed_all_group) res = helpers.get_workspaces_for_phenotype_inventory() self.assertEqual(len(res), 1) self.assertIn("test-bp/test-ws", res) @@ -727,9 +697,7 @@ def test_one_open_access_workspace_shared_two_studies(self): workspace__name="test-ws", ) workspace.studies.add(study_1, study_2) - WorkspaceGroupSharingFactory.create( - workspace=workspace.workspace, group=self.primed_all_group - ) + WorkspaceGroupSharingFactory.create(workspace=workspace.workspace, group=self.primed_all_group) res = helpers.get_workspaces_for_phenotype_inventory() self.assertEqual(len(res), 1) self.assertIn("test-bp/test-ws", res) @@ -741,18 +709,14 @@ def test_two_open_access_workspaces(self): workspace__billing_project__name="test-bp-1", workspace__name="test-ws-1", ) - WorkspaceGroupSharingFactory.create( - workspace=workspace_1.workspace, group=self.primed_all_group - ) + WorkspaceGroupSharingFactory.create(workspace=workspace_1.workspace, group=self.primed_all_group) study_2 = StudyFactory.create(short_name="TEST 2") workspace_2 = OpenAccessWorkspaceFactory.create( workspace__billing_project__name="test-bp-2", workspace__name="test-ws-2", ) workspace_2.studies.add(study_2) - WorkspaceGroupSharingFactory.create( - workspace=workspace_2.workspace, group=self.primed_all_group - ) + WorkspaceGroupSharingFactory.create(workspace=workspace_2.workspace, group=self.primed_all_group) res = helpers.get_workspaces_for_phenotype_inventory() self.assertEqual(len(res), 2) self.assertIn("test-bp-1/test-ws-1", res) @@ -768,27 +732,21 @@ def test_multiple_workspace_types_same_study(self): workspace__name="test-ws-dbgap", dbgap_study_accession__studies=[study], ) - WorkspaceGroupSharingFactory.create( - workspace=workspace.workspace, group=self.primed_all_group - ) + WorkspaceGroupSharingFactory.create(workspace=workspace.workspace, group=self.primed_all_group) # CDSA workspace = CDSAWorkspaceFactory.create( workspace__billing_project__name="test-bp-cdsa", workspace__name="test-ws-cdsa", study=study, ) - WorkspaceGroupSharingFactory.create( - workspace=workspace.workspace, group=self.primed_all_group - ) + WorkspaceGroupSharingFactory.create(workspace=workspace.workspace, group=self.primed_all_group) # Open access workspace = OpenAccessWorkspaceFactory.create( workspace__billing_project__name="test-bp-open", workspace__name="test-ws-open", ) workspace.studies.add(study) - WorkspaceGroupSharingFactory.create( - workspace=workspace.workspace, group=self.primed_all_group - ) + WorkspaceGroupSharingFactory.create(workspace=workspace.workspace, group=self.primed_all_group) res = helpers.get_workspaces_for_phenotype_inventory() self.assertEqual(len(res), 3) self.assertIn("test-bp-dbgap/test-ws-dbgap", res) @@ -806,9 +764,7 @@ def test_multiple_workspace_types_separate_studies(self): workspace__name="test-ws-dbgap", dbgap_study_accession__studies=[study_1], ) - WorkspaceGroupSharingFactory.create( - workspace=workspace.workspace, group=self.primed_all_group - ) + WorkspaceGroupSharingFactory.create(workspace=workspace.workspace, group=self.primed_all_group) # CDSA study_2 = StudyFactory.create(short_name="TEST 2") workspace = CDSAWorkspaceFactory.create( @@ -816,9 +772,7 @@ def test_multiple_workspace_types_separate_studies(self): workspace__name="test-ws-cdsa", study=study_2, ) - WorkspaceGroupSharingFactory.create( - workspace=workspace.workspace, group=self.primed_all_group - ) + WorkspaceGroupSharingFactory.create(workspace=workspace.workspace, group=self.primed_all_group) # Open access study_3 = StudyFactory.create(short_name="TEST 3") workspace = OpenAccessWorkspaceFactory.create( @@ -826,9 +780,7 @@ def test_multiple_workspace_types_separate_studies(self): workspace__name="test-ws-open", ) workspace.studies.add(study_3) - WorkspaceGroupSharingFactory.create( - workspace=workspace.workspace, group=self.primed_all_group - ) + WorkspaceGroupSharingFactory.create(workspace=workspace.workspace, group=self.primed_all_group) res = helpers.get_workspaces_for_phenotype_inventory() self.assertEqual(len(res), 3) self.assertIn("test-bp-dbgap/test-ws-dbgap", res) diff --git a/primed/primed_anvil/tests/test_models.py b/primed/primed_anvil/tests/test_models.py index 93eb829f..b4f249c6 100644 --- a/primed/primed_anvil/tests/test_models.py +++ b/primed/primed_anvil/tests/test_models.py @@ -32,16 +32,12 @@ def test_get_absolute_url(self): def test_unique_short_name(self): """Saving a model with a duplicate short name fails.""" factories.StudyFactory.create(short_name="FOO") - instance2 = factories.StudyFactory.build( - short_name="FOO", full_name="full name" - ) + instance2 = factories.StudyFactory.build(short_name="FOO", full_name="full name") with self.assertRaises(ValidationError) as e: instance2.full_clean() self.assertIn("short_name", e.exception.error_dict) self.assertEqual(len(e.exception.error_dict["short_name"]), 1) - self.assertIn( - "already exists", e.exception.error_dict["short_name"][0].messages[0] - ) + self.assertIn("already exists", e.exception.error_dict["short_name"][0].messages[0]) with self.assertRaises(IntegrityError): instance2.save() diff --git a/primed/primed_anvil/tests/test_tables.py b/primed/primed_anvil/tests/test_tables.py index 60431ffa..c25c9092 100644 --- a/primed/primed_anvil/tests/test_tables.py +++ b/primed/primed_anvil/tests/test_tables.py @@ -145,7 +145,6 @@ def test_ordering(self): class DataSummaryTableTest(TestCase): - table_class = tables.DataSummaryTable def test_row_count_with_no_objects(self): @@ -233,9 +232,7 @@ def test_render_is_not_shared(self): def test_render_is_shared(self): workspace = WorkspaceFactory.create() - WorkspaceGroupSharingFactory.create( - workspace=workspace, group__name="PRIMED_ALL" - ) + WorkspaceGroupSharingFactory.create(workspace=workspace, group__name="PRIMED_ALL") column = tables.WorkspaceSharedWithConsortiumColumn() value = column.render(None, workspace, None) self.assertIn("bi-check-circle-fill", value) diff --git a/primed/primed_anvil/tests/test_views.py b/primed/primed_anvil/tests/test_views.py index b800b6df..e28f43bc 100644 --- a/primed/primed_anvil/tests/test_views.py +++ b/primed/primed_anvil/tests/test_views.py @@ -55,9 +55,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -67,9 +65,7 @@ def get_url(self, *args): def test_staff_view_links(self): user = UserFactory.create() user.user_permissions.add( - Permission.objects.get( - codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.client.force_login(user) response = self.client.get(self.get_url()) @@ -78,14 +74,10 @@ def test_staff_view_links(self): def test_staff_edit_links(self): user = UserFactory.create() user.user_permissions.add( - Permission.objects.get( - codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) user.user_permissions.add( - Permission.objects.get( - codename=acm_models.AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) self.client.force_login(user) response = self.client.get(self.get_url()) @@ -102,9 +94,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -115,9 +105,7 @@ def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." # Need a client for redirects. response = self.client.get(self.get_url()) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url() - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url()) def test_status_code_logged_in(self): """Returns successful response code.""" @@ -134,45 +122,33 @@ def test_user_has_not_linked_account(self): self.client.force_login(self.user) AccountFactory.create(user=self.user, verified=True) response = self.client.get(self.get_url()) - self.assertNotContains( - response, reverse("anvil_consortium_manager:accounts:link") - ) + self.assertNotContains(response, reverse("anvil_consortium_manager:accounts:link")) def test_unauthenticated_user_has_not_linked_account_message(self): response = self.client.get(settings.LOGIN_URL, follow=True) - self.assertNotContains( - response, reverse("anvil_consortium_manager:accounts:link") - ) + self.assertNotContains(response, reverse("anvil_consortium_manager:accounts:link")) def test_staff_view_links(self): user = UserFactory.create() user.user_permissions.add( - Permission.objects.get( - codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.client.force_login(user) response = self.client.get(self.get_url()) # Note: we need quotes around the link because anvil/accounts/link does appear in the response, # so we can't test if "anvil/" is in the response. We need to test if '"anvil/"' is in the response. - self.assertContains( - response, '"{}"'.format(reverse("anvil_consortium_manager:index")) - ) + self.assertContains(response, '"{}"'.format(reverse("anvil_consortium_manager:index"))) def test_view_links(self): user = UserFactory.create() user.user_permissions.add( - Permission.objects.get( - codename=acm_models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.client.force_login(user) response = self.client.get(self.get_url()) # Note: we need quotes around the link because anvil/accounts/link does appear in the response, # so we can't test if "anvil/" is in the response. We need to test if '"anvil/"' is in the response. - self.assertNotContains( - response, '"{}"'.format(reverse("anvil_consortium_manager:index")) - ) + self.assertNotContains(response, '"{}"'.format(reverse("anvil_consortium_manager:index"))) def test_site_announcement_no_text(self): self.client.force_login(self.user) @@ -203,9 +179,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -220,9 +194,7 @@ def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." # Need a client for redirects. response = self.client.get(self.get_url(1)) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(1) - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(1)) def test_status_code_with_user_permission(self): """Returns successful response code.""" @@ -234,9 +206,7 @@ def test_status_code_with_user_permission(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url(1)) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -255,9 +225,7 @@ def test_status_code_with_limited_view_permission(self): obj = self.model_factory.create() user = User.objects.create_user(username="test-2", password="test-2") user.user_permissions.add( - Permission.objects.get( - codename=acm_models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.client.force_login(user) response = self.client.get(self.get_url(obj.pk)) @@ -273,9 +241,7 @@ def test_content_view_permission(self): obj = self.model_factory.create() user = User.objects.create_user(username="test-2", password="test-2") user.user_permissions.add( - Permission.objects.get( - codename=acm_models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.client.force_login(user) response = self.client.get(self.get_url(obj.pk)) @@ -286,45 +252,29 @@ def test_table_classes_view_permission(self): self.client.force_login(self.user) response = self.client.get(self.get_url(obj.pk)) self.assertIn("tables", response.context_data) - self.assertIsInstance( - response.context_data["tables"][0], dbGaPWorkspaceStaffTable - ) - self.assertIsInstance( - response.context_data["tables"][1], CDSAWorkspaceStaffTable - ) - self.assertIsInstance( - response.context_data["tables"][3], OpenAccessWorkspaceStaffTable - ) + self.assertIsInstance(response.context_data["tables"][0], dbGaPWorkspaceStaffTable) + self.assertIsInstance(response.context_data["tables"][1], CDSAWorkspaceStaffTable) + self.assertIsInstance(response.context_data["tables"][3], OpenAccessWorkspaceStaffTable) def test_table_classes_limited_view_permission(self): """Table classes are correct when the user has limited view permission.""" user = User.objects.create_user(username="test-2", password="test-2") user.user_permissions.add( - Permission.objects.get( - codename=acm_models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) obj = self.model_factory.create() self.client.force_login(user) response = self.client.get(self.get_url(obj.pk)) self.assertIn("tables", response.context_data) - self.assertIsInstance( - response.context_data["tables"][0], dbGaPWorkspaceUserTable - ) - self.assertIsInstance( - response.context_data["tables"][1], CDSAWorkspaceUserTable - ) - self.assertIsInstance( - response.context_data["tables"][3], OpenAccessWorkspaceUserTable - ) + self.assertIsInstance(response.context_data["tables"][0], dbGaPWorkspaceUserTable) + self.assertIsInstance(response.context_data["tables"][1], CDSAWorkspaceUserTable) + self.assertIsInstance(response.context_data["tables"][3], OpenAccessWorkspaceUserTable) def test_dbgap_workspace_table(self): """Contains a table of dbGaPWorkspaces with the correct studies.""" obj = self.model_factory.create() dbgap_study_accession = dbGaPStudyAccessionFactory.create(studies=[obj]) - dbgap_workspace = dbGaPWorkspaceFactory.create( - dbgap_study_accession=dbgap_study_accession - ) + dbgap_workspace = dbGaPWorkspaceFactory.create(dbgap_study_accession=dbgap_study_accession) other_workspace = dbGaPWorkspaceFactory.create() self.client.force_login(self.user) response = self.client.get(self.get_url(obj.pk)) @@ -378,9 +328,7 @@ def setUp(self): # Create a user with the correct permissions. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -395,9 +343,7 @@ def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." # Need a client for redirects. response = self.client.get(self.get_url()) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url() - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url()) def test_status_code_with_user_permission(self): """Returns successful response code.""" @@ -408,9 +354,7 @@ def test_status_code_with_user_permission(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url()) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -422,139 +366,92 @@ def test_returns_all_objects(self): request = self.factory.get(self.get_url()) request.user = self.user response = self.get_view()(request) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + returned_ids = [int(x["id"]) for x in json.loads(response.content.decode("utf-8"))["results"]] self.assertEqual(len(returned_ids), 10) - self.assertEqual( - sorted(returned_ids), sorted([object.pk for object in objects]) - ) + self.assertEqual(sorted(returned_ids), sorted([object.pk for object in objects])) def test_returns_correct_object_match_short_name(self): """Queryset returns the correct objects when query matches the short_name.""" - object = factories.StudyFactory.create( - short_name="test", full_name="other study" - ) + object = factories.StudyFactory.create(short_name="test", full_name="other study") request = self.factory.get(self.get_url(), {"q": "test"}) request.user = self.user response = self.get_view()(request) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + returned_ids = [int(x["id"]) for x in json.loads(response.content.decode("utf-8"))["results"]] self.assertEqual(len(returned_ids), 1) self.assertEqual(returned_ids[0], object.pk) def test_returns_correct_object_starting_with_query_short_name(self): """Queryset returns the correct objects when query matches the beginning of the short_name.""" - object = factories.StudyFactory.create( - short_name="test", full_name="other study" - ) + object = factories.StudyFactory.create(short_name="test", full_name="other study") request = self.factory.get(self.get_url(), {"q": "test"}) request.user = self.user response = self.get_view()(request) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + returned_ids = [int(x["id"]) for x in json.loads(response.content.decode("utf-8"))["results"]] self.assertEqual(len(returned_ids), 1) self.assertEqual(returned_ids[0], object.pk) def test_returns_correct_object_containing_query_short_name(self): """Queryset returns the correct objects when the short_name contains the query.""" - object = factories.StudyFactory.create( - short_name="test", full_name="other study" - ) + object = factories.StudyFactory.create(short_name="test", full_name="other study") request = self.factory.get(self.get_url(), {"q": "es"}) request.user = self.user response = self.get_view()(request) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + returned_ids = [int(x["id"]) for x in json.loads(response.content.decode("utf-8"))["results"]] self.assertEqual(len(returned_ids), 1) self.assertEqual(returned_ids[0], object.pk) def test_returns_correct_object_case_insensitive_short_name(self): """Queryset returns the correct objects when query matches the beginning of the short_name.""" - object = factories.StudyFactory.create( - short_name="TEST", full_name="other study" - ) + object = factories.StudyFactory.create(short_name="TEST", full_name="other study") request = self.factory.get(self.get_url(), {"q": "test"}) request.user = self.user response = self.get_view()(request) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + returned_ids = [int(x["id"]) for x in json.loads(response.content.decode("utf-8"))["results"]] self.assertEqual(len(returned_ids), 1) self.assertEqual(returned_ids[0], object.pk) def test_returns_correct_object_match_full_name(self): """Queryset returns the correct objects when query matches the full_name.""" - object = factories.StudyFactory.create( - short_name="other", full_name="test study" - ) + object = factories.StudyFactory.create(short_name="other", full_name="test study") request = self.factory.get(self.get_url(), {"q": "test study"}) request.user = self.user response = self.get_view()(request) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + returned_ids = [int(x["id"]) for x in json.loads(response.content.decode("utf-8"))["results"]] self.assertEqual(len(returned_ids), 1) self.assertEqual(returned_ids[0], object.pk) def test_returns_correct_object_starting_with_query_full_name(self): """Queryset returns the correct objects when query matches the beginning of the full_name.""" - object = factories.StudyFactory.create( - short_name="other", full_name="test study" - ) + object = factories.StudyFactory.create(short_name="other", full_name="test study") request = self.factory.get(self.get_url(), {"q": "test"}) request.user = self.user response = self.get_view()(request) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + returned_ids = [int(x["id"]) for x in json.loads(response.content.decode("utf-8"))["results"]] self.assertEqual(len(returned_ids), 1) self.assertEqual(returned_ids[0], object.pk) def test_returns_correct_object_containing_query_full_name(self): """Queryset returns the correct objects when the full_name contains the query.""" - object = factories.StudyFactory.create( - short_name="other", full_name="test study" - ) + object = factories.StudyFactory.create(short_name="other", full_name="test study") request = self.factory.get(self.get_url(), {"q": "stu"}) request.user = self.user response = self.get_view()(request) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + returned_ids = [int(x["id"]) for x in json.loads(response.content.decode("utf-8"))["results"]] self.assertEqual(len(returned_ids), 1) self.assertEqual(returned_ids[0], object.pk) def test_returns_correct_object_case_insensitive_full_name(self): """Queryset returns the correct objects when query matches the beginning of the full_name.""" - object = factories.StudyFactory.create( - short_name="other", full_name="TEST STUDY" - ) + object = factories.StudyFactory.create(short_name="other", full_name="TEST STUDY") request = self.factory.get(self.get_url(), {"q": "test study"}) request.user = self.user response = self.get_view()(request) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + returned_ids = [int(x["id"]) for x in json.loads(response.content.decode("utf-8"))["results"]] self.assertEqual(len(returned_ids), 1) self.assertEqual(returned_ids[0], object.pk) def test_get_result_label(self): - instance = factories.StudyFactory.create( - full_name="Test Name", short_name="TEST" - ) + instance = factories.StudyFactory.create(full_name="Test Name", short_name="TEST") request = self.factory.get(self.get_url()) request.user = self.user view = views.StudyAutocomplete() @@ -562,9 +459,7 @@ def test_get_result_label(self): self.assertEqual(view.get_result_label(instance), "Test Name (TEST)") def test_get_selected_result_label(self): - instance = factories.StudyFactory.create( - full_name="Test Name", short_name="TEST" - ) + instance = factories.StudyFactory.create(full_name="Test Name", short_name="TEST") request = self.factory.get(self.get_url()) request.user = self.user view = views.StudyAutocomplete() @@ -582,14 +477,10 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=acm_models.AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.STAFF_EDIT_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -604,9 +495,7 @@ def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." # Need a client for redirects. response = self.client.get(self.get_url()) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url() - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url()) def test_status_code_with_user_permission_edit(self): """Returns successful response code.""" @@ -617,9 +506,7 @@ def test_status_code_with_user_permission_edit(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url()) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -627,13 +514,9 @@ def test_access_without_user_permission(self): def test_access_without_user_permission_view(self): """Raises permission denied if user has no permissions.""" - user_view_perm = User.objects.create_user( - username="test-none", password="test-none" - ) + user_view_perm = User.objects.create_user(username="test-none", password="test-none") user_view_perm.user_permissions.add( - Permission.objects.get( - codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user_view_perm @@ -650,9 +533,7 @@ def test_has_form_in_context(self): def test_can_create_object(self): """Can create an object.""" self.client.force_login(self.user) - response = self.client.post( - self.get_url(), {"short_name": "TEST", "full_name": "Test study"} - ) + response = self.client.post(self.get_url(), {"short_name": "TEST", "full_name": "Test study"}) self.assertEqual(response.status_code, 302) # A new object was created. self.assertEqual(models.Study.objects.count(), 1) @@ -663,9 +544,7 @@ def test_can_create_object(self): def test_redirect_url(self): """Redirects to successful url.""" self.client.force_login(self.user) - response = self.client.post( - self.get_url(), {"short_name": "TEST", "full_name": "Test study"} - ) + response = self.client.post(self.get_url(), {"short_name": "TEST", "full_name": "Test study"}) new_object = models.Study.objects.latest("pk") self.assertRedirects(response, new_object.get_absolute_url()) @@ -718,9 +597,7 @@ def test_error_duplicate_short_name(self): """Form shows an error when trying to create a duplicate short name.""" factories.StudyFactory.create(short_name="TEST", full_name="Test study") self.client.force_login(self.user) - response = self.client.post( - self.get_url(), {"short_name": "TEST", "full_name": "Test study 2"} - ) + response = self.client.post(self.get_url(), {"short_name": "TEST", "full_name": "Test study 2"}) self.assertEqual(response.status_code, 200) # No new objects were created. self.assertEqual(models.Study.objects.count(), 1) @@ -760,9 +637,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) def get_url(self): @@ -777,9 +652,7 @@ def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." # Need a client for redirects. response = self.client.get(self.get_url()) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url() - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url()) def test_view_render(self): obj = self.model_factory.create() @@ -800,9 +673,7 @@ def test_status_code_with_limited_view_permission(self): """Returns successful response code.""" user = User.objects.create_user(username="test-2", password="test-2") user.user_permissions.add( - Permission.objects.get( - codename=acm_models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.client.force_login(user) response = self.client.get(self.get_url()) @@ -810,9 +681,7 @@ def test_status_code_with_limited_view_permission(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url()) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -866,9 +735,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -883,9 +750,7 @@ def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." # Need a client for redirects. response = self.client.get(self.get_url(1)) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(1) - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(1)) def test_view_render(self): obj = self.model_factory.create() @@ -904,9 +769,7 @@ def test_status_code_with_user_permission(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url(1)) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -971,9 +834,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) def get_url(self): @@ -988,9 +849,7 @@ def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." # Need a client for redirects. response = self.client.get(self.get_url()) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url() - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url()) def test_view_render(self): obj = self.model_factory.create() @@ -1009,9 +868,7 @@ def test_status_code_with_user_permission(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url()) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -1065,9 +922,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) def get_url(self): @@ -1122,9 +977,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -1139,9 +992,7 @@ def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." # Need a client for redirects. response = self.client.get(self.get_url(1)) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(1) - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(1)) def test_status_code_with_user_permission(self): """Returns successful response code.""" @@ -1153,9 +1004,7 @@ def test_status_code_with_user_permission(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url(1)) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -1208,9 +1057,7 @@ def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." # Need a client for redirects. response = self.client.get(self.get_url()) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url() - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url()) def test_status_code_with_authenticated_user(self): """Returns successful response code.""" @@ -1224,9 +1071,7 @@ def test_table_class(self): self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertIn("summary_table", response.context_data) - self.assertIsInstance( - response.context_data["summary_table"], tables.DataSummaryTable - ) + self.assertIsInstance(response.context_data["summary_table"], tables.DataSummaryTable) def test_table_rows(self): """A summary table exists.""" @@ -1282,9 +1127,7 @@ def setUp(self): # Create a user with both view and edit permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) self.primed_all = ManagedGroupFactory.create(name="PRIMED_ALL") @@ -1300,15 +1143,11 @@ def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." # Need a client for redirects. response = self.client.get(self.get_url()) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url() - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url()) def test_status_code_with_authenticated_user(self): """Redirects to login view when user has no perms.""" - user_no_perms = User.objects.create_user( - username="test-none", password="test-none" - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") request = self.factory.get(self.get_url()) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -1318,9 +1157,7 @@ def test_status_code_with_view_user(self): """Redirects to login view when user has view perm.""" user = User.objects.create_user(username="test-none", password="test-none") user.user_permissions.add( - Permission.objects.get( - codename=acm_models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=acm_models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -1339,9 +1176,7 @@ def test_context_workspaces_input_one_workspace(self): workspace = OpenAccessWorkspaceFactory.create( workspace__billing_project__name="test-bp", workspace__name="test-ws" ) - WorkspaceGroupSharingFactory.create( - workspace=workspace.workspace, group=self.primed_all - ) + WorkspaceGroupSharingFactory.create(workspace=workspace.workspace, group=self.primed_all) self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertIn("workspaces_input", response.context_data) diff --git a/primed/primed_anvil/views.py b/primed/primed_anvil/views.py index f85e787b..844f0160 100644 --- a/primed/primed_anvil/views.py +++ b/primed/primed_anvil/views.py @@ -53,14 +53,10 @@ class StudyDetail(AnVILConsortiumManagerViewRequired, MultiTableMixin, DetailVie # context_table_name = "dbgap_workspace_table" def get_tables(self): - dbgap_qs = Workspace.objects.filter( - dbgapworkspace__dbgap_study_accession__studies=self.object - ) + dbgap_qs = Workspace.objects.filter(dbgapworkspace__dbgap_study_accession__studies=self.object) cdsa_qs = Workspace.objects.filter(cdsaworkspace__study=self.object) agreement_qs = DataAffiliateAgreement.objects.filter(study=self.object) - open_access_qs = Workspace.objects.filter( - openaccessworkspace__studies=self.object - ) + open_access_qs = Workspace.objects.filter(openaccessworkspace__studies=self.object) # Check permissions to determine table type. apm_content_type = ContentType.objects.get_for_model(AnVILProjectManagerAccess) full_view_perm = f"{apm_content_type.app_label}.{AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME}" @@ -88,9 +84,7 @@ class StudyList(AnVILConsortiumManagerViewRequired, SingleTableView): table_class = tables.StudyTable -class StudyCreate( - AnVILConsortiumManagerStaffEditRequired, SuccessMessageMixin, CreateView -): +class StudyCreate(AnVILConsortiumManagerStaffEditRequired, SuccessMessageMixin, CreateView): """View to create a new `Study`.""" model = models.Study @@ -101,9 +95,7 @@ def get_success_url(self): return self.object.get_absolute_url() -class StudyAutocomplete( - AnVILConsortiumManagerStaffViewRequired, autocomplete.Select2QuerySetView -): +class StudyAutocomplete(AnVILConsortiumManagerStaffViewRequired, autocomplete.Select2QuerySetView): """View to provide autocompletion for `Study`s. Match either the `short_name` or `full_name`.""" def get_result_label(self, result): @@ -118,16 +110,12 @@ def get_queryset(self): qs = models.Study.objects.order_by("short_name") if self.q: - qs = qs.filter( - Q(short_name__icontains=self.q) | Q(full_name__icontains=self.q) - ) + qs = qs.filter(Q(short_name__icontains=self.q) | Q(full_name__icontains=self.q)) return qs -class StudySiteDetail( - AnVILConsortiumManagerStaffViewRequired, MultiTableMixin, DetailView -): +class StudySiteDetail(AnVILConsortiumManagerStaffViewRequired, MultiTableMixin, DetailView): """View to show details about a `StudySite`.""" model = models.StudySite @@ -141,9 +129,7 @@ class StudySiteDetail( # return UserTable(User.objects.filter(study_sites=self.object)) def get_tables_data(self): user_qs = User.objects.filter(study_sites=self.object) - dbgap_qs = dbGaPApplication.objects.filter( - principal_investigator__study_sites=self.object - ) + dbgap_qs = dbGaPApplication.objects.filter(principal_investigator__study_sites=self.object) cdsa_qs = MemberAgreement.objects.filter(study_site=self.object) return [user_qs, dbgap_qs, cdsa_qs] @@ -162,9 +148,7 @@ class AvailableDataList(AnVILConsortiumManagerStaffViewRequired, SingleTableView table_class = tables.AvailableDataTable -class AvailableDataDetail( - AnVILConsortiumManagerStaffViewRequired, SingleTableMixin, DetailView -): +class AvailableDataDetail(AnVILConsortiumManagerStaffViewRequired, SingleTableMixin, DetailView): """View to show details about a `AvailableData`.""" model = models.AvailableData @@ -177,7 +161,6 @@ def get_table_data(self): class DataSummaryView(LoginRequiredMixin, TemplateView): - template_name = "primed_anvil/data_summary.html" def get_context_data(self, **kwargs): @@ -187,15 +170,10 @@ def get_context_data(self, **kwargs): return context -class PhenotypeInventoryInputsView( - AnVILConsortiumManagerStaffViewRequired, TemplateView -): - +class PhenotypeInventoryInputsView(AnVILConsortiumManagerStaffViewRequired, TemplateView): template_name = "primed_anvil/phenotype_inventory_inputs.html" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context["workspaces_input"] = json.dumps( - helpers.get_workspaces_for_phenotype_inventory(), indent=2 - ) + context["workspaces_input"] = json.dumps(helpers.get_workspaces_for_phenotype_inventory(), indent=2) return context diff --git a/primed/users/adapters.py b/primed/users/adapters.py index 24e6d91e..a2b33115 100644 --- a/primed/users/adapters.py +++ b/primed/users/adapters.py @@ -32,8 +32,7 @@ def update_user_info(self, user, extra_data: Dict, apply_update=True): user_changed = False if user.name != full_name: logger.info( - f"[SocialAccountAdatpter:update_user_name] user {user} " - f"name updated from {user.name} to {full_name}" + f"[SocialAccountAdatpter:update_user_name] user {user} " f"name updated from {user.name} to {full_name}" ) user.name = full_name user_changed = True @@ -63,9 +62,7 @@ def update_user_study_sites(self, user, extra_data: Dict, apply_update=True): user_sites_updated = False if research_center_or_site: if not isinstance(research_center_or_site, list): - raise ImproperlyConfigured( - "sociallogin.extra_data.study_site_or_center should be a list" - ) + raise ImproperlyConfigured("sociallogin.extra_data.study_site_or_center should be a list") for rc_name in research_center_or_site: try: rc = StudySite.objects.get(short_name=rc_name) @@ -106,14 +103,10 @@ def update_user_groups(self, user, extra_data: Dict): added_groups = [] removed_groups = [] if not isinstance(managed_scope_status, dict): - raise ImproperlyConfigured( - "sociallogin.extra_data.managed_scope_status should be a dict" - ) + raise ImproperlyConfigured("sociallogin.extra_data.managed_scope_status should be a dict") else: for group_name, user_has_group in managed_scope_status.items(): - user_group, was_created = Group.objects.get_or_create( - name=group_name - ) + user_group, was_created = Group.objects.get_or_create(name=group_name) if was_created: logger.debug( f"[SocialAccountAdatpter:update_user_data] created mapped user group: {group_name}" @@ -134,7 +127,6 @@ def update_user_groups(self, user, extra_data: Dict): ) def update_user_data(self, sociallogin: Any): - logger.debug( f"[SocialAccountAdatpter:update_user_data] account: {sociallogin.account} " f"extra_data {sociallogin.account.extra_data} " diff --git a/primed/users/admin.py b/primed/users/admin.py index 7d71a538..ee8da869 100644 --- a/primed/users/admin.py +++ b/primed/users/admin.py @@ -10,7 +10,6 @@ @admin.register(User) class UserAdmin(auth_admin.UserAdmin): - form = UserChangeForm add_form = UserCreationForm fieldsets = ( diff --git a/primed/users/audit.py b/primed/users/audit.py index 371d7760..c81fd479 100644 --- a/primed/users/audit.py +++ b/primed/users/audit.py @@ -69,9 +69,7 @@ def get_table_dictionary(self): if self.remote_user_data: row.update( { - "remote_user_id": self.remote_user_data.attributes.get( - "drupal_internal__uid" - ), + "remote_user_id": self.remote_user_data.attributes.get("drupal_internal__uid"), "remote_username": self.remote_user_data.attributes.get("name"), } ) @@ -140,42 +138,29 @@ def _run_audit(self): user_count = 0 while user_endpoint_url is not None: - users_endpoint = json_api.endpoint(user_endpoint_url) users_endpoint_response = users_endpoint.get() # If there are more, there will be a 'next' link - user_endpoint_url = users_endpoint_response.content.links.get( - "next", {} - ).get("href") + user_endpoint_url = users_endpoint_response.content.links.get("next", {}).get("href") for user in users_endpoint_response.data: drupal_uid = user.attributes.get("drupal_internal__uid") drupal_username = user.attributes.get("name") drupal_email = user.attributes.get("mail") drupal_firstname = user.attributes.get("field_given_first_name_s_") - drupal_lastname = user.attributes.get( - "field_examples_family_last_name_" - ) - drupal_full_name = " ".join( - part for part in (drupal_firstname, drupal_lastname) if part - ) - drupal_study_sites_rel = user.relationships.get( - "field_study_site_or_center" - ) + drupal_lastname = user.attributes.get("field_examples_family_last_name_") + drupal_full_name = " ".join(part for part in (drupal_firstname, drupal_lastname) if part) + drupal_study_sites_rel = user.relationships.get("field_study_site_or_center") drupal_user_study_site_shortnames = [] if drupal_study_sites_rel: for dss in drupal_study_sites_rel.data: study_site_uuid = dss.id study_site_info = study_sites[study_site_uuid] - drupal_user_study_site_shortnames.append( - study_site_info["short_name"] - ) - new_user_sites = StudySite.objects.filter( - short_name__in=drupal_user_study_site_shortnames - ) + drupal_user_study_site_shortnames.append(study_site_info["short_name"]) + new_user_sites = StudySite.objects.filter(short_name__in=drupal_user_study_site_shortnames) # no uid is blocked or anonymous if not drupal_uid: # potential blocked user, but will no longer have a drupal uid @@ -201,16 +186,12 @@ def _run_audit(self): uid=user.attributes["drupal_internal__uid"], provider=CustomProvider.id, ) - self.needs_action.append( - NewUser(local_user=sa, remote_user_data=user) - ) + self.needs_action.append(NewUser(local_user=sa, remote_user_data=user)) if sa: user_updates = {} if sa.user.name != drupal_full_name: - user_updates.update( - {"name": {"old": sa.user.name, "new": drupal_full_name}} - ) + user_updates.update({"name": {"old": sa.user.name, "new": drupal_full_name}}) sa.user.name = drupal_full_name if sa.user.username != drupal_username: user_updates.update( @@ -223,21 +204,16 @@ def _run_audit(self): ) sa.user.username = drupal_username if sa.user.email != drupal_email: - user_updates.update( - {"email": {"old": sa.user.email, "new": drupal_email}} - ) + user_updates.update({"email": {"old": sa.user.email, "new": drupal_email}}) sa.user.email = drupal_email if sa.user.is_active is False: user_updates.update({"is_active": {"old": False, "new": True}}) sa.user.is_active = True - prev_user_site_names = set( - sa.user.study_sites.all().values_list("short_name", flat=True) - ) + prev_user_site_names = set(sa.user.study_sites.all().values_list("short_name", flat=True)) new_user_site_names = set(drupal_user_study_site_shortnames) if prev_user_site_names != new_user_site_names: - user_updates.update( { "sites": { @@ -247,9 +223,7 @@ def _run_audit(self): } ) # do not remove from sites by default - removed_sites = prev_user_site_names.difference( - new_user_site_names - ) + removed_sites = prev_user_site_names.difference(new_user_site_names) new_sites = new_user_site_names.difference(prev_user_site_names) if settings.DRUPAL_DATA_AUDIT_REMOVE_USER_SITES is True: @@ -282,9 +256,7 @@ def _run_audit(self): ) ) else: - self.verified.append( - VerifiedUser(local_user=sa, remote_user_data=user) - ) + self.verified.append(VerifiedUser(local_user=sa, remote_user_data=user)) drupal_uids.add(drupal_uid) user_count += 1 @@ -314,9 +286,7 @@ def _run_audit(self): handled = True self.needs_action.append(RemoveUser(local_user=uda)) if handled is False: - self.errors.append( - RemoveUser(local_user=uda, note=f"Over Threshold {over_threshold}") - ) + self.errors.append(RemoveUser(local_user=uda, note=f"Over Threshold {over_threshold}")) inactive_anvil_users = Account.objects.filter( Q(user__is_active=False) | Q(user__id__in=user_ids_to_check), @@ -327,9 +297,7 @@ def _run_audit(self): InactiveAnvilUser( anvil_account=inactive_anvil_user, anvil_groups=list( - inactive_anvil_user.groupaccountmembership_set.all().values_list( - "group__name", flat=True - ) + inactive_anvil_user.groupaccountmembership_set.all().values_list("group__name", flat=True) ), ) ) @@ -419,7 +387,6 @@ def _run_audit(self): json_api = get_drupal_json_api() study_sites = get_study_sites(json_api=json_api) for study_site_info in study_sites.values(): - short_name = study_site_info["short_name"] full_name = study_site_info["full_name"] node_id = study_site_info["node_id"] @@ -435,16 +402,12 @@ def _run_audit(self): short_name=short_name, full_name=full_name, ) - self.needs_action.append( - NewSite(remote_site_data=study_site_info, local_site=study_site) - ) + self.needs_action.append(NewSite(remote_site_data=study_site_info, local_site=study_site)) else: study_site_updates = {} if study_site.full_name != full_name: - study_site_updates.update( - {"full_name": {"old": study_site.full_name, "new": full_name}} - ) + study_site_updates.update({"full_name": {"old": study_site.full_name, "new": full_name}}) study_site.full_name = full_name if study_site.short_name != short_name: @@ -469,22 +432,15 @@ def _run_audit(self): ) ) else: - self.verified.append( - VerifiedSite( - local_site=study_site, remote_site_data=study_site_info - ) - ) + self.verified.append(VerifiedSite(local_site=study_site, remote_site_data=study_site_info)) invalid_study_sites = StudySite.objects.exclude(drupal_node_id__in=valid_nodes) for iss in invalid_study_sites: - self.errors.append( - RemoveSite(local_site=iss, note=self.ISSUE_TYPE_LOCAL_SITE_INVALID) - ) + self.errors.append(RemoveSite(local_site=iss, note=self.ISSUE_TYPE_LOCAL_SITE_INVALID)) def get_drupal_json_api(): - json_api_client_id = settings.DRUPAL_API_CLIENT_ID json_api_client_secret = settings.DRUPAL_API_CLIENT_SECRET diff --git a/primed/users/forms.py b/primed/users/forms.py index 5076a427..2ea6f0a3 100644 --- a/primed/users/forms.py +++ b/primed/users/forms.py @@ -17,9 +17,7 @@ class UserCreationForm(admin_forms.UserCreationForm): class Meta(admin_forms.UserCreationForm.Meta): model = User - error_messages = { - "username": {"unique": _("This username has already been taken.")} - } + error_messages = {"username": {"unique": _("This username has already been taken.")}} class UserLookupForm(Bootstrap5MediaFormMixin, forms.Form): diff --git a/primed/users/tests/factories.py b/primed/users/tests/factories.py index 6a0e0384..b99e1fc9 100644 --- a/primed/users/tests/factories.py +++ b/primed/users/tests/factories.py @@ -7,7 +7,6 @@ class UserFactory(DjangoModelFactory): - username = Faker("user_name") email = Faker("email") name = Faker("name") diff --git a/primed/users/tests/test_adapters.py b/primed/users/tests/test_adapters.py index c5c24a83..cae571dc 100644 --- a/primed/users/tests/test_adapters.py +++ b/primed/users/tests/test_adapters.py @@ -53,9 +53,7 @@ def test_drupal_social_login_adapter(self): sociallogin = SocialLogin(user=user, account=account) complete_social_login(request, sociallogin) - user = User.objects.get( - **{account_settings.USER_MODEL_USERNAME_FIELD: old_username} - ) + user = User.objects.get(**{account_settings.USER_MODEL_USERNAME_FIELD: old_username}) assert SocialAccount.objects.filter(user=user, uid=account.uid).exists() is True assert user.name == old_name assert user.username == old_username @@ -101,9 +99,7 @@ def test_update_user_study_sites_add(self): user.save() - adapter.update_user_study_sites( - user, dict(study_site_or_center=[rc1.short_name]) - ) + adapter.update_user_study_sites(user, dict(study_site_or_center=[rc1.short_name])) assert user.study_sites.filter(pk=rc1.pk).exists() assert user.study_sites.all().count() == 1 @@ -121,9 +117,7 @@ def test_update_user_study_sites_remove(self): user.study_sites.add(rc1, rc2) assert user.study_sites.all().count() == 2 - adapter.update_user_study_sites( - user, dict(study_site_or_center=[rc1.short_name]) - ) + adapter.update_user_study_sites(user, dict(study_site_or_center=[rc1.short_name])) assert user.study_sites.filter(pk=rc1.pk).exists() assert user.study_sites.all().count() == 1 @@ -135,10 +129,7 @@ def test_update_user_study_sites_unknown(self, settings): adapter.update_user_study_sites(user, dict(study_site_or_center=["UNKNOWN"])) assert user.study_sites.all().count() == 0 assert len(mail.outbox) == 1 - assert ( - mail.outbox[0].subject - == f"{settings.EMAIL_SUBJECT_PREFIX}Missing StudySite" - ) + assert mail.outbox[0].subject == f"{settings.EMAIL_SUBJECT_PREFIX}Missing StudySite" def test_update_study_sites_malformed(self): adapter = SocialAccountAdapter() @@ -157,9 +148,7 @@ def test_update_user_groups_add(self): user.save() - adapter.update_user_groups( - user, extra_data=dict(managed_scope_status={rc1.name: True}) - ) + adapter.update_user_groups(user, extra_data=dict(managed_scope_status={rc1.name: True})) assert user.groups.filter(pk=rc1.pk).exists() assert user.groups.all().count() == 1 @@ -173,9 +162,7 @@ def test_update_user_groups_add_new(self): user.save() new_group_name = "NEW_GROUP" - adapter.update_user_groups( - user, extra_data=dict(managed_scope_status={new_group_name: True}) - ) + adapter.update_user_groups(user, extra_data=dict(managed_scope_status={new_group_name: True})) assert user.groups.filter(name=new_group_name).exists() assert user.groups.all().count() == 1 diff --git a/primed/users/tests/test_audit.py b/primed/users/tests/test_audit.py index 155d114e..412618f2 100644 --- a/primed/users/tests/test_audit.py +++ b/primed/users/tests/test_audit.py @@ -162,13 +162,9 @@ def add_fake_study_sites_response(self): ) def add_fake_users_response(self): - url_path = ( - f"{settings.DRUPAL_SITE_URL}/{settings.DRUPAL_API_REL_PATH}/user/user/" - ) + url_path = f"{settings.DRUPAL_SITE_URL}/{settings.DRUPAL_API_REL_PATH}/user/user/" TEST_USER_DATA[0].field_study_site_or_center = [TEST_STUDY_SITE_DATA[0]] - user_data = UserSchema( - include_data=("field_study_site_or_center",), many=True - ).dump(TEST_USER_DATA) + user_data = UserSchema(include_data=("field_study_site_or_center",), many=True).dump(TEST_USER_DATA) responses.get( url=url_path, @@ -186,10 +182,7 @@ def get_fake_json_api(self): @responses.activate def test_get_json_api(self): json_api = self.get_fake_json_api() - assert ( - json_api.requests.config.AUTH._client.token["access_token"] - == self.token["access_token"] - ) + assert json_api.requests.config.AUTH._client.token["access_token"] == self.token["access_token"] @responses.activate def test_get_study_sites(self): @@ -198,19 +191,9 @@ def test_get_study_sites(self): study_sites = audit.get_study_sites(json_api=json_api) for test_study_site in TEST_STUDY_SITE_DATA: - - assert ( - test_study_site.field_long_name - == study_sites[test_study_site.drupal_internal__nid]["full_name"] - ) - assert ( - test_study_site.title - == study_sites[test_study_site.drupal_internal__nid]["short_name"] - ) - assert ( - test_study_site.drupal_internal__nid - == study_sites[test_study_site.drupal_internal__nid]["node_id"] - ) + assert test_study_site.field_long_name == study_sites[test_study_site.drupal_internal__nid]["full_name"] + assert test_study_site.title == study_sites[test_study_site.drupal_internal__nid]["short_name"] + assert test_study_site.drupal_internal__nid == study_sites[test_study_site.drupal_internal__nid]["node_id"] @responses.activate def test_audit_study_sites_no_update(self): @@ -273,9 +256,7 @@ def test_audit_study_sites_with_site_update(self): @responses.activate def test_audit_study_sites_with_extra_site(self): - StudySite.objects.create( - drupal_node_id=99, short_name="ExtraSite", full_name="ExtraSiteLong" - ) + StudySite.objects.create(drupal_node_id=99, short_name="ExtraSite", full_name="ExtraSiteLong") self.get_fake_json_api() self.add_fake_study_sites_response() site_audit = audit.SiteAudit(apply_changes=True) @@ -307,10 +288,7 @@ def test_full_user_audit(self): assert users.first().email == TEST_USER_DATA[0].mail assert users.first().username == TEST_USER_DATA[0].name assert users.first().study_sites.count() == 1 - assert ( - users.first().study_sites.first().short_name - == TEST_STUDY_SITE_DATA[0].title - ) + assert users.first().study_sites.first().short_name == TEST_STUDY_SITE_DATA[0].title @responses.activate def test_full_user_audit_check_only(self): @@ -449,9 +427,7 @@ def test_user_audit_remove_user_only_inform(self): full_name=TEST_STUDY_SITE_DATA[0].field_long_name, ) - new_user = get_user_model().objects.create( - username="username2", email="useremail2", name="user fullname2" - ) + new_user = get_user_model().objects.create(username="username2", email="useremail2", name="user fullname2") SocialAccount.objects.create( user=new_user, uid=999, @@ -476,9 +452,7 @@ def test_user_audit_remove_user(self): full_name=TEST_STUDY_SITE_DATA[0].field_long_name, ) - new_user = get_user_model().objects.create( - username="username2", email="useremail2", name="user fullname2" - ) + new_user = get_user_model().objects.create(username="username2", email="useremail2", name="user fullname2") SocialAccount.objects.create( user=new_user, uid=999, @@ -504,9 +478,7 @@ def test_user_audit_remove_user(self): self.assertFalse(user_audit.ok()) self.assertEqual(len(user_audit.errors), 1) self.assertEqual(user_audit.errors[0].anvil_account, new_anvil_account) - self.assertIn( - "InactiveAnvilUser", user_audit.get_errors_table().render_to_text() - ) + self.assertIn("InactiveAnvilUser", user_audit.get_errors_table().render_to_text()) self.assertEqual(len(user_audit.needs_action), 2) new_user.refresh_from_db() self.assertFalse(new_user.is_active) @@ -524,32 +496,24 @@ def test_user_audit_remove_user_threshold(self): ) SocialAccount.objects.create( - user=get_user_model().objects.create( - username="username2", email="useremail2", name="user fullname2" - ), + user=get_user_model().objects.create(username="username2", email="useremail2", name="user fullname2"), uid=996, provider=CustomProvider.id, ) SocialAccount.objects.create( - user=get_user_model().objects.create( - username="username3", email="useremail3", name="user fullname3" - ), + user=get_user_model().objects.create(username="username3", email="useremail3", name="user fullname3"), uid=997, provider=CustomProvider.id, ) SocialAccount.objects.create( - user=get_user_model().objects.create( - username="username4", email="useremail4", name="user fullname4" - ), + user=get_user_model().objects.create(username="username4", email="useremail4", name="user fullname4"), uid=998, provider=CustomProvider.id, ) SocialAccount.objects.create( - user=get_user_model().objects.create( - username="username5", email="useremail5", name="user fullname5" - ), + user=get_user_model().objects.create(username="username5", email="useremail5", name="user fullname5"), uid=999, provider=CustomProvider.id, ) @@ -561,9 +525,7 @@ def test_user_audit_remove_user_threshold(self): self.assertEqual(len(user_audit.needs_action), 1) self.assertEqual(user_audit.errors[0].note, "Over Threshold True") # Run again with ignore threshold, should move from error to needs action - user_audit = audit.UserAudit( - apply_changes=False, ignore_deactivate_threshold=True - ) + user_audit = audit.UserAudit(apply_changes=False, ignore_deactivate_threshold=True) user_audit.run_audit() self.assertFalse(user_audit.ok()) self.assertEqual(len(user_audit.errors), 0) @@ -583,16 +545,13 @@ def test_sync_drupal_data_command(self): @responses.activate def test_sync_drupal_data_command_with_issues(self): - StudySite.objects.create( drupal_node_id="999999", short_name=TEST_STUDY_SITE_DATA[0].title, full_name=TEST_STUDY_SITE_DATA[0].field_long_name, ) - new_user = get_user_model().objects.create( - username="username2", email="useremail2", name="user fullname2" - ) + new_user = get_user_model().objects.create(username="username2", email="useremail2", name="user fullname2") SocialAccount.objects.create( user=new_user, uid=999, diff --git a/primed/users/tests/test_forms.py b/primed/users/tests/test_forms.py index 8e34e7bb..81fe9d9b 100644 --- a/primed/users/tests/test_forms.py +++ b/primed/users/tests/test_forms.py @@ -1,6 +1,7 @@ """ Module for all Form Tests. """ + import pytest from django.test import TestCase from django.utils.translation import gettext_lazy as _ @@ -42,7 +43,6 @@ def test_username_validation_error_msg(self, user: User): class UserLookupFormTest(TestCase): - form_class = UserLookupForm def test_valid(self): diff --git a/primed/users/tests/test_urls.py b/primed/users/tests/test_urls.py index 9d224344..4ed608c7 100644 --- a/primed/users/tests/test_urls.py +++ b/primed/users/tests/test_urls.py @@ -7,10 +7,7 @@ def test_detail(user: User): - assert ( - reverse("users:detail", kwargs={"username": user.username}) - == f"/users/{user.username}/" - ) + assert reverse("users:detail", kwargs={"username": user.username}) == f"/users/{user.username}/" assert resolve(f"/users/{user.username}/").view_name == "users:detail" diff --git a/primed/users/tests/test_views.py b/primed/users/tests/test_views.py index 8fcced81..b4785706 100644 --- a/primed/users/tests/test_views.py +++ b/primed/users/tests/test_views.py @@ -113,14 +113,10 @@ def test_authenticated(self, client, user: User, rf: RequestFactory): assert response.status_code == 200 - def test_authenticated_with_verified_account( - self, client, user: User, rf: RequestFactory - ): + def test_authenticated_with_verified_account(self, client, user: User, rf: RequestFactory): client.force_login(user) user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) AccountFactory.create(email="foo@bar.com", user=user, verified=True) user_detail_url = reverse("users:detail", kwargs=dict(username=user.username)) @@ -128,14 +124,10 @@ def test_authenticated_with_verified_account( assert response.status_code == 200 - def test_authenticated_with_user_email_entry( - self, client, user: User, rf: RequestFactory - ): + def test_authenticated_with_user_email_entry(self, client, user: User, rf: RequestFactory): client.force_login(user) user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) UserEmailEntryFactory.create(email="foo@bar.com", user=user) user_detail_url = reverse("users:detail", kwargs=dict(username=user.username)) @@ -143,9 +135,7 @@ def test_authenticated_with_user_email_entry( assert response.status_code == 200 - def test_authenticated_with_unverified_account( - self, client, user: User, rf: RequestFactory - ): + def test_authenticated_with_unverified_account(self, client, user: User, rf: RequestFactory): client.force_login(user) AccountFactory.create(email="foo@bar.com", user=user, verified=False) user_detail_url = reverse("users:detail", kwargs=dict(username=user.username)) @@ -153,9 +143,7 @@ def test_authenticated_with_unverified_account( assert response.status_code == 200 - def test_authenticated_with_study_sites( - self, client, user: User, rf: RequestFactory - ): + def test_authenticated_with_study_sites(self, client, user: User, rf: RequestFactory): client.force_login(user) study_site = StudySiteFactory.create() user.study_sites.add(study_site) @@ -177,9 +165,7 @@ def test_not_authenticated(self, user: User, rf: RequestFactory): def test_staff_view_links(self, client, user: User, rf: RequestFactory): """Link to ACM account page is in response for users with STAFF_VIEW permission.""" user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=AnVILProjectManagerAccess.STAFF_VIEW_PERMISSION_CODENAME) ) client.force_login(user) account = AccountFactory.create(email="foo@bar.com", user=user, verified=True) @@ -189,11 +175,7 @@ def test_staff_view_links(self, client, user: User, rf: RequestFactory): def test_view_links(self, client, user: User, rf: RequestFactory): """Link to ACM account page is not in response for users with VIEW permission.""" - user.user_permissions.add( - Permission.objects.get( - codename=AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) - ) + user.user_permissions.add(Permission.objects.get(codename=AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME)) client.force_login(user) account = AccountFactory.create(email="foo@bar.com", user=user, verified=True) user_detail_url = reverse("users:detail", kwargs=dict(username=user.username)) @@ -220,9 +202,7 @@ def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." # Need a client for redirects. response = self.client.get(self.get_url()) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url() - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url()) def test_status_code_with_user_permission(self): """Returns successful response code.""" @@ -237,10 +217,7 @@ def test_returns_all_instances(self): request = self.factory.get(self.get_url()) request.user = self.user response = self.get_view()(request) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + returned_ids = [int(x["id"]) for x in json.loads(response.content.decode("utf-8"))["results"]] # The test user plus the ones we created in this test. self.assertEqual(len(returned_ids), 10) self.assertEqual( @@ -255,10 +232,7 @@ def test_returns_correct_instance_match_name(self): request = self.factory.get(self.get_url(), {"q": "First Last"}) request.user = self.user response = self.get_view()(request) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + returned_ids = [int(x["id"]) for x in json.loads(response.content.decode("utf-8"))["results"]] self.assertEqual(len(returned_ids), 1) self.assertEqual(returned_ids[0], instance.pk) @@ -269,10 +243,7 @@ def test_returns_correct_instance_starting_with_query_name(self): request = self.factory.get(self.get_url(), {"q": "Firs"}) request.user = self.user response = self.get_view()(request) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + returned_ids = [int(x["id"]) for x in json.loads(response.content.decode("utf-8"))["results"]] self.assertEqual(len(returned_ids), 1) self.assertEqual(returned_ids[0], instance.pk) @@ -283,10 +254,7 @@ def test_returns_correct_instance_containing_query_short_name(self): request = self.factory.get(self.get_url(), {"q": "ast"}) request.user = self.user response = self.get_view()(request) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + returned_ids = [int(x["id"]) for x in json.loads(response.content.decode("utf-8"))["results"]] self.assertEqual(len(returned_ids), 1) self.assertEqual(returned_ids[0], instance.pk) @@ -297,10 +265,7 @@ def test_returns_correct_instance_case_insensitive_name(self): request = self.factory.get(self.get_url(), {"q": "first last"}) request.user = self.user response = self.get_view()(request) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + returned_ids = [int(x["id"]) for x in json.loads(response.content.decode("utf-8"))["results"]] self.assertEqual(len(returned_ids), 1) self.assertEqual(returned_ids[0], instance.pk) @@ -311,10 +276,7 @@ def test_returns_correct_instance_match_email(self): request = self.factory.get(self.get_url(), {"q": "foo@bar.com"}) request.user = self.user response = self.get_view()(request) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + returned_ids = [int(x["id"]) for x in json.loads(response.content.decode("utf-8"))["results"]] self.assertEqual(len(returned_ids), 1) self.assertEqual(returned_ids[0], instance.pk) @@ -325,10 +287,7 @@ def test_returns_correct_instance_starting_with_query_email(self): request = self.factory.get(self.get_url(), {"q": "foo"}) request.user = self.user response = self.get_view()(request) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + returned_ids = [int(x["id"]) for x in json.loads(response.content.decode("utf-8"))["results"]] self.assertEqual(len(returned_ids), 1) self.assertEqual(returned_ids[0], instance.pk) @@ -339,10 +298,7 @@ def test_returns_correct_instance_containing_query_email(self): request = self.factory.get(self.get_url(), {"q": "bar"}) request.user = self.user response = self.get_view()(request) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + returned_ids = [int(x["id"]) for x in json.loads(response.content.decode("utf-8"))["results"]] self.assertEqual(len(returned_ids), 1) self.assertEqual(returned_ids[0], instance.pk) @@ -353,10 +309,7 @@ def test_returns_correct_instance_case_insensitive_email(self): request = self.factory.get(self.get_url(), {"q": "FOO@BAR.COM"}) request.user = self.user response = self.get_view()(request) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + returned_ids = [int(x["id"]) for x in json.loads(response.content.decode("utf-8"))["results"]] self.assertEqual(len(returned_ids), 1) self.assertEqual(returned_ids[0], instance.pk) @@ -376,9 +329,7 @@ def test_get_selected_result_label(self): request.user = self.user view = UserAutocompleteView() view.setup(request) - self.assertEqual( - view.get_selected_result_label(instance), "First Last (foo@bar.com)" - ) + self.assertEqual(view.get_selected_result_label(instance), "First Last (foo@bar.com)") class UserLookup(TestCase): @@ -405,9 +356,7 @@ def test_form_class(self): def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." response = self.client.get(self.get_url()) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url() - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url()) def test_status_code_with_user_permission(self): """Returns successful response code.""" diff --git a/primed/users/views.py b/primed/users/views.py index 07133ef7..881fc2ba 100644 --- a/primed/users/views.py +++ b/primed/users/views.py @@ -13,7 +13,6 @@ class UserDetailView(LoginRequiredMixin, DetailView): - model = User slug_field = "username" slug_url_kwarg = "username" @@ -23,7 +22,6 @@ class UserDetailView(LoginRequiredMixin, DetailView): class UserUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView): - model = User fields = ["name"] success_message = _("Information successfully updated") @@ -39,7 +37,6 @@ def get_object(self): class UserRedirectView(LoginRequiredMixin, RedirectView): - permanent = False def get_redirect_url(self): From 0a077847788383fd8619acfe0d5bbe7cfd04ebcf Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Mon, 29 Apr 2024 15:38:49 -0700 Subject: [PATCH 5/6] Replace black/isort/flake8 with ruff in pre-commit config --- .pre-commit-config.yaml | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3b9bd274..38956395 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,22 +10,15 @@ repos: - id: end-of-file-fixer - id: check-yaml - - repo: https://github.com/psf/black - rev: 22.3.0 + - repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.4.2 hooks: - - id: black - - - repo: https://github.com/timothycrosley/isort - rev: 5.12.0 - hooks: - - id: isort - - - repo: https://github.com/PyCQA/flake8 - rev: 7.0.0 - hooks: - - id: flake8 - args: ['--config=setup.cfg'] - additional_dependencies: [flake8-isort] + # Run the linter. + - id: ruff + args: [ --fix ] + # Run the formatter. + - id: ruff-format - repo: https://github.com/gitleaks/gitleaks rev: v8.16.1 From 3dfbbc6d8f82988d348ac7875fc50cdc18701595 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Mon, 29 Apr 2024 15:55:09 -0700 Subject: [PATCH 6/6] Remove flake8, isort, and black from requirements file --- requirements/dev-requirements.in | 8 +++--- requirements/dev-requirements.txt | 44 ------------------------------- 2 files changed, 4 insertions(+), 48 deletions(-) diff --git a/requirements/dev-requirements.in b/requirements/dev-requirements.in index 37e02e6e..79a043ec 100644 --- a/requirements/dev-requirements.in +++ b/requirements/dev-requirements.in @@ -17,10 +17,10 @@ sphinx-autobuild # https://github.com/GaretJax/sphinx-autobuild # Code quality # ------------------------------------------------------------------------------ -flake8 # https://github.com/PyCQA/flake8 -flake8-isort # https://github.com/gforcada/flake8-isort -black # https://github.com/psf/black -pylint-django # https://github.com/PyCQA/pylint-django +# flake8 # https://github.com/PyCQA/flake8 +# flake8-isort # https://github.com/gforcada/flake8-isort +# black # https://github.com/psf/black +# pylint-django # https://github.com/PyCQA/pylint-django pre-commit # https://github.com/pre-commit/pre-commit ruff # https://github.com/astral-sh/ruff diff --git a/requirements/dev-requirements.txt b/requirements/dev-requirements.txt index 133d6577..08c17266 100644 --- a/requirements/dev-requirements.txt +++ b/requirements/dev-requirements.txt @@ -10,8 +10,6 @@ asgiref==3.7.2 # via # -c requirements.txt # django -astroid==3.0.3 - # via pylint asttokens==2.4.1 # via stack-data babel==2.14.0 @@ -22,8 +20,6 @@ backports-zoneinfo==0.2.1 # via # -c requirements.txt # django -black==22.12.0 - # via -r dev-requirements.in certifi==2023.11.17 # via # -c requirements.txt @@ -39,15 +35,12 @@ charset-normalizer==3.3.2 click==8.1.3 # via # -c requirements.txt - # black colorama==0.4.6 # via sphinx-autobuild decorator==5.1.1 # via # ipdb # ipython -dill==0.3.8 - # via pylint distlib==0.3.8 # via virtualenv django==4.2.11 @@ -68,12 +61,6 @@ executing==2.0.1 # via stack-data filelock==3.13.1 # via virtualenv -flake8==7.0.0 - # via - # -r dev-requirements.in - # flake8-isort -flake8-isort==6.1.1 - # via -r dev-requirements.in identify==2.5.34 # via pre-commit idna==3.3 @@ -91,10 +78,6 @@ ipdb==0.13.13 # via -r dev-requirements.in ipython==8.12.3 # via ipdb -isort==5.13.2 - # via - # flake8-isort - # pylint jedi==0.19.1 # via ipython jinja2==3.1.3 @@ -107,15 +90,10 @@ markupsafe==2.1.5 # werkzeug matplotlib-inline==0.1.6 # via ipython -mccabe==0.7.0 - # via - # flake8 - # pylint mypy==1.9.0 # via -r dev-requirements.in mypy-extensions==1.0.0 # via - # black # mypy nodeenv==1.8.0 # via pre-commit @@ -126,16 +104,12 @@ packaging==21.3 # sphinx parso==0.8.3 # via jedi -pathspec==0.12.1 - # via black pexpect==4.9.0 # via ipython pickleshare==0.7.5 # via ipython platformdirs==4.1.0 # via - # black - # pylint # virtualenv pre-commit==3.5.0 # via -r dev-requirements.in @@ -145,22 +119,10 @@ ptyprocess==0.7.0 # via pexpect pure-eval==0.2.2 # via stack-data -pycodestyle==2.11.1 - # via flake8 -pyflakes==3.2.0 - # via flake8 pygments==2.17.2 # via # ipython # sphinx -pylint==3.0.3 - # via - # pylint-django - # pylint-plugin-utils -pylint-django==2.5.5 - # via -r dev-requirements.in -pylint-plugin-utils==0.8.2 - # via pylint-django pyparsing==3.1.1 # via # -c requirements.txt @@ -218,13 +180,9 @@ tomli==2.0.1 # via # -c requirements.txt # -c test-requirements.txt - # black # django-stubs # ipdb # mypy - # pylint -tomlkit==0.12.3 - # via pylint tornado==6.4 # via livereload traitlets==5.14.1 @@ -243,12 +201,10 @@ typing-extensions==4.8.0 # -c test-requirements.txt # asgiref # astroid - # black # django-stubs # django-stubs-ext # ipython # mypy - # pylint urllib3==2.1.0 # via # -c requirements.txt