From 37efead329a80af1699792a538447c89e62ee9f4 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Mon, 30 Oct 2023 15:51:45 -0700 Subject: [PATCH 01/14] Move project metadata to pyproject.toml --- pyproject.toml | 22 ++++++++++++++++++++++ setup.cfg | 48 ++++++++++++++++++++++++------------------------ 2 files changed, 46 insertions(+), 24 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 947f620f..2dcf0e08 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,25 @@ [build-system] requires = ['setuptools>=40.8.0', 'wheel'] build-backend = "setuptools.build_meta" + +[project] +name = "django-anvil-consortium-manager" +# Version needs to be updated such that the canonical version is only stored in one place. +version = "0.19" +authors = [ + {name="Adrienne Stilp", email="amstilp@uw.edu"}, +] +description = "A Django app to manage Consortium AnVIL groups, workspaces, and access." +readme = "README.md" +requires-python = ">=3.7" +classifiers = [ + "Framework :: Django", + "Development Status :: 4 - Beta", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3", +] + +[project.urls] +"Homepage" = "https://github.com/UW-GAC/django-anvil-consortium-manager" +"Bug Tracker" = "https://github.com/UW-GAC/django-anvil-consortium-manager/issues" diff --git a/setup.cfg b/setup.cfg index 1699276c..0d0b74c7 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,27 +1,27 @@ -[metadata] -name = django-anvil-consortium-manager -version = attr: anvil_consortium_manager.__version__ -description = A Django app to manage Consortium AnVIL groups, workspaces, and access. -long_description = file: README.md -url = https://github.com/UW-GAC/django-anvil-consortium-manager -author = Adrienne Stilp -author_email = amstilp@uw.edu -license = MIT -classifiers = - Environment :: Web Environment - Framework :: Django - Framework :: Django :: 3.2 - Intended Audience :: Developers - License :: OSI Approved :: MIT License - Operating System :: OS Independent - Programming Language :: Python - Programming Language :: Python :: 3 - Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.10 - Topic :: Internet :: WWW/HTTP - Topic :: Internet :: WWW/HTTP :: Dynamic Content +# [metadata] +# name = django-anvil-consortium-manager +# version = attr: anvil_consortium_manager.__version__ +# description = A Django app to manage Consortium AnVIL groups, workspaces, and access. +# long_description = file: README.md +# url = https://github.com/UW-GAC/django-anvil-consortium-manager +# author = Adrienne Stilp +# author_email = amstilp@uw.edu +# license = MIT +# classifiers = +# Environment :: Web Environment +# Framework :: Django +# Framework :: Django :: 3.2 +# Intended Audience :: Developers +# License :: OSI Approved :: MIT License +# Operating System :: OS Independent +# Programming Language :: Python +# Programming Language :: Python :: 3 +# Programming Language :: Python :: 3 :: Only +# Programming Language :: Python :: 3.8 +# Programming Language :: Python :: 3.9 +# Programming Language :: Python :: 3.10 +# Topic :: Internet :: WWW/HTTP +# Topic :: Internet :: WWW/HTTP :: Dynamic Content [options] include_package_data = true From ad36a133c178fa3c63908117af93ad30952e12d7 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Mon, 30 Oct 2023 16:02:14 -0700 Subject: [PATCH 02/14] Change required python version to match setup.cfg --- pyproject.toml | 2 +- setup.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 2dcf0e08..1c3d9603 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ authors = [ ] description = "A Django app to manage Consortium AnVIL groups, workspaces, and access." readme = "README.md" -requires-python = ">=3.7" +requires-python = ">=3.8" classifiers = [ "Framework :: Django", "Development Status :: 4 - Beta", diff --git a/setup.cfg b/setup.cfg index 0d0b74c7..0c5b5d86 100644 --- a/setup.cfg +++ b/setup.cfg @@ -26,7 +26,7 @@ [options] include_package_data = true packages = find: -python_requires = >=3.8 +# python_requires = >=3.8 install_requires = Django >= 3.2 pytz >= 0 From 76187eb1cd0f8f256c2ed99959749555a2c5ad25 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Mon, 30 Oct 2023 16:07:01 -0700 Subject: [PATCH 03/14] Move package dependencies into pyproject.toml --- pyproject.toml | 16 ++++++++++++++++ setup.cfg | 30 +++++++++++++++--------------- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 1c3d9603..a2eb487e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,6 +19,22 @@ classifiers = [ "Operating System :: OS Independent", "Programming Language :: Python :: 3", ] +dependencies = [ + "Django >= 3.2", + "pytz >= 0", + "crispy-bootstrap5 >= 0.6", + "django-crispy-forms >= 1.12", + "google-auth >= 2.6", + "fontawesomefree >= 6.1", + "django-autocomplete-light >= 3.9", + "django-filter >= 23.0", + "django-tables2 >= 2.4", + "django-simple-history >= 3.1.1", + "django-extensions >= 3.1.5", + "plotly >= 5.11.0", + "networkx >= 2.8.2", + "numpy >= 1.24", +] [project.urls] "Homepage" = "https://github.com/UW-GAC/django-anvil-consortium-manager" diff --git a/setup.cfg b/setup.cfg index 0c5b5d86..fa968dca 100644 --- a/setup.cfg +++ b/setup.cfg @@ -27,21 +27,21 @@ include_package_data = true packages = find: # python_requires = >=3.8 -install_requires = - Django >= 3.2 - pytz >= 0 - crispy-bootstrap5 >= 0.6 - django-crispy-forms >= 1.12 - google-auth >= 2.6 - fontawesomefree >= 6.1 - django-autocomplete-light >= 3.9 - django-filter >= 23.0 - django-tables2 >= 2.4 - django-simple-history >= 3.1.1 - django-extensions >= 3.1.5 - plotly >= 5.11.0 - networkx >= 2.8.2 - numpy >= 1.24 +# install_requires = +# Django >= 3.2 +# pytz >= 0 +# crispy-bootstrap5 >= 0.6 +# django-crispy-forms >= 1.12 +# google-auth >= 2.6 +# fontawesomefree >= 6.1 +# django-autocomplete-light >= 3.9 +# django-filter >= 23.0 +# django-tables2 >= 2.4 +# django-simple-history >= 3.1.1 +# django-extensions >= 3.1.5 +# plotly >= 5.11.0 +# networkx >= 2.8.2 +# numpy >= 1.24 [flake8] From 93de6e106b94393060bea077e397feb079520e40 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Mon, 30 Oct 2023 16:35:24 -0700 Subject: [PATCH 04/14] Move package directory specification to pyproject.toml --- pyproject.toml | 3 +++ setup.cfg | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a2eb487e..2bc8532c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,3 +39,6 @@ dependencies = [ [project.urls] "Homepage" = "https://github.com/UW-GAC/django-anvil-consortium-manager" "Bug Tracker" = "https://github.com/UW-GAC/django-anvil-consortium-manager/issues" + +[tool.setuptools] +packages = ["anvil_consortium_manager"] diff --git a/setup.cfg b/setup.cfg index fa968dca..6567ab1b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -24,8 +24,8 @@ # Topic :: Internet :: WWW/HTTP :: Dynamic Content [options] -include_package_data = true -packages = find: +# include_package_data = true +# packages = find: # python_requires = >=3.8 # install_requires = # Django >= 3.2 From 80dbdcf5121bfe371142409e3294f6833456908b Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Mon, 30 Oct 2023 16:57:23 -0700 Subject: [PATCH 05/14] Clean up warnings when building with setuptools setuptools gave warnings about submodules that were not declared. instead of including all those separately, change the way that pyproject.toml declares how to find packages. As part of this, remove the docs/_build directory using MANIFEST.in. --- MANIFEST.in | 1 + pyproject.toml | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in index 8a0e930c..184af0ba 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -2,3 +2,4 @@ include LICENSE include README.md recursive-include anvil_consortium_manager/templates * recursive-include docs * +prune docs/_build diff --git a/pyproject.toml b/pyproject.toml index 2bc8532c..a7376440 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,5 +40,5 @@ dependencies = [ "Homepage" = "https://github.com/UW-GAC/django-anvil-consortium-manager" "Bug Tracker" = "https://github.com/UW-GAC/django-anvil-consortium-manager/issues" -[tool.setuptools] -packages = ["anvil_consortium_manager"] +[tool.setuptools.packages.find] +include = ["anvil_consortium_manager*"] From 4ee1c514677b561d86dac9c5459a0c346b793dc1 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 31 Oct 2023 13:15:43 -0700 Subject: [PATCH 06/14] Move isort settings to pyproject.toml --- pyproject.toml | 11 +++++++++++ setup.cfg | 20 ++++++++++---------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a7376440..97fe5794 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,3 +42,14 @@ dependencies = [ [tool.setuptools.packages.find] include = ["anvil_consortium_manager*"] + +[tool.isort] +line_length = 88 +known_first_party = ["anvil_consortium_manager", "example_site"] +multi_line_output = 3 +default_section = "THIRDPARTY" +skip = ["venv/"] +skip_glob = ["**/migrations/*.py"] +include_trailing_comma = true +force_grid_wrap = 0 +use_parentheses = true diff --git a/setup.cfg b/setup.cfg index 6567ab1b..b1c9d56f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -52,16 +52,16 @@ exclude = .tox,.git,*/migrations/*,*/static/CACHE/*,docs,node_modules,venv max-line-length = 120 exclude = .tox,.git,*/migrations/*,*/static/CACHE/*,docs,node_modules,venv -[isort] -line_length = 88 -known_first_party = anvil_consortium_manager,example_site -multi_line_output = 3 -default_section = THIRDPARTY -skip = venv/ -skip_glob = **/migrations/*.py -include_trailing_comma = true -force_grid_wrap = 0 -use_parentheses = true +# [isort] +# line_length = 88 +# known_first_party = anvil_consortium_manager,example_site +# multi_line_output = 3 +# default_section = THIRDPARTY +# skip = venv/ +# skip_glob = **/migrations/*.py +# include_trailing_comma = true +# force_grid_wrap = 0 +# use_parentheses = true [mypy] python_version = 3.9 From ecdc9ff125691e5512f09976f5ed82e4d53c0ff7 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 31 Oct 2023 13:30:43 -0700 Subject: [PATCH 07/14] Add black settings to pyproject.toml Note: changing the line length reformatted a number of files. --- add_test_data.py | 12 +- anvil_consortium_manager/adapters/account.py | 12 +- .../adapters/workspace.py | 40 +- anvil_consortium_manager/anvil_api.py | 68 +- anvil_consortium_manager/apps.py | 4 +- anvil_consortium_manager/audit/audit.py | 114 +- anvil_consortium_manager/auth.py | 4 +- anvil_consortium_manager/forms.py | 38 +- .../management/commands/run_anvil_audit.py | 16 +- anvil_consortium_manager/models.py | 244 +- .../tests/api_factories.py | 16 +- anvil_consortium_manager/tests/factories.py | 8 +- .../integration_tests_anvil_api.py | 164 +- .../tests/settings/test.py | 8 +- .../tests/settings/urls.py | 8 +- .../tests/test_adapters.py | 44 +- .../tests/test_app/models.py | 7 +- anvil_consortium_manager/tests/test_audit.py | 552 +- anvil_consortium_manager/tests/test_auth.py | 12 +- .../tests/test_commands.py | 46 +- anvil_consortium_manager/tests/test_forms.py | 8 +- .../tests/test_migrations.py | 12 +- anvil_consortium_manager/tests/test_models.py | 748 +-- .../tests/test_models_anvil_api_unit.py | 450 +- anvil_consortium_manager/tests/test_views.py | 4860 ++++------------- anvil_consortium_manager/tests/utils.py | 8 +- anvil_consortium_manager/urls.py | 4 +- anvil_consortium_manager/viewmixins.py | 24 +- anvil_consortium_manager/views.py | 688 +-- example_site/__init__.py | 7 +- example_site/settings.py | 9 +- pyproject.toml | 6 +- 32 files changed, 2024 insertions(+), 6217 deletions(-) diff --git a/add_test_data.py b/add_test_data.py index 2da3352a..1f6d86e8 100644 --- a/add_test_data.py +++ b/add_test_data.py @@ -8,15 +8,9 @@ workspaces = factories.WorkspaceFactory.create_batch(5, workspace_type="example") # Add some groups to other groups. -factories.GroupGroupMembershipFactory.create( - parent_group=groups[0], child_group=groups[1] -) -factories.GroupGroupMembershipFactory.create( - parent_group=groups[0], child_group=groups[2] -) -factories.GroupGroupMembershipFactory.create( - parent_group=groups[3], child_group=groups[2] -) +factories.GroupGroupMembershipFactory.create(parent_group=groups[0], child_group=groups[1]) +factories.GroupGroupMembershipFactory.create(parent_group=groups[0], child_group=groups[2]) +factories.GroupGroupMembershipFactory.create(parent_group=groups[3], child_group=groups[2]) # Add accounts to groups. factories.GroupAccountMembershipFactory.create(group=groups[1], account=accounts[0]) diff --git a/anvil_consortium_manager/adapters/account.py b/anvil_consortium_manager/adapters/account.py index 097d090d..3017d44c 100644 --- a/anvil_consortium_manager/adapters/account.py +++ b/anvil_consortium_manager/adapters/account.py @@ -26,21 +26,15 @@ def list_filterset_class(self): def get_list_table_class(self): """Return the table class to use for the AccountList view.""" if not self.list_table_class: - raise ImproperlyConfigured( - "Set `list_table_class` in `{}`.".format(type(self)) - ) + raise ImproperlyConfigured("Set `list_table_class` in `{}`.".format(type(self))) return self.list_table_class def get_list_filterset_class(self): """Return the FilterSet subclass to use for Account filtering in the AccountList view.""" if not self.list_filterset_class: - raise ImproperlyConfigured( - "Set `list_filterset_class` in `{}`.".format(type(self)) - ) + raise ImproperlyConfigured("Set `list_filterset_class` in `{}`.".format(type(self))) if not issubclass(self.list_filterset_class, FilterSet): - raise ImproperlyConfigured( - "list_filterset_class must be a subclass of FilterSet." - ) + raise ImproperlyConfigured("list_filterset_class must be a subclass of FilterSet.") # Make sure it has the correct model set. if self.list_filterset_class.Meta.model != models.Account: raise ImproperlyConfigured( diff --git a/anvil_consortium_manager/adapters/workspace.py b/anvil_consortium_manager/adapters/workspace.py index 73a11746..3f806351 100644 --- a/anvil_consortium_manager/adapters/workspace.py +++ b/anvil_consortium_manager/adapters/workspace.py @@ -78,9 +78,7 @@ def get_description(self): def get_list_table_class(self): """Return the table class to use for the WorkspaceListByType view.""" if not self.list_table_class: - raise ImproperlyConfigured( - "Set `list_table_class` in `{}`.".format(type(self)) - ) + raise ImproperlyConfigured("Set `list_table_class` in `{}`.".format(type(self))) return self.list_table_class def get_workspace_form_class(self): @@ -89,9 +87,7 @@ def get_workspace_form_class(self): raise ImproperlyConfigured("Set `workspace_data_form_class`.") # Make sure it is a model form if not issubclass(self.workspace_form_class, ModelForm): - raise ImproperlyConfigured( - "workspace_form_class must be a subclass of ModelForm." - ) + raise ImproperlyConfigured("workspace_form_class must be a subclass of ModelForm.") # Make sure it has the correct model set. if self.workspace_form_class.Meta.model != models.Workspace: raise ImproperlyConfigured( @@ -104,9 +100,7 @@ def get_workspace_data_model(self): if not self.workspace_data_model: raise ImproperlyConfigured("Set `workspace_data_model`.") elif not issubclass(self.workspace_data_model, models.BaseWorkspaceData): - raise ImproperlyConfigured( - "`workspace_data_model` must be a subclass of `BaseWorkspaceData`." - ) + raise ImproperlyConfigured("`workspace_data_model` must be a subclass of `BaseWorkspaceData`.") return self.workspace_data_model def get_workspace_data_form_class(self): @@ -118,9 +112,7 @@ def get_workspace_data_form_class(self): raise ImproperlyConfigured("Set `workspace_data_form_class`.") # Make sure it has the "workspace" field. if "workspace" not in self.workspace_data_form_class().fields: - raise ImproperlyConfigured( - "`workspace_data_form_class` must have a field for workspace." - ) + raise ImproperlyConfigured("`workspace_data_form_class` must have a field for workspace.") return self.workspace_data_form_class def get_workspace_detail_template_name(self): @@ -159,44 +151,32 @@ def register(self, adapter_class): """Register an adapter class using its type.""" # Make sure the adapter has the correct subclass. if not issubclass(adapter_class, BaseWorkspaceAdapter): - raise ImproperlyConfigured( - "`adapter_class` must inherit from `BaseWorkspaceAdapter`." - ) + raise ImproperlyConfigured("`adapter_class` must inherit from `BaseWorkspaceAdapter`.") # Make sure that an adapter for this type is not already registered. adapter = adapter_class() type = adapter.get_type() if type in self._registry: if self._registry[type] is adapter_class: - raise AdapterAlreadyRegisteredError( - "adapter {} already exists in registry.".format(adapter_class) - ) + raise AdapterAlreadyRegisteredError("adapter {} already exists in registry.".format(adapter_class)) else: - raise AdapterAlreadyRegisteredError( - "type `{}` already exists in registry.".format(type) - ) + raise AdapterAlreadyRegisteredError("type `{}` already exists in registry.".format(type)) # Add the adapter to the registry. self._registry[type] = adapter_class def unregister(self, adapter_class): """Unregister an adapter class.""" if not issubclass(adapter_class, BaseWorkspaceAdapter): - raise ImproperlyConfigured( - "`adapter_class` must inherit from `BaseWorkspaceAdapter`." - ) + raise ImproperlyConfigured("`adapter_class` must inherit from `BaseWorkspaceAdapter`.") type = adapter_class().type if type in self._registry: # Check that the registered adapter is the same class and raise an exception if not. registered_adapter = self._registry[type] if registered_adapter is not adapter_class: - raise AdapterNotRegisteredError( - "adapter {} has not been registered yet.".format(adapter_class) - ) + raise AdapterNotRegisteredError("adapter {} has not been registered yet.".format(adapter_class)) else: del self._registry[type] else: - raise AdapterNotRegisteredError( - "adapter {} has not been registered yet.".format(adapter_class) - ) + raise AdapterNotRegisteredError("adapter {} has not been registered yet.".format(adapter_class)) def get_adapter(self, type): """ "Return an instance of the adapter for a given workspace ``type``.""" diff --git a/anvil_consortium_manager/anvil_api.py b/anvil_consortium_manager/anvil_api.py index ca1f91da..2452050e 100644 --- a/anvil_consortium_manager/anvil_api.py +++ b/anvil_consortium_manager/anvil_api.py @@ -202,15 +202,7 @@ def add_user_to_group(self, group_name, role, user_email): Returns: requests.Response """ - url = ( - self.sam_entry_point - + "/api/groups/v1/" - + group_name - + "/" - + role - + "/" - + user_email - ) + url = self.sam_entry_point + "/api/groups/v1/" + group_name + "/" + role + "/" + user_email return self.auth_session.put(url, 204) def remove_user_from_group(self, group_name, role, user_email): @@ -226,15 +218,7 @@ def remove_user_from_group(self, group_name, role, user_email): Returns: requests.Response """ - url = ( - self.sam_entry_point - + "/api/groups/v1/" - + group_name - + "/" - + role - + "/" - + user_email - ) + url = self.sam_entry_point + "/api/groups/v1/" + group_name + "/" + role + "/" + user_email return self.auth_session.delete(url, 204) def list_workspaces(self, fields=None): @@ -267,18 +251,10 @@ def get_workspace(self, workspace_namespace, workspace_name): Returns: requests.Response """ - url = ( - self.rawls_entry_point - + "/api/workspaces/" - + workspace_namespace - + "/" - + workspace_name - ) + url = self.rawls_entry_point + "/api/workspaces/" + workspace_namespace + "/" + workspace_name return self.auth_session.get(url, 200) - def create_workspace( - self, workspace_namespace, workspace_name, authorization_domains=[] - ): + def create_workspace(self, workspace_namespace, workspace_name, authorization_domains=[]): """Create a workspace on AnVIL. Calls the /api/create_workspace POST method. @@ -335,12 +311,9 @@ def clone_workspace( Returns: requests.Response """ - url = ( - self.rawls_entry_point - + "/api/workspaces/{namespace}/{name}/clone".format( - namespace=existing_workspace_namespace, - name=existing_workspace_name, - ) + url = self.rawls_entry_point + "/api/workspaces/{namespace}/{name}/clone".format( + namespace=existing_workspace_namespace, + name=existing_workspace_name, ) body = { "namespace": cloned_workspace_namespace, @@ -372,13 +345,7 @@ def delete_workspace(self, workspace_namespace, workspace_name): Returns: requests.Response """ - url = ( - self.rawls_entry_point - + "/api/workspaces/" - + workspace_namespace - + "/" - + workspace_name - ) + url = self.rawls_entry_point + "/api/workspaces/" + workspace_namespace + "/" + workspace_name return self.auth_session.delete(url, 202) def get_workspace_acl(self, workspace_namespace, workspace_name): @@ -395,14 +362,7 @@ def get_workspace_acl(self, workspace_namespace, workspace_name): Returns: requests.Response """ - url = ( - self.rawls_entry_point - + "/api/workspaces/" - + workspace_namespace - + "/" - + workspace_name - + "/acl" - ) + url = self.rawls_entry_point + "/api/workspaces/" + workspace_namespace + "/" + workspace_name + "/acl" return self.auth_session.get(url, 200) def update_workspace_acl(self, workspace_namespace, workspace_name, acl_updates): @@ -421,17 +381,11 @@ def update_workspace_acl(self, workspace_namespace, workspace_name, acl_updates) requests.Response """ url = self.rawls_entry_point + ( - "/api/workspaces/" - + workspace_namespace - + "/" - + workspace_name - + "/acl?inviteUsersNotFound=false" + "/api/workspaces/" + workspace_namespace + "/" + workspace_name + "/acl?inviteUsersNotFound=false" ) # False here means do not invite unregistered users. updates = json.dumps(acl_updates) - return self.auth_session.patch( - url, 200, headers={"Content-type": "application/json"}, data=updates - ) + return self.auth_session.patch(url, 200, headers={"Content-type": "application/json"}, data=updates) class AnVILAPISession(AuthorizedSession): diff --git a/anvil_consortium_manager/apps.py b/anvil_consortium_manager/apps.py index d278fabc..254fcb93 100644 --- a/anvil_consortium_manager/apps.py +++ b/anvil_consortium_manager/apps.py @@ -12,8 +12,6 @@ def ready(self): super().ready() # Register adapters sepcified in settings. # Import here because importing outside of this method raises the AppRegistryNotReady exception. - from anvil_consortium_manager.adapters.workspace import ( - workspace_adapter_registry, - ) + from anvil_consortium_manager.adapters.workspace import workspace_adapter_registry workspace_adapter_registry.populate_from_settings() diff --git a/anvil_consortium_manager/audit/audit.py b/anvil_consortium_manager/audit/audit.py index 6cd51d99..65411cf9 100644 --- a/anvil_consortium_manager/audit/audit.py +++ b/anvil_consortium_manager/audit/audit.py @@ -15,9 +15,7 @@ def __init__(self, model_instance): self.errors = set() def __eq__(self, other): - return ( - self.model_instance == other.model_instance and self.errors == other.errors - ) + return self.model_instance == other.model_instance and self.errors == other.errors def __str__(self): return str(self.model_instance) @@ -93,9 +91,7 @@ def add_result(self, result): elif isinstance(result, ModelInstanceResult): self._add_model_instance_result(result) else: - raise ValueError( - "result must be a ModelInstanceResult or a NotInAppResult." - ) + raise ValueError("result must be a ModelInstanceResult or a NotInAppResult.") def _add_not_in_app_result(self, result): # Check that it hasn't been added yet. @@ -105,23 +101,13 @@ def _add_not_in_app_result(self, result): self._not_in_app_results.append(result) def _add_model_instance_result(self, result): - check = [ - x - for x in self._model_instance_results - if x.model_instance == result.model_instance - ] + check = [x for x in self._model_instance_results if x.model_instance == result.model_instance] if len(check) > 0: - raise ValueError( - "Already added a result for {}.".format(result.model_instance) - ) + raise ValueError("Already added a result for {}.".format(result.model_instance)) self._model_instance_results.append(result) def get_result_for_model_instance(self, model_instance): - results = [ - x - for x in self._model_instance_results - if x.model_instance == model_instance - ] + results = [x for x in self._model_instance_results if x.model_instance == model_instance] if len(results) != 1: raise ValueError("model_instance is not in the results.") return results[0] @@ -135,9 +121,7 @@ def get_error_results(self): def get_not_in_app_results(self): return self._not_in_app_results - def export( - self, include_verified=True, include_errors=True, include_not_in_app=True - ): + def export(self, include_verified=True, include_errors=True, include_not_in_app=True): """Return a dictionary representation of the audit results.""" exported_results = {} if include_verified: @@ -155,9 +139,7 @@ def export( for result in self.get_error_results() ] if include_not_in_app: - exported_results["not_in_app"] = list( - sorted([x.record for x in self.get_not_in_app_results()]) - ) + exported_results["not_in_app"] = list(sorted([x.record for x in self.get_not_in_app_results()])) return exported_results @@ -169,9 +151,7 @@ class BillingProjectAudit(AnVILAudit): def run_audit(self): # Check that all billing projects exist. - for billing_project in models.BillingProject.objects.filter( - has_app_as_user=True - ).all(): + for billing_project in models.BillingProject.objects.filter(has_app_as_user=True).all(): model_instance_result = ModelInstanceResult(billing_project) if not billing_project.anvil_exists(): model_instance_result.add_error(self.ERROR_NOT_IN_ANVIL) @@ -186,9 +166,7 @@ class AccountAudit(AnVILAudit): def run_audit(self): # Only checks active accounts. - for account in models.Account.objects.filter( - status=models.Account.ACTIVE_STATUS - ).all(): + for account in models.Account.objects.filter(status=models.Account.ACTIVE_STATUS).all(): model_instance_result = ModelInstanceResult(account) if not account.anvil_exists(): model_instance_result.add_error(self.ERROR_NOT_IN_ANVIL) @@ -269,14 +247,10 @@ class ManagedGroupMembershipAudit(AnVILAudit): ERROR_ACCOUNT_MEMBER_NOT_IN_ANVIL = "Account not a member in AnVIL" """Error when an Account is a member of a ManagedGroup on the app, but not in AnVIL.""" - ERROR_DEACTIVATED_ACCOUNT_IS_ADMIN_IN_ANVIL = ( - "Account is deactivated but is an admin in AnVIL." - ) + ERROR_DEACTIVATED_ACCOUNT_IS_ADMIN_IN_ANVIL = "Account is deactivated but is an admin in AnVIL." """Error when a deactivated Account is an admin of a ManagedGroup in AnVIL.""" - ERROR_DEACTIVATED_ACCOUNT_IS_MEMBER_IN_ANVIL = ( - "Account is deactivated but is a member in AnVIL." - ) + ERROR_DEACTIVATED_ACCOUNT_IS_MEMBER_IN_ANVIL = "Account is deactivated but is a member in AnVIL." """Error when a deactivated Account is a member of a ManagedGroup in AnVIL.""" ERROR_GROUP_ADMIN_NOT_IN_ANVIL = "Group not an admin in AnVIL" @@ -288,9 +262,7 @@ class ManagedGroupMembershipAudit(AnVILAudit): def __init__(self, managed_group, *args, **kwargs): super().__init__(*args, **kwargs) if not managed_group.is_managed_by_app: - raise exceptions.AnVILNotGroupAdminError( - "group {} is not managed by app".format(managed_group.name) - ) + raise exceptions.AnVILNotGroupAdminError("group {} is not managed by app".format(managed_group.name)) self.managed_group = managed_group def run_audit(self): @@ -303,9 +275,7 @@ def run_audit(self): members_in_anvil = [x.lower() for x in response.json()] # Sometimes the service account is also listed as a member. Remove that too. try: - members_in_anvil.remove( - api_client.auth_session.credentials.service_account_email.lower() - ) + members_in_anvil.remove(api_client.auth_session.credentials.service_account_email.lower()) except ValueError: # Not listed as a member -- this is ok. pass @@ -315,9 +285,7 @@ def run_audit(self): admins_in_anvil = [x.lower() for x in response.json()] # Remove the service account as admin. try: - admins_in_anvil.remove( - api_client.auth_session.credentials.service_account_email.lower() - ) + admins_in_anvil.remove(api_client.auth_session.credentials.service_account_email.lower()) except ValueError: # Not listed as an admin -- this is ok because it could be via group membership. pass @@ -330,28 +298,20 @@ def run_audit(self): try: admins_in_anvil.remove(membership.account.email.lower()) if membership.account.status == models.Account.INACTIVE_STATUS: - model_instance_result.add_error( - self.ERROR_DEACTIVATED_ACCOUNT_IS_ADMIN_IN_ANVIL - ) + model_instance_result.add_error(self.ERROR_DEACTIVATED_ACCOUNT_IS_ADMIN_IN_ANVIL) except ValueError: # For active accounts, this is an error - the email is not in the list of members. if membership.account.status == models.Account.ACTIVE_STATUS: - model_instance_result.add_error( - self.ERROR_ACCOUNT_ADMIN_NOT_IN_ANVIL - ) + model_instance_result.add_error(self.ERROR_ACCOUNT_ADMIN_NOT_IN_ANVIL) elif membership.role == models.GroupAccountMembership.MEMBER: try: members_in_anvil.remove(membership.account.email.lower()) if membership.account.status == models.Account.INACTIVE_STATUS: - model_instance_result.add_error( - self.ERROR_DEACTIVATED_ACCOUNT_IS_MEMBER_IN_ANVIL - ) + model_instance_result.add_error(self.ERROR_DEACTIVATED_ACCOUNT_IS_MEMBER_IN_ANVIL) except ValueError: # For active accounts, this is an error - the email is not in the list of members. if membership.account.status == models.Account.ACTIVE_STATUS: - model_instance_result.add_error( - self.ERROR_ACCOUNT_MEMBER_NOT_IN_ANVIL - ) + model_instance_result.add_error(self.ERROR_ACCOUNT_MEMBER_NOT_IN_ANVIL) self.add_result(model_instance_result) # Check group-group membership. @@ -375,25 +335,15 @@ def run_audit(self): members_in_anvil.remove(membership.child_group.email.lower()) except ValueError: # This email is not in the list of members. - model_instance_result.add_error( - self.ERROR_GROUP_MEMBER_NOT_IN_ANVIL - ) + model_instance_result.add_error(self.ERROR_GROUP_MEMBER_NOT_IN_ANVIL) self.add_result(model_instance_result) # Add any admin that the app doesn't know about. for member in admins_in_anvil: - self.add_result( - NotInAppResult( - "{}: {}".format(models.GroupAccountMembership.ADMIN, member) - ) - ) + self.add_result(NotInAppResult("{}: {}".format(models.GroupAccountMembership.ADMIN, member))) # Add any members that the app doesn't know about. for member in members_in_anvil: - self.add_result( - NotInAppResult( - "{}: {}".format(models.GroupAccountMembership.MEMBER, member) - ) - ) + self.add_result(NotInAppResult("{}: {}".format(models.GroupAccountMembership.MEMBER, member))) class WorkspaceAudit(AnVILAudit): @@ -433,8 +383,7 @@ def run_audit(self): for idx, x in enumerate(workspaces_on_anvil) if ( x["workspace"]["name"] == workspace.name - and x["workspace"]["namespace"] - == workspace.billing_project.name + and x["workspace"]["namespace"] == workspace.billing_project.name ) ) except StopIteration: @@ -452,12 +401,9 @@ def run_audit(self): model_instance_result.add_error(self.ERROR_WORKSPACE_SHARING) # Check auth domains. auth_domains_on_anvil = [ - x["membersGroupName"] - for x in workspace_details["workspace"]["authorizationDomain"] + x["membersGroupName"] for x in workspace_details["workspace"]["authorizationDomain"] ] - auth_domains_in_app = workspace.authorization_domains.all().values_list( - "name", flat=True - ) + auth_domains_in_app = workspace.authorization_domains.all().values_list("name", flat=True) if set(auth_domains_on_anvil) != set(auth_domains_in_app): model_instance_result.add_error(self.ERROR_DIFFERENT_AUTH_DOMAINS) # Check lock status. @@ -498,15 +444,11 @@ def __init__(self, workspace, *args, **kwargs): def run_audit(self): """Run the audit for all workspace instances.""" api_client = AnVILAPIClient() - response = api_client.get_workspace_acl( - self.workspace.billing_project.name, self.workspace.name - ) + response = api_client.get_workspace_acl(self.workspace.billing_project.name, self.workspace.name) acl_in_anvil = {k.lower(): v for k, v in response.json()["acl"].items()} # Remove the service account. try: - acl_in_anvil.pop( - api_client.auth_session.credentials.service_account_email.lower() - ) + acl_in_anvil.pop(api_client.auth_session.credentials.service_account_email.lower()) except KeyError: # In some cases, the workspace is shared with a group we are part of instead of directly with us. pass @@ -534,6 +476,4 @@ def run_audit(self): # Add any access that the app doesn't know about. for key in acl_in_anvil: - self.add_result( - NotInAppResult("{}: {}".format(acl_in_anvil[key]["accessLevel"], key)) - ) + self.add_result(NotInAppResult("{}: {}".format(acl_in_anvil[key]["accessLevel"], key))) diff --git a/anvil_consortium_manager/auth.py b/anvil_consortium_manager/auth.py index 0414710e..7cc14861 100644 --- a/anvil_consortium_manager/auth.py +++ b/anvil_consortium_manager/auth.py @@ -13,9 +13,7 @@ def test_func(self): apm_content_type = ContentType.objects.get_for_model(AnVILProjectManagerAccess) perm_1 = f"{apm_content_type.app_label}.{AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME}" perm_2 = f"{apm_content_type.app_label}.{AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME}" - has_perms = self.request.user.has_perms( - (perm_1,) - ) or self.request.user.has_perms((perm_2,)) + has_perms = self.request.user.has_perms((perm_1,)) or self.request.user.has_perms((perm_2,)) return has_perms diff --git a/anvil_consortium_manager/forms.py b/anvil_consortium_manager/forms.py index 77080e1d..69535286 100644 --- a/anvil_consortium_manager/forms.py +++ b/anvil_consortium_manager/forms.py @@ -49,9 +49,7 @@ def __init__(self, *args, **kwargs): # Add a submit button with col-auto. This makes auto-sizes the column to just fit the submit button. layout.Div( # mb-3 to match what is done in FloatingField - this centers the button vertically. - layout.Submit( - "submit", "Filter", css_class="btn btn-secondary mb-3" - ), + layout.Submit("submit", "Filter", css_class="btn btn-secondary mb-3"), css_class="col-auto", ), css_class="row align-items-center" @@ -113,9 +111,7 @@ class Meta: class UserEmailEntryForm(forms.Form): """Form for user to enter their email attempting to link their AnVIL account.""" - email = forms.EmailField( - label="Email", help_text="Enter the email associated with your AnVIL account." - ) + email = forms.EmailField(label="Email", help_text="Enter the email associated with your AnVIL account.") def clean_email(self): """Custom validation. @@ -178,9 +174,7 @@ class Meta: def clean_billing_project(self): billing_project = self.cleaned_data.get("billing_project") if billing_project and not billing_project.has_app_as_user: - raise ValidationError( - "Billing project must have has_app_as_user set to True" - ) + raise ValidationError("Billing project must have has_app_as_user set to True") return billing_project def clean(self): @@ -202,9 +196,7 @@ def clean(self): ).exists() ): # The workspace already exists - raise a Validation error. - raise ValidationError( - "Workspace with this Billing Project and Name already exists." - ) + raise ValidationError("Workspace with this Billing Project and Name already exists.") return self.cleaned_data @@ -213,9 +205,7 @@ class WorkspaceImportForm(forms.Form): title = "Import a workspace" workspace = forms.ChoiceField() - note = forms.CharField( - widget=forms.Textarea, help_text="Additional notes.", required=False - ) + note = forms.CharField(widget=forms.Textarea, help_text="Additional notes.", required=False) def __init__(self, workspace_choices=[], *args, **kwargs): """Initialize form with a set of possible workspace choices.""" @@ -271,11 +261,7 @@ def __init__(self, workspace_to_clone, *args, **kwargs): self.workspace_to_clone = workspace_to_clone # Add the list of required auth domains to the help text. if self.workspace_to_clone.authorization_domains.exists(): - auth_domain_names = ( - self.workspace_to_clone.authorization_domains.values_list( - "name", flat=True - ) - ) + auth_domain_names = self.workspace_to_clone.authorization_domains.values_list("name", flat=True) extra_text = " You must also include the authorization domain(s) from the original workspace ({}).".format( ", ".join(auth_domain_names) ) @@ -286,12 +272,8 @@ def __init__(self, workspace_to_clone, *args, **kwargs): def clean_authorization_domains(self): """Verify that all authorization domains from the original workspace are selected.""" authorization_domains = self.cleaned_data["authorization_domains"] - required_authorization_domains = ( - self.workspace_to_clone.authorization_domains.all() - ) - missing = [ - g for g in required_authorization_domains if g not in authorization_domains - ] + required_authorization_domains = self.workspace_to_clone.authorization_domains.all() + missing = [g for g in required_authorization_domains if g not in authorization_domains] if missing: msg = "Must contain all original workspace authorization domains: {}".format( # ", ".join([g.name for g in self.workspace_to_clone.authorization_domains.all()]) @@ -313,9 +295,7 @@ def clean(self): ).exists() ): # The workspace already exists - raise a Validation error. - raise ValidationError( - "Workspace with this Billing Project and Name already exists." - ) + raise ValidationError("Workspace with this Billing Project and Name already exists.") return self.cleaned_data diff --git a/anvil_consortium_manager/management/commands/run_anvil_audit.py b/anvil_consortium_manager/management/commands/run_anvil_audit.py index 3b9347a2..cb752c7d 100644 --- a/anvil_consortium_manager/management/commands/run_anvil_audit.py +++ b/anvil_consortium_manager/management/commands/run_anvil_audit.py @@ -64,29 +64,21 @@ def _run_audit(self, audit_results, **options): else: if not audit_results.ok(): self.stdout.write(self.style.ERROR("problems found.")) - self.stdout.write( - pprint.pformat(audit_results.export(include_verified=False)) - ) + self.stdout.write(pprint.pformat(audit_results.export(include_verified=False))) else: self.stdout.write(self.style.SUCCESS("ok!")) if email and (not errors_only) or (errors_only and not audit_results.ok()): # Set up the email message. - subject = "AnVIL audit {} -- {}".format( - audit_name, "ok" if audit_results.ok() else "errors!" - ) + subject = "AnVIL audit {} -- {}".format(audit_name, "ok" if audit_results.ok() else "errors!") exported_results = audit_results.export() html_body = render_to_string( "anvil_consortium_manager/email_audit_report.html", context={ "model_name": audit_name, "verified_results": audit_results.get_verified_results(), - "errors_table": ErrorTableWithLink( - audit_results.get_error_results() - ), - "not_in_app_table": audit.NotInAppTable( - audit_results.get_not_in_app_results() - ), + "errors_table": ErrorTableWithLink(audit_results.get_error_results()), + "not_in_app_table": audit.NotInAppTable(audit_results.get_not_in_app_results()), }, ) send_mail( diff --git a/anvil_consortium_manager/models.py b/anvil_consortium_manager/models.py index 77b21070..6a1d4ce6 100644 --- a/anvil_consortium_manager/models.py +++ b/anvil_consortium_manager/models.py @@ -50,12 +50,8 @@ class Meta: class BillingProject(TimeStampedModel): """A model to store information about AnVIL billing projects.""" - name = models.SlugField( - max_length=64, unique=True, help_text="Name of the Billing Project on AnVIL." - ) - has_app_as_user = models.BooleanField( - help_text="Indicator of whether the app is a user in this BillingProject." - ) + name = models.SlugField(max_length=64, unique=True, help_text="Name of the Billing Project on AnVIL.") + has_app_as_user = models.BooleanField(help_text="Indicator of whether the app is a user in this BillingProject.") note = models.TextField(blank=True, help_text="Additional notes.") history = HistoricalRecords() @@ -82,15 +78,11 @@ def anvil_import(cls, billing_project_name, **kwargs): try: billing_project = cls.objects.get(name=billing_project_name) except cls.DoesNotExist: - billing_project = cls( - name=billing_project_name, has_app_as_user=True, **kwargs - ) + billing_project = cls(name=billing_project_name, has_app_as_user=True, **kwargs) billing_project.full_clean() else: # The billing project already exists in the database. - raise exceptions.AnVILAlreadyImported( - "BillingProject: " + billing_project_name - ) + raise exceptions.AnVILAlreadyImported("BillingProject: " + billing_project_name) # I think we only care if this doesn't raise an exception. # That should mean that it is successful, and we don't care about any of the information returned. AnVILAPIClient().get_billing_project(billing_project_name) @@ -107,9 +99,7 @@ class UserEmailEntry(TimeStampedModel, models.Model): email = models.EmailField() """The email entered by the user.""" - user = models.ForeignKey( - settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE - ) + user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE) """The user who created the record.""" date_verification_email_sent = models.DateTimeField() @@ -122,11 +112,7 @@ class UserEmailEntry(TimeStampedModel, models.Model): """Django simple history.""" class Meta: - constraints = [ - models.UniqueConstraint( - fields=["email", "user"], name="unique_user_email_entry" - ) - ] + constraints = [models.UniqueConstraint(fields=["email", "user"], name="unique_user_email_entry")] verbose_name_plural = "user email entries" def __str__(self): @@ -200,24 +186,14 @@ def send_notification_email(self): class Account(TimeStampedModel, ActivatorModel): """A model to store information about AnVIL accounts.""" - ERROR_USER_WITHOUT_VERIFIED_EMAIL_ENTRY = ( - "Accounts with a user must have a verified_email_entry." - ) - ERROR_VERIFIED_EMAIL_ENTRY_WITHOUT_USER = ( - "Accounts with a verified_email_entry must have a user." - ) - ERROR_UNVERIFIED_VERIFIED_EMAIL_ENTRY = ( - "verified_email_entry must have date_verified." - ) + ERROR_USER_WITHOUT_VERIFIED_EMAIL_ENTRY = "Accounts with a user must have a verified_email_entry." + ERROR_VERIFIED_EMAIL_ENTRY_WITHOUT_USER = "Accounts with a verified_email_entry must have a user." + ERROR_UNVERIFIED_VERIFIED_EMAIL_ENTRY = "verified_email_entry must have date_verified." ERROR_MISMATCHED_USER = "Account.user and verified_email_entry.user do not match." - ERROR_MISMATCHED_EMAIL = ( - "Account.email and verified_email_entry.email do not match." - ) + ERROR_MISMATCHED_EMAIL = "Account.email and verified_email_entry.email do not match." # TODO: Consider using CIEmailField if using postgres. - email = models.EmailField( - unique=True, help_text="""Email associated with this account on AnVIL.""" - ) + email = models.EmailField(unique=True, help_text="""Email associated with this account on AnVIL.""") is_service_account = models.BooleanField( help_text="""Indicator of whether this account is a service account or a user account.""" ) @@ -233,9 +209,7 @@ class Account(TimeStampedModel, ActivatorModel): on_delete=models.PROTECT, help_text="User linked to this AnVIL account.", ) - is_service_account = models.BooleanField( - help_text="Indicator of whether this Account is a service account." - ) + is_service_account = models.BooleanField(help_text="Indicator of whether this Account is a service account.") verified_email_entry = models.OneToOneField( UserEmailEntry, null=True, @@ -268,19 +242,13 @@ def clean(self): """ if self.user and not self.verified_email_entry: - raise ValidationError( - {"verified_email_entry": self.ERROR_USER_WITHOUT_VERIFIED_EMAIL_ENTRY} - ) + raise ValidationError({"verified_email_entry": self.ERROR_USER_WITHOUT_VERIFIED_EMAIL_ENTRY}) elif self.verified_email_entry and not self.user: - raise ValidationError( - {"user": self.ERROR_VERIFIED_EMAIL_ENTRY_WITHOUT_USER} - ) + raise ValidationError({"user": self.ERROR_VERIFIED_EMAIL_ENTRY_WITHOUT_USER}) elif self.verified_email_entry and self.user: # Make sure the email entry is actually verified. if not self.verified_email_entry.date_verified: - raise ValidationError( - {"verified_email_entry": self.ERROR_UNVERIFIED_VERIFIED_EMAIL_ENTRY} - ) + raise ValidationError({"verified_email_entry": self.ERROR_UNVERIFIED_VERIFIED_EMAIL_ENTRY}) # Check that emails match. if self.email != self.verified_email_entry.email: raise ValidationError({"email": self.ERROR_MISMATCHED_EMAIL}) @@ -299,9 +267,7 @@ def get_absolute_url(self): Returns: A string with the url to the detail page for this object. """ - return reverse( - "anvil_consortium_manager:accounts:detail", kwargs={"uuid": self.uuid} - ) + return reverse("anvil_consortium_manager:accounts:detail", kwargs={"uuid": self.uuid}) def deactivate(self): """Set status to deactivated and remove from any AnVIL groups.""" @@ -380,9 +346,7 @@ def get_all_groups(self): class ManagedGroup(TimeStampedModel): """A model to store information about AnVIL Managed Groups.""" - name = models.SlugField( - max_length=64, unique=True, help_text="Name of the group on AnVIL." - ) + name = models.SlugField(max_length=64, unique=True, help_text="Name of the group on AnVIL.") email = models.EmailField( help_text="Email for this group.", blank=False, @@ -398,9 +362,7 @@ def __str__(self): return "{name}".format(name=self.name) def get_absolute_url(self): - return reverse( - "anvil_consortium_manager:managed_groups:detail", kwargs={"slug": self.name} - ) + return reverse("anvil_consortium_manager:managed_groups:detail", kwargs={"slug": self.name}) def get_direct_parents(self): """Return a queryset of the direct parents of this group. Does not include grandparents.""" @@ -537,12 +499,7 @@ def anvil_import(cls, group_name, **kwargs): # Create the group but don't save it yet. # Assume that it's not managed by the app until we figure out that it is. # Assume the email is the default until we figure out what it is. - group = cls( - name=group_name, - is_managed_by_app=False, - email=group_name.lower() + "@firecloud.org", - **kwargs - ) + group = cls(name=group_name, is_managed_by_app=False, email=group_name.lower() + "@firecloud.org", **kwargs) # Make sure we don't already have it in the database. group.full_clean() # Note that we have to be a member of the group to import it. @@ -562,9 +519,7 @@ def anvil_import(cls, group_name, **kwargs): group.is_managed_by_app = True # Make sure a group was found. if count == 0: - raise exceptions.AnVILNotGroupMemberError( - "group {} not found in response.".format(group_name) - ) + raise exceptions.AnVILNotGroupMemberError("group {} not found in response.".format(group_name)) # Verify it is still correct after modifying some fields. with transaction.atomic(): group.full_clean() @@ -579,9 +534,7 @@ def anvil_import_membership(self): Groups or accounts that are not already in the app are not imported.""" if not self.is_managed_by_app: - raise exceptions.AnVILNotGroupAdminError( - "group {} is not managed by app".format(self.name) - ) + raise exceptions.AnVILNotGroupAdminError("group {} is not managed by app".format(self.name)) # Now add membership records. api_client = AnVILAPIClient() response = api_client.get_group_members(self.name) @@ -607,9 +560,7 @@ def anvil_import_membership(self): # Check accounts. try: account = Account.objects.get(email=email) - membership = GroupAccountMembership( - group=self, account=account, role=GroupAccountMembership.ADMIN - ) + membership = GroupAccountMembership(group=self, account=account, role=GroupAccountMembership.ADMIN) membership.full_clean() membership.save() except Account.DoesNotExist: @@ -637,9 +588,7 @@ def anvil_import_membership(self): # Check accounts. try: account = Account.objects.get(email=email) - membership = GroupAccountMembership( - group=self, account=account, role=GroupAccountMembership.MEMBER - ) + membership = GroupAccountMembership(group=self, account=account, role=GroupAccountMembership.MEMBER) membership.full_clean() membership.save() except Account.DoesNotExist: @@ -689,9 +638,7 @@ class Workspace(TimeStampedModel): ) note = models.TextField(blank=True, help_text="Additional notes.") # If this doesn't work easily, we could switch to using generic relationships. - workspace_type = models.CharField( - max_length=255, help_text="""Workspace data type as indicated by an adapter.""" - ) + workspace_type = models.CharField(max_length=255, help_text="""Workspace data type as indicated by an adapter.""") is_locked = models.BooleanField( help_text="Indicator of whether the workspace is locked or not.", default=False, @@ -700,11 +647,7 @@ class Workspace(TimeStampedModel): history = HistoricalRecords() class Meta: - constraints = [ - models.UniqueConstraint( - fields=["billing_project", "name"], name="unique_workspace" - ) - ] + constraints = [models.UniqueConstraint(fields=["billing_project", "name"], name="unique_workspace")] def clean_fields(self, exclude=None): super().clean_fields(exclude=exclude) @@ -712,16 +655,10 @@ def clean_fields(self, exclude=None): if not exclude or "workspace_type" not in exclude: registered_adapters = workspace_adapter_registry.get_registered_adapters() if self.workspace_type not in registered_adapters: - raise ValidationError( - { - "workspace_type": "Value ``workspace_type`` is not a registered adapter type." - } - ) + raise ValidationError({"workspace_type": "Value ``workspace_type`` is not a registered adapter type."}) def __str__(self): - return "{billing_project}/{name}".format( - billing_project=self.billing_project, name=self.name - ) + return "{billing_project}/{name}".format(billing_project=self.billing_project, name=self.name) def get_absolute_url(self): return reverse( @@ -733,9 +670,7 @@ def get_absolute_url(self): ) def get_full_name(self): - return "{billing_project}/{name}".format( - billing_project=self.billing_project, name=self.name - ) + return "{billing_project}/{name}".format(billing_project=self.billing_project, name=self.name) def get_anvil_url(self): """Return the URL of the workspace on AnVIL.""" @@ -747,17 +682,13 @@ def is_in_authorization_domain(self, group): """Check if a group (or a group that it is part of) is in the auth domain of this workspace.""" in_auth_domain = True for auth_domain in self.authorization_domains.all(): - in_auth_domain = (in_auth_domain) and ( - group in auth_domain.get_all_children() - ) + in_auth_domain = (in_auth_domain) and (group in auth_domain.get_all_children()) return in_auth_domain def is_shared(self, group): """Check if this workspace is shared with a group (or a group that it is part of).""" parents = group.get_all_parents() - is_shared = self.workspacegroupsharing_set.filter( - models.Q(group=group) | models.Q(group__in=parents) - ).exists() + is_shared = self.workspacegroupsharing_set.filter(models.Q(group=group) | models.Q(group__in=parents)).exists() return is_shared def has_access(self, group): @@ -772,21 +703,15 @@ def has_access(self, group): def anvil_exists(self): """Check if the workspace exists on AnVIL.""" try: - response = AnVILAPIClient().get_workspace( - self.billing_project.name, self.name - ) + response = AnVILAPIClient().get_workspace(self.billing_project.name, self.name) except AnVILAPIError404: return False return response.status_code == 200 def anvil_create(self): """Create the workspace on AnVIL.""" - auth_domains = list( - self.authorization_domains.all().values_list("name", flat=True) - ) - AnVILAPIClient().create_workspace( - self.billing_project.name, self.name, authorization_domains=auth_domains - ) + auth_domains = list(self.authorization_domains.all().values_list("name", flat=True)) + AnVILAPIClient().create_workspace(self.billing_project.name, self.name, authorization_domains=auth_domains) def anvil_delete(self): """Delete the workspace on AnVIL.""" @@ -829,21 +754,15 @@ def anvil_clone(self, billing_project, workspace_name, authorization_domains=[]) # That way, the workspace_type can be set. @classmethod - def anvil_import( - cls, billing_project_name, workspace_name, workspace_type, note="" - ): + def anvil_import(cls, billing_project_name, workspace_name, workspace_type, note=""): """Create a new instance for a workspace that already exists on AnVIL. Methods calling this should handle AnVIL API exceptions appropriately. """ # Check if the workspace already exists in the database. try: - cls.objects.get( - billing_project__name=billing_project_name, name=workspace_name - ) - raise exceptions.AnVILAlreadyImported( - billing_project_name + "/" + workspace_name - ) + cls.objects.get(billing_project__name=billing_project_name, name=workspace_name) + raise exceptions.AnVILAlreadyImported(billing_project_name + "/" + workspace_name) except cls.DoesNotExist: # The workspace doesn't exist: continue to creation. pass @@ -856,45 +775,33 @@ def anvil_import( # This is primarily to check that the fields are valid. # We only want ot make the API call if they are valid. try: - billing_project = BillingProject.objects.get( - name=billing_project_name - ) + billing_project = BillingProject.objects.get(name=billing_project_name) billing_project_exists = True except BillingProject.DoesNotExist: - temporary_billing_project = BillingProject( - name=billing_project_name, has_app_as_user=False - ) + temporary_billing_project = BillingProject(name=billing_project_name, has_app_as_user=False) temporary_billing_project.clean_fields() billing_project_exists = False # Do not set the Billing yet, since we might be importing it or creating it later. # This is only to validate the other fields. - workspace = cls( - name=workspace_name, workspace_type=workspace_type, note=note - ) + workspace = cls(name=workspace_name, workspace_type=workspace_type, note=note) workspace.clean_fields(exclude="billing_project") # At this point, they should be valid objects. # Make sure we actually have access to the workspace. - response = AnVILAPIClient().get_workspace( - billing_project_name, workspace_name - ) + response = AnVILAPIClient().get_workspace(billing_project_name, workspace_name) workspace_json = response.json() # Make sure that we are owners of the workspace. if workspace_json["accessLevel"] != "OWNER": - raise exceptions.AnVILNotWorkspaceOwnerError( - billing_project_name + "/" + workspace_name - ) + raise exceptions.AnVILNotWorkspaceOwnerError(billing_project_name + "/" + workspace_name) # Now we can proceed with saving the objects. # Import the billing project from AnVIL if it doesn't already exist. if not billing_project_exists: try: - billing_project = BillingProject.anvil_import( - billing_project_name - ) + billing_project = BillingProject.anvil_import(billing_project_name) except AnVILAPIError404: # Use the temporary billing project we previously created above. billing_project = temporary_billing_project @@ -911,10 +818,7 @@ def anvil_import( workspace.save() # Check the authorization domains and import them. - auth_domains = [ - ad["membersGroupName"] - for ad in workspace_json["workspace"]["authorizationDomain"] - ] + auth_domains = [ad["membersGroupName"] for ad in workspace_json["workspace"]["authorizationDomain"]] # We don't need to check if we are members of the auth domains, because if we weren't we wouldn't be # able to see the workspace. @@ -925,14 +829,10 @@ def anvil_import( except ManagedGroup.DoesNotExist: group = ManagedGroup.anvil_import(auth_domain) # Add it as an authorization domain for this workspace. - WorkspaceAuthorizationDomain.objects.create( - workspace=workspace, group=group - ) + WorkspaceAuthorizationDomain.objects.create(workspace=workspace, group=group) # Get the list of groups that it is shared with and create records for them. - response = AnVILAPIClient().get_workspace_acl( - workspace.billing_project.name, workspace.name - ) + response = AnVILAPIClient().get_workspace_acl(workspace.billing_project.name, workspace.name) # import ipdb; ipdb.set_trace() acl = response.json()["acl"] for email, item in acl.items(): @@ -994,17 +894,11 @@ class WorkspaceAuthorizationDomain(TimeStampedModel): history = HistoricalRecords() class Meta: - constraints = [ - models.UniqueConstraint( - fields=["group", "workspace"], name="unique_workspace_auth_domain" - ) - ] + constraints = [models.UniqueConstraint(fields=["group", "workspace"], name="unique_workspace_auth_domain")] def __str__(self): """String method for WorkspaceAuthorizationDomains""" - return "Auth domain {group} for {workspace}".format( - group=self.group.name, workspace=self.workspace - ) + return "Auth domain {group} for {workspace}".format(group=self.group.name, workspace=self.workspace) class GroupGroupMembership(TimeStampedModel): @@ -1018,12 +912,8 @@ class GroupGroupMembership(TimeStampedModel): (ADMIN, "Admin"), ] - parent_group = models.ForeignKey( - "ManagedGroup", on_delete=models.CASCADE, related_name="child_memberships" - ) - child_group = models.ForeignKey( - "ManagedGroup", on_delete=models.PROTECT, related_name="parent_memberships" - ) + parent_group = models.ForeignKey("ManagedGroup", on_delete=models.CASCADE, related_name="child_memberships") + child_group = models.ForeignKey("ManagedGroup", on_delete=models.PROTECT, related_name="parent_memberships") role = models.CharField(max_length=10, choices=ROLE_CHOICES, default=MEMBER) history = HistoricalRecords() @@ -1073,15 +963,11 @@ def clean(self): def anvil_create(self): """Add the child group to the parent group on AnVIL.""" - AnVILAPIClient().add_user_to_group( - self.parent_group.name, self.role.lower(), self.child_group.email - ) + AnVILAPIClient().add_user_to_group(self.parent_group.name, self.role.lower(), self.child_group.email) def anvil_delete(self): """Remove the child group from the parent on AnVIL""" - AnVILAPIClient().remove_user_from_group( - self.parent_group.name, self.role.lower(), self.child_group.email - ) + AnVILAPIClient().remove_user_from_group(self.parent_group.name, self.role.lower(), self.child_group.email) class GroupAccountMembership(TimeStampedModel): @@ -1105,11 +991,7 @@ class GroupAccountMembership(TimeStampedModel): class Meta: verbose_name = "group-account membership" - constraints = [ - models.UniqueConstraint( - fields=["account", "group"], name="unique_group_account_membership" - ) - ] + constraints = [models.UniqueConstraint(fields=["account", "group"], name="unique_group_account_membership")] def __str__(self): return "{account} as {role} in {group}".format( @@ -1126,15 +1008,11 @@ def get_absolute_url(self): def anvil_create(self): """Add the account to the group on AnVIL.""" - AnVILAPIClient().add_user_to_group( - self.group.name, self.role.lower(), self.account.email - ) + AnVILAPIClient().add_user_to_group(self.group.name, self.role.lower(), self.account.email) def anvil_delete(self): """Remove the account from the group on AnVIL""" - AnVILAPIClient().remove_user_from_group( - self.group.name, self.role.lower(), self.account.email - ) + AnVILAPIClient().remove_user_from_group(self.group.name, self.role.lower(), self.account.email) class WorkspaceGroupSharing(TimeStampedModel): @@ -1190,11 +1068,7 @@ class Meta: # NOTE - we intentionally have left the name of the constraint # as group_access instead of updating to group_sharing to get around # django bug: #31335 - when the fix for this is patched in we can update - constraints = [ - models.UniqueConstraint( - fields=["group", "workspace"], name="unique_workspace_group_access" - ) - ] + constraints = [models.UniqueConstraint(fields=["group", "workspace"], name="unique_workspace_group_access")] def __str__(self): """String method for this object. @@ -1250,9 +1124,7 @@ def anvil_create_or_update(self): self.workspace.billing_project.name, self.workspace.name, acl_updates ) if len(response.json()["usersNotFound"]) > 0: - raise exceptions.AnVILGroupNotFound( - "{} not found on AnVIL".format(self.group) - ) + raise exceptions.AnVILGroupNotFound("{} not found on AnVIL".format(self.group)) def anvil_delete(self): """Remove the access to ``workspace`` for the ``group`` on AnVIL.""" @@ -1266,6 +1138,4 @@ def anvil_delete(self): } ] # It is ok if we try to remove access for a group that doesn't exist on AnVIL. - AnVILAPIClient().update_workspace_acl( - self.workspace.billing_project.name, self.workspace.name, acl_updates - ) + AnVILAPIClient().update_workspace_acl(self.workspace.billing_project.name, self.workspace.name, acl_updates) diff --git a/anvil_consortium_manager/tests/api_factories.py b/anvil_consortium_manager/tests/api_factories.py index e61ddd77..35d03329 100644 --- a/anvil_consortium_manager/tests/api_factories.py +++ b/anvil_consortium_manager/tests/api_factories.py @@ -34,9 +34,7 @@ class ErrorResponseFactory(MockAPIResponseFactory): class GroupDetailsFactory(factory.DictFactory): groupName = factory.Faker("word") - groupEmail = factory.LazyAttribute( - lambda obj: "{}@firecloud.org".format(obj.groupName) - ) + groupEmail = factory.LazyAttribute(lambda obj: "{}@firecloud.org".format(obj.groupName)) role = FuzzyChoice(["admin", "member"]) @@ -61,9 +59,7 @@ class Meta: # Neither of these worked. # response = "foo" # response = factory.RelatedFactoryList(GetGroupDetailsFactory, size=3) - response = factory.LazyAttribute( - lambda o: [GroupDetailsFactory() for _ in range(o.n_groups)] - ) + response = factory.LazyAttribute(lambda o: [GroupDetailsFactory() for _ in range(o.n_groups)]) class Params: n_groups = 0 @@ -71,9 +67,7 @@ class Params: class GetGroupMembershipResponseFactory(MockAPIResponseFactory): - response = factory.LazyAttribute( - lambda o: [fake.email() for _ in range(o.n_emails)] - ) + response = factory.LazyAttribute(lambda o: [fake.email() for _ in range(o.n_emails)]) class Params: n_emails = 0 @@ -83,6 +77,4 @@ class GetGroupMembershipAdminResponseFactory(GetGroupMembershipResponseFactory): @classmethod def _after_postgeneration(cls, obj, create, results=None): """Populate the response with the service account email.""" - obj.response = obj.response + [ - anvil_api.AnVILAPIClient().auth_session.credentials.service_account_email - ] + obj.response = obj.response + [anvil_api.AnVILAPIClient().auth_session.credentials.service_account_email] diff --git a/anvil_consortium_manager/tests/factories.py b/anvil_consortium_manager/tests/factories.py index 5eabfc38..a959aac6 100644 --- a/anvil_consortium_manager/tests/factories.py +++ b/anvil_consortium_manager/tests/factories.py @@ -36,9 +36,7 @@ class UserEmailEntryFactory(DjangoModelFactory): email = Faker("email") user = SubFactory(UserFactory) - date_verification_email_sent = Faker( - "date_time", tzinfo=timezone.get_current_timezone() - ) + date_verification_email_sent = Faker("date_time", tzinfo=timezone.get_current_timezone()) class Meta: model = models.UserEmailEntry @@ -72,9 +70,7 @@ class Params: UserEmailEntryFactory, email=SelfAttribute("..email"), user=SelfAttribute("..user"), - date_verified=Faker( - "date_time", tzinfo=timezone.get_current_timezone() - ), + date_verified=Faker("date_time", tzinfo=timezone.get_current_timezone()), ), ) diff --git a/anvil_consortium_manager/tests/integration/integration_tests_anvil_api.py b/anvil_consortium_manager/tests/integration/integration_tests_anvil_api.py index 8bc33a4e..75daad66 100644 --- a/anvil_consortium_manager/tests/integration/integration_tests_anvil_api.py +++ b/anvil_consortium_manager/tests/integration/integration_tests_anvil_api.py @@ -171,35 +171,23 @@ def test_group_membership(self): # Try adding the user as a member to a group that doesn't exist. # This is undocumented in the API. response = self.client.add_user_to_group(test_group_1, "MEMBER", test_user) - self.assertEqual( - response.status_code, 204 - ) # Interesting - I'm surprised this isn't a 404. + self.assertEqual(response.status_code, 204) # Interesting - I'm surprised this isn't a 404. self.assertEqual(response.text, "") # Try removing a user from a group that doesn't exist. # This is undocumented in the API. response = self.client.remove_user_from_group(test_group_1, "MEMBER", test_user) - self.assertEqual( - response.status_code, 204 - ) # Interesting - I'm surprised this isn't a 404. + self.assertEqual(response.status_code, 204) # Interesting - I'm surprised this isn't a 404. self.assertEqual(response.text, "") # Try adding a group that doesn't exist as a member to another group that doesn't exist. # This is undocumented in the API. - response = self.client.add_user_to_group( - test_group_1, "MEMBER", test_group_2 + "@firecloud.org" - ) - self.assertEqual( - response.status_code, 204 - ) # Interesting - I'm surprised this isn't a 404. + response = self.client.add_user_to_group(test_group_1, "MEMBER", test_group_2 + "@firecloud.org") + self.assertEqual(response.status_code, 204) # Interesting - I'm surprised this isn't a 404. self.assertEqual(response.text, "") # Try removing a user from a group that doesn't exist. # This is undocumented in the API. - response = self.client.remove_user_from_group( - test_group_1, "MEMBER", test_group_2 + "@firecloud.org" - ) - self.assertEqual( - response.status_code, 204 - ) # Interesting - I'm surprised this isn't a 404. + response = self.client.remove_user_from_group(test_group_1, "MEMBER", test_group_2 + "@firecloud.org") + self.assertEqual(response.status_code, 204) # Interesting - I'm surprised this isn't a 404. self.assertEqual(response.text, "") # Create the group. @@ -211,18 +199,14 @@ def test_group_membership(self): # with self.assertRaises(anvil_api.AnVILAPIError404): # response = self.client.add_user_to_group(test_group_1, "MEMBER", "asdfghjkl@asdfghjkl.com") # ACTUAL behavior: - response = self.client.add_user_to_group( - test_group_1, "MEMBER", "asdfghjkl@asdfghjkl.com" - ) + response = self.client.add_user_to_group(test_group_1, "MEMBER", "asdfghjkl@asdfghjkl.com") self.assertEqual(response.status_code, 204) # Remove a user that doesn't exist from the group. # EXPECTED behavior: # with self.assertRaises(anvil_api.AnVILAPIError404): # response = self.client.remove_user_from_group(test_group_1, "MEMBER", "asdfghjkl@asdfghjkl.com") # ACTUAL behavior: - response = self.client.remove_user_from_group( - test_group_1, "MEMBER", "asdfghjkl@asdfghjkl.com" - ) + response = self.client.remove_user_from_group(test_group_1, "MEMBER", "asdfghjkl@asdfghjkl.com") self.assertEqual(response.status_code, 204) # Add a user that exists to the group. @@ -309,18 +293,14 @@ def test_group_membership(self): # with self.assertRaises(anvil_api.AnVILAPIError404): # response = self.client.add_user_to_group(test_group_1, "MEMBER", test_group_2 + "@firecloud.org") # ACTUAL behavior: - response = self.client.add_user_to_group( - test_group_1, "MEMBER", test_group_2 + "@firecloud.org" - ) + response = self.client.add_user_to_group(test_group_1, "MEMBER", test_group_2 + "@firecloud.org") self.assertEqual(response.status_code, 204) # Remove a group that doesn't exist from the group. # EXPECTED behavior: # with self.assertRaises(anvil_api.AnVILAPIError404): # response = self.client.remove_user_from_group(test_group_1, "MEMBER", test_group_2 + "@firecloud.org") # ACTUAL behavior: - response = self.client.remove_user_from_group( - test_group_1, "MEMBER", test_group_2 + "@firecloud.org" - ) + response = self.client.remove_user_from_group(test_group_1, "MEMBER", test_group_2 + "@firecloud.org") self.assertEqual(response.status_code, 204) # Create another group. @@ -328,38 +308,26 @@ def test_group_membership(self): self.assertEqual(response.status_code, 201) # Add the second group to the first group as a MEMBER. - response = self.client.add_user_to_group( - test_group_1, "MEMBER", test_group_2 + "@firecloud.org" - ) + response = self.client.add_user_to_group(test_group_1, "MEMBER", test_group_2 + "@firecloud.org") self.assertEqual(response.status_code, 204) # Check group membership. response = self.client.get_group(test_group_1) json = response.json() self.assertIn("adminsEmails", json.keys()) - self.assertNotIn( - test_group_2 + "@firecloud.org", json["adminsEmails"] - ) # Not an admin. + self.assertNotIn(test_group_2 + "@firecloud.org", json["adminsEmails"]) # Not an admin. self.assertIn("membersEmails", json.keys()) - self.assertIn( - test_group_2 + "@firecloud.org", json["membersEmails"] - ) # Added as a member. + self.assertIn(test_group_2 + "@firecloud.org", json["membersEmails"]) # Added as a member. # Remove the second group from the first group. - response = self.client.remove_user_from_group( - test_group_1, "MEMBER", test_group_2 + "@firecloud.org" - ) + response = self.client.remove_user_from_group(test_group_1, "MEMBER", test_group_2 + "@firecloud.org") self.assertEqual(response.status_code, 204) # Check group membership. response = self.client.get_group(test_group_1) json = response.json() self.assertIn("adminsEmails", json.keys()) - self.assertNotIn( - test_group_2 + "@firecloud.org", json["adminsEmails"] - ) # Still not an admin. + self.assertNotIn(test_group_2 + "@firecloud.org", json["adminsEmails"]) # Still not an admin. self.assertIn("membersEmails", json.keys()) - self.assertNotIn( - test_group_2 + "@firecloud.org", json["membersEmails"] - ) # No longer a member. + self.assertNotIn(test_group_2 + "@firecloud.org", json["membersEmails"]) # No longer a member. # Add the user to a group that we don't have permission for. response = self.client.add_user_to_group("test-group", "MEMBER", test_user) @@ -374,21 +342,13 @@ def test_group_membership(self): self.client.delete_group(test_group_1) # Add a group that exists to a group that doesn't exist. - response = self.client.add_user_to_group( - test_group_1, "MEMBER", test_group_2 + "@firecloud.org" - ) - self.assertEqual( - response.status_code, 204 - ) # Interesting - I'm surprised this isn't a 404. + response = self.client.add_user_to_group(test_group_1, "MEMBER", test_group_2 + "@firecloud.org") + self.assertEqual(response.status_code, 204) # Interesting - I'm surprised this isn't a 404. self.assertEqual(response.text, "") # Try removing a group that exists from a group that doesn't exist. # This is undocumented in the API. - response = self.client.remove_user_from_group( - test_group_1, "MEMBER", test_group_2 + "@firecloud.org" - ) - self.assertEqual( - response.status_code, 204 - ) # Interesting - I'm surprised this isn't a 404. + response = self.client.remove_user_from_group(test_group_1, "MEMBER", test_group_2 + "@firecloud.org") + self.assertEqual(response.status_code, 204) # Interesting - I'm surprised this isn't a 404. self.assertEqual(response.text, "") # Delete the second group. @@ -465,12 +425,8 @@ def test_workspace_auth_domains(self): self.client.auth_session.delete, "workspaces/" + test_billing_project + "/" + test_workspace, ) - self.addCleanup( - self.client.auth_session.delete, "api/groups/" + test_auth_domain_1 - ) - self.addCleanup( - self.client.auth_session.delete, "api/groups/" + test_auth_domain_2 - ) + self.addCleanup(self.client.auth_session.delete, "api/groups/" + test_auth_domain_1) + self.addCleanup(self.client.auth_session.delete, "api/groups/" + test_auth_domain_2) # Create a workspace with an auth domain group that doesn't exist. Should fail. with self.assertRaises(anvil_api.AnVILAPIError400): @@ -485,9 +441,7 @@ def test_workspace_auth_domains(self): self.client.create_workspace( test_billing_project, test_workspace, - authorization_domains=[ - "adrienne-test" - ], # The service account is not a member of this group. + authorization_domains=["adrienne-test"], # The service account is not a member of this group. ) # Create the auth domain group. @@ -578,26 +532,20 @@ def test_workspace_sharing(self): # with self.assertRaises(anvil_api.AnVILAPIError404): # self.client.update_workspace_acl(test_billing_project, test_workspace, acl_updates) # ACTUAL behavior. - response = self.client.update_workspace_acl( - test_billing_project, test_workspace, acl_updates - ) + response = self.client.update_workspace_acl(test_billing_project, test_workspace, acl_updates) self.assertEqual(response.status_code, 200) json = response.json() self.assertIn("usersUpdated", json.keys()) self.assertEqual(json["usersUpdated"], []) self.assertIn("usersNotFound", json.keys()) self.assertEqual(len(json["usersNotFound"]), 1) - self.assertEqual( - json["usersNotFound"][0]["email"], test_group + "@firecloud.org" - ) + self.assertEqual(json["usersNotFound"][0]["email"], test_group + "@firecloud.org") self.assertIn("invitesSent", json.keys()) self.assertEqual(json["invitesSent"], []) # Check ACLs for a workspace that doesn't exist. with self.assertRaises(anvil_api.AnVILAPIError404): - response = self.client.get_workspace_acl( - test_billing_project, test_workspace - ) + response = self.client.get_workspace_acl(test_billing_project, test_workspace) # Create the workspace. response = self.client.create_workspace(test_billing_project, test_workspace) @@ -617,18 +565,14 @@ def test_workspace_sharing(self): # self.assertEqual(group_acl['pending'], False) # Try to add a group that doesn't exist to the workspace. - response = self.client.update_workspace_acl( - test_billing_project, test_workspace, acl_updates - ) + response = self.client.update_workspace_acl(test_billing_project, test_workspace, acl_updates) self.assertEqual(response.status_code, 200) json = response.json() self.assertIn("usersUpdated", json.keys()) self.assertEqual(json["usersUpdated"], []) self.assertIn("usersNotFound", json.keys()) self.assertEqual(len(json["usersNotFound"]), 1) - self.assertEqual( - json["usersNotFound"][0]["email"], test_group + "@firecloud.org" - ) + self.assertEqual(json["usersNotFound"][0]["email"], test_group + "@firecloud.org") self.assertIn("invitesSent", json.keys()) self.assertEqual(json["invitesSent"], []) @@ -644,16 +588,12 @@ def test_workspace_sharing(self): response = self.client.create_group(test_group) # Share the workspace with the group. - response = self.client.update_workspace_acl( - test_billing_project, test_workspace, acl_updates - ) + response = self.client.update_workspace_acl(test_billing_project, test_workspace, acl_updates) self.assertEqual(response.status_code, 200) json = response.json() self.assertIn("usersUpdated", json.keys()) self.assertEqual(len(json["usersUpdated"]), 1) - self.assertEqual( - json["usersUpdated"][0]["email"], test_group + "@firecloud.org" - ) + self.assertEqual(json["usersUpdated"][0]["email"], test_group + "@firecloud.org") self.assertEqual(json["usersUpdated"][0]["accessLevel"], "READER") self.assertIn("usersNotFound", json.keys()) self.assertEqual(json["usersNotFound"], []) @@ -666,9 +606,7 @@ def test_workspace_sharing(self): self.assertIn("acl", json.keys()) self.assertEqual(len(json["acl"]), 2) self.assertIn(owner, json["acl"]) - self.assertEqual( - json["acl"][owner], owner_acl - ) # Service account permissions haven't changed. + self.assertEqual(json["acl"][owner], owner_acl) # Service account permissions haven't changed. self.assertIn(test_group + "@firecloud.org", json["acl"]) group_acl = json["acl"][test_group + "@firecloud.org"] self.assertIn("accessLevel", group_acl) @@ -678,9 +616,7 @@ def test_workspace_sharing(self): self.assertEqual(group_acl["pending"], False) # Share the workspace with the group a second time. - response = self.client.update_workspace_acl( - test_billing_project, test_workspace, acl_updates - ) + response = self.client.update_workspace_acl(test_billing_project, test_workspace, acl_updates) self.assertEqual(response.status_code, 200) json = response.json() self.assertIn("usersUpdated", json.keys()) @@ -696,9 +632,7 @@ def test_workspace_sharing(self): self.assertIn("acl", json.keys()) self.assertEqual(len(json["acl"]), 2) self.assertIn(owner, json["acl"]) - self.assertEqual( - json["acl"][owner], owner_acl - ) # Service account permissions haven't changed. + self.assertEqual(json["acl"][owner], owner_acl) # Service account permissions haven't changed. self.assertIn(test_group + "@firecloud.org", json["acl"]) group_acl = json["acl"][test_group + "@firecloud.org"] self.assertIn("accessLevel", group_acl) @@ -709,16 +643,12 @@ def test_workspace_sharing(self): # Change the group's access to WRITER. acl_updates[0]["accessLevel"] = "WRITER" - response = self.client.update_workspace_acl( - test_billing_project, test_workspace, acl_updates - ) + response = self.client.update_workspace_acl(test_billing_project, test_workspace, acl_updates) self.assertEqual(response.status_code, 200) json = response.json() self.assertIn("usersUpdated", json.keys()) self.assertEqual(len(json["usersUpdated"]), 1) - self.assertEqual( - json["usersUpdated"][0]["email"], test_group + "@firecloud.org" - ) + self.assertEqual(json["usersUpdated"][0]["email"], test_group + "@firecloud.org") self.assertEqual(json["usersUpdated"][0]["accessLevel"], "WRITER") self.assertIn("usersNotFound", json.keys()) self.assertEqual(json["usersNotFound"], []) @@ -731,9 +661,7 @@ def test_workspace_sharing(self): self.assertIn("acl", json.keys()) self.assertEqual(len(json["acl"]), 2) self.assertIn(owner, json["acl"]) - self.assertEqual( - json["acl"][owner], owner_acl - ) # Service account permissions haven't changed. + self.assertEqual(json["acl"][owner], owner_acl) # Service account permissions haven't changed. self.assertIn(test_group + "@firecloud.org", json["acl"]) group_acl = json["acl"][test_group + "@firecloud.org"] self.assertIn("accessLevel", group_acl) @@ -745,22 +673,16 @@ def test_workspace_sharing(self): # Try to share the workspace with an invalid access level. acl_updates[0]["accessLevel"] = "foo" with self.assertRaises(anvil_api.AnVILAPIError400): - self.client.update_workspace_acl( - test_billing_project, test_workspace, acl_updates - ) + self.client.update_workspace_acl(test_billing_project, test_workspace, acl_updates) # Remove the group's access to the workspace. acl_updates[0]["accessLevel"] = "NO ACCESS" - response = self.client.update_workspace_acl( - test_billing_project, test_workspace, acl_updates - ) + response = self.client.update_workspace_acl(test_billing_project, test_workspace, acl_updates) self.assertEqual(response.status_code, 200) json = response.json() self.assertIn("usersUpdated", json.keys()) self.assertEqual(len(json["usersUpdated"]), 1) - self.assertEqual( - json["usersUpdated"][0]["email"], test_group + "@firecloud.org" - ) + self.assertEqual(json["usersUpdated"][0]["email"], test_group + "@firecloud.org") self.assertEqual(json["usersUpdated"][0]["accessLevel"], "NO ACCESS") self.assertIn("usersNotFound", json.keys()) self.assertEqual(json["usersNotFound"], []) @@ -773,9 +695,7 @@ def test_workspace_sharing(self): self.assertIn("acl", json.keys()) self.assertEqual(len(json["acl"]), 1) self.assertIn(owner, json["acl"]) - self.assertEqual( - json["acl"][owner], owner_acl - ) # Service account permissions haven't changed. + self.assertEqual(json["acl"][owner], owner_acl) # Service account permissions haven't changed. self.assertNotIn(test_group + "@firecloud.org", json["acl"]) # Delete the workspace. @@ -785,9 +705,7 @@ def test_workspace_sharing(self): # Try to share the workspace (which does not exist) with the group (which exists). acl_updates[0]["accessLevel"] = "READER" with self.assertRaises(anvil_api.AnVILAPIError404): - self.client.update_workspace_acl( - test_billing_project, test_workspace, acl_updates - ) + self.client.update_workspace_acl(test_billing_project, test_workspace, acl_updates) # Delete the group self.client.delete_group(test_group) diff --git a/anvil_consortium_manager/tests/settings/test.py b/anvil_consortium_manager/tests/settings/test.py index d227d31c..6ed4ac80 100644 --- a/anvil_consortium_manager/tests/settings/test.py +++ b/anvil_consortium_manager/tests/settings/test.py @@ -30,9 +30,7 @@ DATABASES = { "default": { - "ENGINE": "django.db.backends.{}".format( - os.getenv("DBBACKEND", default="sqlite3") - ), + "ENGINE": "django.db.backends.{}".format(os.getenv("DBBACKEND", default="sqlite3")), "NAME": os.getenv("DBNAME", default="anvil_consortium_manager"), "USER": os.getenv("DBUSER", default="django"), "PASSWORD": os.getenv("DBPASSWORD", default="password"), @@ -145,6 +143,4 @@ ANVIL_WORKSPACE_ADAPTERS = [ "anvil_consortium_manager.adapters.default.DefaultWorkspaceAdapter", ] -ANVIL_ACCOUNT_ADAPTER = ( - "anvil_consortium_manager.adapters.default.DefaultAccountAdapter" -) +ANVIL_ACCOUNT_ADAPTER = "anvil_consortium_manager.adapters.default.DefaultAccountAdapter" diff --git a/anvil_consortium_manager/tests/settings/urls.py b/anvil_consortium_manager/tests/settings/urls.py index 149e5a5a..48ad199b 100644 --- a/anvil_consortium_manager/tests/settings/urls.py +++ b/anvil_consortium_manager/tests/settings/urls.py @@ -7,17 +7,13 @@ # Unprotected URL for testing login redirect without a template. path( "test_login/", - TemplateView.as_view( - template_name="../templates/anvil_consortium_manager/index.html" - ), + TemplateView.as_view(template_name="../templates/anvil_consortium_manager/index.html"), name="test_login", ), # Unprotected view for testing redirects. path( "test_home/", - TemplateView.as_view( - template_name="../templates/anvil_consortium_manager/index.html" - ), + TemplateView.as_view(template_name="../templates/anvil_consortium_manager/index.html"), name="test_home", ), # These urls. diff --git a/anvil_consortium_manager/tests/test_adapters.py b/anvil_consortium_manager/tests/test_adapters.py index f5a54456..5190ff2b 100644 --- a/anvil_consortium_manager/tests/test_adapters.py +++ b/anvil_consortium_manager/tests/test_adapters.py @@ -50,17 +50,13 @@ def test_list_table_class_none(self): def test_list_filterset_class_default(self): """get_list_filterset_class returns the correct filter when using the default adapter.""" - self.assertEqual( - DefaultAccountAdapter().get_list_filterset_class(), AccountListFilter - ) + self.assertEqual(DefaultAccountAdapter().get_list_filterset_class(), AccountListFilter) def test_list_filterset_class_custom(self): """get_list_filterset_class returns the correct filter when using a custom adapter.""" TestAdapter = self.get_test_adapter() setattr(TestAdapter, "list_filterset_class", filters.TestAccountListFilter) - self.assertEqual( - TestAdapter().get_list_filterset_class(), filters.TestAccountListFilter - ) + self.assertEqual(TestAdapter().get_list_filterset_class(), filters.TestAccountListFilter) def test_list_filterset_class_none(self): """get_list_filterset_class raises ImproperlyConfigured when get_list_filterset_class is not set.""" @@ -91,9 +87,7 @@ def test_get_autocomplete_queryset_default(self): """get_autocomplete_queryset returns the correct queryset when using the default adapter.""" account_1 = factories.AccountFactory.create(email="test@test.com") account_2 = factories.AccountFactory.create(email="foo@bar.com") - qs = DefaultAccountAdapter().get_autocomplete_queryset( - Account.objects.all(), "test" - ) + qs = DefaultAccountAdapter().get_autocomplete_queryset(Account.objects.all(), "test") self.assertEqual(qs.count(), 1) self.assertIn(account_1, qs) self.assertNotIn(account_2, qs) @@ -116,16 +110,12 @@ def foo(self, queryset, q): def test_get_autocomplete_label_default(self): """get_label_from_instance returns the correct queryset when using the default adapter.""" account = factories.AccountFactory.create(email="test@test.com") - self.assertEqual( - DefaultAccountAdapter().get_autocomplete_label(account), "test@test.com" - ) + self.assertEqual(DefaultAccountAdapter().get_autocomplete_label(account), "test@test.com") def test_get_autocomplete_label_custom(self): """get_label_from_instance returns the correct queryset when using a custom adapter.""" - account = factories.AccountFactory.create( - verified=True, user__username="testuser" - ) + account = factories.AccountFactory.create(verified=True, user__username="testuser") def foo(self, account): return account.user.username @@ -155,17 +145,13 @@ class TestAdapter(BaseWorkspaceAdapter): def test_list_table_class_default(self): """get_list_table_class returns the correct table when using the default adapter.""" - self.assertEqual( - DefaultWorkspaceAdapter().get_list_table_class(), WorkspaceTable - ) + self.assertEqual(DefaultWorkspaceAdapter().get_list_table_class(), WorkspaceTable) def test_list_table_class_custom(self): """get_list_table_class returns the correct table when using a custom adapter.""" TestAdapter = self.get_test_adapter() setattr(TestAdapter, "list_table_class", tables.TestWorkspaceDataTable) - self.assertEqual( - TestAdapter().get_list_table_class(), tables.TestWorkspaceDataTable - ) + self.assertEqual(TestAdapter().get_list_table_class(), tables.TestWorkspaceDataTable) def test_list_table_class_none(self): """get_list_table_class raises ImproperlyConfigured when list_table_class is not set.""" @@ -185,9 +171,7 @@ def test_get_workspace_form_class_custom(self): """get_workspace_form_class returns the correct form when using a custom adapter.""" TestAdapter = self.get_test_adapter() setattr(TestAdapter, "workspace_form_class", forms.TestWorkspaceForm) - self.assertEqual( - TestAdapter().get_workspace_form_class(), forms.TestWorkspaceForm - ) + self.assertEqual(TestAdapter().get_workspace_form_class(), forms.TestWorkspaceForm) def test_get_workspace_form_class_none(self): """get_workspace_form_class raises exception if form class is not set.""" @@ -233,9 +217,7 @@ def test_get_workspace_data_form_class_custom(self): """get_workspace_data_form_class returns the correct form when using a custom adapter.""" TestAdapter = self.get_test_adapter() setattr(TestAdapter, "workspace_data_form_class", forms.TestWorkspaceDataForm) - self.assertEqual( - TestAdapter().get_workspace_data_form_class(), forms.TestWorkspaceDataForm - ) + self.assertEqual(TestAdapter().get_workspace_data_form_class(), forms.TestWorkspaceDataForm) def test_get_workspace_data_form_class_none(self): """get_workspace_data_form_class raises exception if form class is not set.""" @@ -259,17 +241,13 @@ class Meta: def test_get_workspace_data_model_default(self): """get_workspace_data_model returns the correct model when using the default adapter.""" - self.assertEqual( - DefaultWorkspaceAdapter().get_workspace_data_model(), DefaultWorkspaceData - ) + self.assertEqual(DefaultWorkspaceAdapter().get_workspace_data_model(), DefaultWorkspaceData) def test_get_workspace_data_model_custom(self): """get_workspace_data_model returns the correct model when using a custom adapter.""" TestAdapter = self.get_test_adapter() setattr(TestAdapter, "workspace_data_model", models.TestWorkspaceData) - self.assertEqual( - TestAdapter().get_workspace_data_model(), models.TestWorkspaceData - ) + self.assertEqual(TestAdapter().get_workspace_data_model(), models.TestWorkspaceData) def test_get_workspace_data_model_subclass(self): """workspace_data_model must be a subclass of models.BaseWorkspaceData""" diff --git a/anvil_consortium_manager/tests/test_app/models.py b/anvil_consortium_manager/tests/test_app/models.py index 2f3c5f8d..091c4014 100644 --- a/anvil_consortium_manager/tests/test_app/models.py +++ b/anvil_consortium_manager/tests/test_app/models.py @@ -1,11 +1,6 @@ from django.db import models -from anvil_consortium_manager.models import ( - BaseWorkspaceData, - DefaultWorkspaceData, - ManagedGroup, - Workspace, -) +from anvil_consortium_manager.models import BaseWorkspaceData, DefaultWorkspaceData, ManagedGroup, Workspace # Create your models here. diff --git a/anvil_consortium_manager/tests/test_audit.py b/anvil_consortium_manager/tests/test_audit.py index 1a6c4427..d7c321dd 100644 --- a/anvil_consortium_manager/tests/test_audit.py +++ b/anvil_consortium_manager/tests/test_audit.py @@ -238,9 +238,7 @@ def test_add_result_second_result_for_same_model_instance(self): with self.assertRaises(ValueError): self.audit_results.add_result(model_instance_result_2) self.assertEqual(len(self.audit_results._model_instance_results), 1) - self.assertEqual( - self.audit_results._model_instance_results, [model_instance_result_1] - ) + self.assertEqual(self.audit_results._model_instance_results, [model_instance_result_1]) def test_add_result_second_result_for_same_model_instance_with_error(self): obj = self.model_factory() @@ -251,9 +249,7 @@ def test_add_result_second_result_for_same_model_instance_with_error(self): with self.assertRaises(ValueError): self.audit_results.add_result(model_instance_result_2) self.assertEqual(len(self.audit_results._model_instance_results), 1) - self.assertEqual( - self.audit_results._model_instance_results, [model_instance_result_1] - ) + self.assertEqual(self.audit_results._model_instance_results, [model_instance_result_1]) def test_get_result_for_model_instance_no_matches(self): obj = self.model_factory() @@ -286,12 +282,8 @@ def test_get_error_results_two_verified_result(self): model_instance_result_2 = audit.ModelInstanceResult(self.model_factory()) self.audit_results.add_result(model_instance_result_2) self.assertEqual(len(self.audit_results.get_verified_results()), 2) - self.assertIn( - model_instance_result_1, self.audit_results.get_verified_results() - ) - self.assertIn( - model_instance_result_2, self.audit_results.get_verified_results() - ) + self.assertIn(model_instance_result_1, self.audit_results.get_verified_results()) + self.assertIn(model_instance_result_2, self.audit_results.get_verified_results()) def test_get_verified_results_one_error_result(self): """get_verified_results returns a list of lenght zero when there is one error result.""" @@ -441,11 +433,7 @@ class BillingProjectAuditTest(AnVILAPIMockTestMixin, TestCase): """Tests for the BillingProject.anvil_audit method.""" def get_api_url(self, billing_project_name): - return ( - self.api_client.rawls_entry_point - + "/api/billing/v2/" - + billing_project_name - ) + return self.api_client.rawls_entry_point + "/api/billing/v2/" + billing_project_name def get_api_json_response(self): return { @@ -776,15 +764,11 @@ def get_api_groups_url(self): def get_api_url_members(self, group_name): """Return the API url being called by the method.""" - return ( - self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/member" - ) + return self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/member" def get_api_url_admins(self, group_name): """Return the API url being called by the method.""" - return ( - self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/admin" - ) + return self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/admin" def test_anvil_audit_no_groups(self): """anvil_audit works correct if there are no ManagedGroups in the app.""" @@ -902,11 +886,7 @@ def test_anvil_audit_one_group_not_managed_by_app_no_errors_uppercase_role(self) api_url, status=200, json=api_factories.GetGroupsResponseFactory( - response=[ - api_factories.GroupDetailsFactory( - groupName=group.name, role="Member" - ) - ] + response=[api_factories.GroupDetailsFactory(groupName=group.name, role="Member")] ).response, ) audit_results = audit.ManagedGroupAudit() @@ -997,9 +977,7 @@ def test_anvil_audit_one_group_managed_by_app_on_anvil_but_app_not_in_group(self self.assertEqual(len(audit_results.get_not_in_app_results()), 0) record_result = audit_results.get_result_for_model_instance(group) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_DIFFERENT_ROLE]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_DIFFERENT_ROLE])) def test_anvil_audit_one_group_admin_in_app_member_on_anvil(self): """anvil_audit raises exception if one group exists in the app as an admin but the role on AnVIL is member.""" @@ -1021,9 +999,7 @@ def test_anvil_audit_one_group_admin_in_app_member_on_anvil(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) record_result = audit_results.get_result_for_model_instance(group) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_DIFFERENT_ROLE]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_DIFFERENT_ROLE])) def test_anvil_audit_one_group_member_in_app_admin_on_anvil(self): """anvil_audit raises exception if one group exists in the app as an member but the role on AnVIL is admin.""" @@ -1045,9 +1021,7 @@ def test_anvil_audit_one_group_member_in_app_admin_on_anvil(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) record_result = audit_results.get_result_for_model_instance(group) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_DIFFERENT_ROLE]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_DIFFERENT_ROLE])) def test_anvil_audit_two_groups_no_errors(self): """anvil_audit works correctly if if two groups exist in both the app and AnVIL.""" @@ -1226,9 +1200,7 @@ def test_anvil_audit_one_group_member_missing_in_app(self): api_url, status=200, json=api_factories.GetGroupsResponseFactory( - response=[ - api_factories.GroupDetailsMemberFactory(groupName="test-group") - ] + response=[api_factories.GroupDetailsMemberFactory(groupName="test-group")] ).response, ) audit_results = audit.ManagedGroupAudit() @@ -1246,9 +1218,7 @@ def test_anvil_audit_one_group_admin_missing_in_app(self): api_url, status=200, json=api_factories.GetGroupsResponseFactory( - response=[ - api_factories.GroupDetailsAdminFactory(groupName="test-group") - ] + response=[api_factories.GroupDetailsAdminFactory(groupName="test-group")] ).response, ) audit_results = audit.ManagedGroupAudit() @@ -1320,9 +1290,7 @@ def test_fails_membership_audit(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) record_result = audit_results.get_result_for_model_instance(group) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_GROUP_MEMBERSHIP]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_GROUP_MEMBERSHIP])) def test_admin_in_app_both_member_and_admin_on_anvil(self): """anvil_audit works correctly when the app is an admin and AnVIL returns both a member and admin record.""" @@ -1423,9 +1391,7 @@ def test_member_in_app_both_member_and_admin_on_anvil(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) record_result = audit_results.get_result_for_model_instance(group) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_DIFFERENT_ROLE]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_DIFFERENT_ROLE])) def test_member_in_app_both_member_and_admin_different_order_on_anvil(self): """anvil_audit works correctly when the app is a member and AnVIL returns both a member and admin record.""" @@ -1450,9 +1416,7 @@ def test_member_in_app_both_member_and_admin_different_order_on_anvil(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) record_result = audit_results.get_result_for_model_instance(group) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_DIFFERENT_ROLE]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_DIFFERENT_ROLE])) class ManagedGroupMembershipAuditTest(AnVILAPIMockTestMixin, TestCase): @@ -1460,15 +1424,11 @@ class ManagedGroupMembershipAuditTest(AnVILAPIMockTestMixin, TestCase): def get_api_url_members(self, group_name): """Return the API url being called by the method.""" - return ( - self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/member" - ) + return self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/member" def get_api_url_admins(self, group_name): """Return the API url being called by the method.""" - return ( - self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/admin" - ) + return self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/admin" def test_group_not_managed_by_app(self): group = factories.ManagedGroupFactory.create(is_managed_by_app=False) @@ -1508,9 +1468,7 @@ def test_one_account_members(self): responses.GET, api_url_members, status=200, - json=api_factories.GetGroupMembershipResponseFactory( - response=[membership.account.email] - ).response, + json=api_factories.GetGroupMembershipResponseFactory(response=[membership.account.email]).response, ) api_url_admins = self.get_api_url_admins(group.name) self.anvil_response_mock.add( @@ -1589,9 +1547,7 @@ def test_one_account_members_not_in_anvil(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) model_result = audit_results.get_result_for_model_instance(membership) self.assertFalse(model_result.ok()) - self.assertEqual( - model_result.errors, set([audit_results.ERROR_ACCOUNT_MEMBER_NOT_IN_ANVIL]) - ) + self.assertEqual(model_result.errors, set([audit_results.ERROR_ACCOUNT_MEMBER_NOT_IN_ANVIL])) def test_two_account_members_not_in_anvil(self): """anvil_audit works correctly if this group has two account member not in anvil.""" @@ -1620,15 +1576,11 @@ def test_two_account_members_not_in_anvil(self): model_result = audit_results.get_result_for_model_instance(membership_1) self.assertIsInstance(model_result, audit.ModelInstanceResult) self.assertFalse(model_result.ok()) - self.assertEqual( - model_result.errors, set([audit_results.ERROR_ACCOUNT_MEMBER_NOT_IN_ANVIL]) - ) + self.assertEqual(model_result.errors, set([audit_results.ERROR_ACCOUNT_MEMBER_NOT_IN_ANVIL])) model_result = audit_results.get_result_for_model_instance(membership_2) self.assertIsInstance(model_result, audit.ModelInstanceResult) self.assertFalse(model_result.ok()) - self.assertEqual( - model_result.errors, set([audit_results.ERROR_ACCOUNT_MEMBER_NOT_IN_ANVIL]) - ) + self.assertEqual(model_result.errors, set([audit_results.ERROR_ACCOUNT_MEMBER_NOT_IN_ANVIL])) self.assertEqual(len(audit_results.get_not_in_app_results()), 0) def test_one_account_members_not_in_app(self): @@ -1639,9 +1591,7 @@ def test_one_account_members_not_in_app(self): responses.GET, api_url_members, status=200, - json=api_factories.GetGroupMembershipResponseFactory( - response=["test-member@example.com"] - ).response, + json=api_factories.GetGroupMembershipResponseFactory(response=["test-member@example.com"]).response, ) api_url_admins = self.get_api_url_admins(group.name) self.anvil_response_mock.add( @@ -1705,9 +1655,7 @@ def test_one_account_members_case_insensitive(self): responses.GET, api_url_members, status=200, - json=api_factories.GetGroupMembershipResponseFactory( - response=["Test-Member@example.com"] - ).response, + json=api_factories.GetGroupMembershipResponseFactory(response=["Test-Member@example.com"]).response, ) api_url_admins = self.get_api_url_admins(group.name) self.anvil_response_mock.add( @@ -1743,9 +1691,7 @@ def test_one_account_admin(self): responses.GET, api_url_admins, status=200, - json=api_factories.GetGroupMembershipAdminResponseFactory( - response=[membership.account.email] - ).response, + json=api_factories.GetGroupMembershipAdminResponseFactory(response=[membership.account.email]).response, ) audit_results = audit.ManagedGroupMembershipAudit(group) audit_results.run_audit() @@ -1820,9 +1766,7 @@ def test_one_account_admin_not_in_anvil(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) record_result = audit_results.get_result_for_model_instance(membership) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_ACCOUNT_ADMIN_NOT_IN_ANVIL]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_ACCOUNT_ADMIN_NOT_IN_ANVIL])) def test_two_account_admins_not_in_anvil(self): """anvil_audit works correctly if this group has two account member not in anvil.""" @@ -1855,14 +1799,10 @@ def test_two_account_admins_not_in_anvil(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) record_result = audit_results.get_result_for_model_instance(membership_1) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_ACCOUNT_ADMIN_NOT_IN_ANVIL]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_ACCOUNT_ADMIN_NOT_IN_ANVIL])) record_result = audit_results.get_result_for_model_instance(membership_2) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_ACCOUNT_ADMIN_NOT_IN_ANVIL]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_ACCOUNT_ADMIN_NOT_IN_ANVIL])) def test_one_account_admin_not_in_app(self): """anvil_audit works correctly if this group has one account member not in the app.""" @@ -1879,9 +1819,7 @@ def test_one_account_admin_not_in_app(self): responses.GET, api_url_admins, status=200, - json=api_factories.GetGroupMembershipAdminResponseFactory( - response=["test-admin@example.com"] - ).response, + json=api_factories.GetGroupMembershipAdminResponseFactory(response=["test-admin@example.com"]).response, ) audit_results = audit.ManagedGroupMembershipAudit(group) audit_results.run_audit() @@ -1942,9 +1880,7 @@ def test_one_account_admin_case_insensitive(self): responses.GET, api_url_admins, status=200, - json=api_factories.GetGroupMembershipAdminResponseFactory( - response=["Test-Admin@example.com"] - ).response, + json=api_factories.GetGroupMembershipAdminResponseFactory(response=["Test-Admin@example.com"]).response, ) audit_results = audit.ManagedGroupMembershipAudit(group) audit_results.run_audit() @@ -1973,9 +1909,7 @@ def test_account_different_role_member_in_app_admin_in_anvil(self): responses.GET, api_url_admins, status=200, - json=api_factories.GetGroupMembershipAdminResponseFactory( - response=[membership.account.email] - ).response, + json=api_factories.GetGroupMembershipAdminResponseFactory(response=[membership.account.email]).response, ) audit_results = audit.ManagedGroupMembershipAudit(group) audit_results.run_audit() @@ -1985,9 +1919,7 @@ def test_account_different_role_member_in_app_admin_in_anvil(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 1) record_result = audit_results.get_result_for_model_instance(membership) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_ACCOUNT_MEMBER_NOT_IN_ANVIL]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_ACCOUNT_MEMBER_NOT_IN_ANVIL])) record_result = audit_results.get_not_in_app_results()[0] self.assertEqual(record_result.record, "ADMIN: " + membership.account.email) @@ -2000,9 +1932,7 @@ def test_one_group_members(self): responses.GET, api_url_members, status=200, - json=api_factories.GetGroupMembershipResponseFactory( - response=[membership.child_group.email] - ).response, + json=api_factories.GetGroupMembershipResponseFactory(response=[membership.child_group.email]).response, ) api_url_admins = self.get_api_url_admins(group.name) self.anvil_response_mock.add( @@ -2081,9 +2011,7 @@ def test_one_group_members_not_in_anvil(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) record_result = audit_results.get_result_for_model_instance(membership) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_GROUP_MEMBER_NOT_IN_ANVIL]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_GROUP_MEMBER_NOT_IN_ANVIL])) def test_two_group_members_not_in_anvil(self): """anvil_audit works correctly if this group has two group member not in anvil.""" @@ -2112,14 +2040,10 @@ def test_two_group_members_not_in_anvil(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) record_result = audit_results.get_result_for_model_instance(membership_1) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_GROUP_MEMBER_NOT_IN_ANVIL]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_GROUP_MEMBER_NOT_IN_ANVIL])) record_result = audit_results.get_result_for_model_instance(membership_2) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_GROUP_MEMBER_NOT_IN_ANVIL]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_GROUP_MEMBER_NOT_IN_ANVIL])) def test_one_group_members_not_in_app(self): """anvil_audit works correctly if this group has one group member not in the app.""" @@ -2129,9 +2053,7 @@ def test_one_group_members_not_in_app(self): responses.GET, api_url_members, status=200, - json=api_factories.GetGroupMembershipResponseFactory( - response=["test-member@firecloud.org"] - ).response, + json=api_factories.GetGroupMembershipResponseFactory(response=["test-member@firecloud.org"]).response, ) api_url_admins = self.get_api_url_admins(group.name) self.anvil_response_mock.add( @@ -2182,17 +2104,13 @@ def test_two_group_members_not_in_app(self): def test_one_group_members_case_insensitive(self): """anvil_audit works correctly if this group has one group member not in the app.""" group = factories.ManagedGroupFactory.create() - membership = factories.GroupGroupMembershipFactory.create( - parent_group=group, child_group__name="tEsT-mEmBeR" - ) + membership = factories.GroupGroupMembershipFactory.create(parent_group=group, child_group__name="tEsT-mEmBeR") api_url_members = self.get_api_url_members(group.name) self.anvil_response_mock.add( responses.GET, api_url_members, status=200, - json=api_factories.GetGroupMembershipResponseFactory( - response=["Test-Member@firecloud.org"] - ).response, + json=api_factories.GetGroupMembershipResponseFactory(response=["Test-Member@firecloud.org"]).response, ) api_url_admins = self.get_api_url_admins(group.name) self.anvil_response_mock.add( @@ -2308,9 +2226,7 @@ def test_one_group_admin_not_in_anvil(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) record_result = audit_results.get_result_for_model_instance(membership) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_GROUP_ADMIN_NOT_IN_ANVIL]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_GROUP_ADMIN_NOT_IN_ANVIL])) def test_two_group_admins_not_in_anvil(self): """anvil_audit works correctly if this group has two group member not in anvil.""" @@ -2343,14 +2259,10 @@ def test_two_group_admins_not_in_anvil(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) record_result = audit_results.get_result_for_model_instance(membership_1) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_GROUP_ADMIN_NOT_IN_ANVIL]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_GROUP_ADMIN_NOT_IN_ANVIL])) record_result = audit_results.get_result_for_model_instance(membership_2) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_GROUP_ADMIN_NOT_IN_ANVIL]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_GROUP_ADMIN_NOT_IN_ANVIL])) def test_one_group_admin_not_in_app(self): """anvil_audit works correctly if this group has one group member not in the app.""" @@ -2367,9 +2279,7 @@ def test_one_group_admin_not_in_app(self): responses.GET, api_url_admins, status=200, - json=api_factories.GetGroupMembershipAdminResponseFactory( - response=["test-admin@firecloud.org"] - ).response, + json=api_factories.GetGroupMembershipAdminResponseFactory(response=["test-admin@firecloud.org"]).response, ) audit_results = audit.ManagedGroupMembershipAudit(group) audit_results.run_audit() @@ -2430,9 +2340,7 @@ def test_one_group_admin_case_insensitive(self): responses.GET, api_url_admins, status=200, - json=api_factories.GetGroupMembershipAdminResponseFactory( - response=["Test-Admin@firecloud.org"] - ).response, + json=api_factories.GetGroupMembershipAdminResponseFactory(response=["Test-Admin@firecloud.org"]).response, ) audit_results = audit.ManagedGroupMembershipAudit(group) audit_results.run_audit() @@ -2473,9 +2381,7 @@ def test_group_different_role_member_in_app_admin_in_anvil(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 1) record_result = audit_results.get_result_for_model_instance(membership) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_GROUP_MEMBER_NOT_IN_ANVIL]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_GROUP_MEMBER_NOT_IN_ANVIL])) record_result = audit_results.get_not_in_app_results()[0] self.assertEqual(record_result.record, "ADMIN: " + membership.child_group.email) @@ -2487,9 +2393,7 @@ def test_service_account_is_both_admin_and_member(self): responses.GET, api_url_members, status=200, - json=api_factories.GetGroupMembershipResponseFactory( - response=[self.service_account_email] - ).response, + json=api_factories.GetGroupMembershipResponseFactory(response=[self.service_account_email]).response, ) api_url_admins = self.get_api_url_admins(group.name) self.anvil_response_mock.add( @@ -2508,17 +2412,13 @@ def test_service_account_is_both_admin_and_member(self): def test_different_group_member_email(self): """anvil_audit works correctly if this group has one group member with a different email.""" group = factories.ManagedGroupFactory.create() - membership = factories.GroupGroupMembershipFactory.create( - parent_group=group, child_group__email="foo@bar.com" - ) + membership = factories.GroupGroupMembershipFactory.create(parent_group=group, child_group__email="foo@bar.com") api_url_members = self.get_api_url_members(group.name) self.anvil_response_mock.add( responses.GET, api_url_members, status=200, - json=api_factories.GetGroupMembershipResponseFactory( - response=[membership.child_group.email] - ).response, + json=api_factories.GetGroupMembershipResponseFactory(response=[membership.child_group.email]).response, ) api_url_admins = self.get_api_url_admins(group.name) self.anvil_response_mock.add( @@ -2539,17 +2439,13 @@ def test_different_group_member_email(self): def test_different_group_member_email_case_insensitive(self): """anvil_audit works correctly if this group has one group member with a different email, case insensitive.""" group = factories.ManagedGroupFactory.create() - membership = factories.GroupGroupMembershipFactory.create( - parent_group=group, child_group__email="foo@bar.com" - ) + membership = factories.GroupGroupMembershipFactory.create(parent_group=group, child_group__email="foo@bar.com") api_url_members = self.get_api_url_members(group.name) self.anvil_response_mock.add( responses.GET, api_url_members, status=200, - json=api_factories.GetGroupMembershipResponseFactory( - response=["Foo@Bar.com"] - ).response, + json=api_factories.GetGroupMembershipResponseFactory(response=["Foo@Bar.com"]).response, ) api_url_admins = self.get_api_url_admins(group.name) self.anvil_response_mock.add( @@ -2588,9 +2484,7 @@ def test_service_account_is_not_directly_admin(self): api_url_admins, status=200, # Use the Membership factory because it doesn't add the service account as a direct admin. - json=api_factories.GetGroupMembershipResponseFactory( - response=["foo@bar.com"] - ).response, + json=api_factories.GetGroupMembershipResponseFactory(response=["foo@bar.com"]).response, ) audit_results = audit.ManagedGroupMembershipAudit(group) audit_results.run_audit() @@ -2611,9 +2505,7 @@ def test_group_is_both_admin_and_member(self): responses.GET, api_url_members, status=200, - json=api_factories.GetGroupMembershipResponseFactory( - response=[membership.child_group.email] - ).response, + json=api_factories.GetGroupMembershipResponseFactory(response=[membership.child_group.email]).response, ) api_url_admins = self.get_api_url_admins(group.name) self.anvil_response_mock.add( @@ -2637,9 +2529,7 @@ def test_deactivated_account_not_member_in_anvil(self): """Audit is ok if a deactivated account is not in the group on AnVIL.""" group = factories.ManagedGroupFactory.create() # Create an inactive account that is a member of this group. - factories.GroupAccountMembershipFactory.create( - group=group, account__status=models.Account.INACTIVE_STATUS - ) + factories.GroupAccountMembershipFactory.create(group=group, account__status=models.Account.INACTIVE_STATUS) # The Account is not a member in AnVIL api_url_members = self.get_api_url_members(group.name) self.anvil_response_mock.add( @@ -2675,9 +2565,7 @@ def test_deactivated_account_member_in_anvil(self): responses.GET, api_url_members, status=200, - json=api_factories.GetGroupMembershipResponseFactory( - response=[membership.account.email] - ).response, + json=api_factories.GetGroupMembershipResponseFactory(response=[membership.account.email]).response, ) api_url_admins = self.get_api_url_admins(group.name) self.anvil_response_mock.add( @@ -2751,9 +2639,7 @@ def test_deactivated_account_admin_in_anvil(self): responses.GET, api_url_admins, status=200, - json=api_factories.GetGroupMembershipAdminResponseFactory( - response=[membership.account.email] - ).response, + json=api_factories.GetGroupMembershipAdminResponseFactory(response=[membership.account.email]).response, ) audit_results = audit.ManagedGroupMembershipAudit(group) audit_results.run_audit() @@ -2840,16 +2726,10 @@ def test_anvil_audit_one_workspace_no_errors(self): responses.GET, api_url, status=200, - json=[ - self.get_api_workspace_json( - workspace.billing_project.name, workspace.name, "OWNER" - ) - ], + json=[self.get_api_workspace_json(workspace.billing_project.name, workspace.name, "OWNER")], ) # Response to check workspace access. - workspace_acl_url = self.get_api_workspace_acl_url( - workspace.billing_project.name, workspace.name - ) + workspace_acl_url = self.get_api_workspace_acl_url(workspace.billing_project.name, workspace.name) self.anvil_response_mock.add( responses.GET, workspace_acl_url, @@ -2893,11 +2773,7 @@ def test_anvil_audit_one_workspace_owner_in_app_reader_on_anvil(self): responses.GET, api_url, status=200, - json=[ - self.get_api_workspace_json( - workspace.billing_project.name, workspace.name, "READER" - ) - ], + json=[self.get_api_workspace_json(workspace.billing_project.name, workspace.name, "READER")], ) audit_results = audit.WorkspaceAudit() audit_results.run_audit() @@ -2907,9 +2783,7 @@ def test_anvil_audit_one_workspace_owner_in_app_reader_on_anvil(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) record_result = audit_results.get_result_for_model_instance(workspace) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_NOT_OWNER_ON_ANVIL]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_NOT_OWNER_ON_ANVIL])) def test_anvil_audit_one_workspace_owner_in_app_writer_on_anvil(self): """anvil_audit raises exception if one workspace exists in the app but the access on AnVIL is WRITER.""" @@ -2919,11 +2793,7 @@ def test_anvil_audit_one_workspace_owner_in_app_writer_on_anvil(self): responses.GET, api_url, status=200, - json=[ - self.get_api_workspace_json( - workspace.billing_project.name, workspace.name, "WRITER" - ) - ], + json=[self.get_api_workspace_json(workspace.billing_project.name, workspace.name, "WRITER")], ) audit_results = audit.WorkspaceAudit() audit_results.run_audit() @@ -2933,9 +2803,7 @@ def test_anvil_audit_one_workspace_owner_in_app_writer_on_anvil(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) record_result = audit_results.get_result_for_model_instance(workspace) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_NOT_OWNER_ON_ANVIL]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_NOT_OWNER_ON_ANVIL])) def test_anvil_audit_one_workspace_is_locked_in_app_not_on_anvil(self): """anvil_audit raises exception if workspace is locked in the app but not on AnVIL.""" @@ -2955,9 +2823,7 @@ def test_anvil_audit_one_workspace_is_locked_in_app_not_on_anvil(self): ], ) # Response to check workspace access. - workspace_acl_url = self.get_api_workspace_acl_url( - workspace.billing_project.name, workspace.name - ) + workspace_acl_url = self.get_api_workspace_acl_url(workspace.billing_project.name, workspace.name) self.anvil_response_mock.add( responses.GET, workspace_acl_url, @@ -2972,9 +2838,7 @@ def test_anvil_audit_one_workspace_is_locked_in_app_not_on_anvil(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) record_result = audit_results.get_result_for_model_instance(workspace) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_DIFFERENT_LOCK]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_DIFFERENT_LOCK])) def test_anvil_audit_one_workspace_is_not_locked_in_app_but_is_on_anvil(self): """anvil_audit raises exception if workspace is locked in the app but not on AnVIL.""" @@ -2994,9 +2858,7 @@ def test_anvil_audit_one_workspace_is_not_locked_in_app_but_is_on_anvil(self): ], ) # Response to check workspace access. - workspace_acl_url = self.get_api_workspace_acl_url( - workspace.billing_project.name, workspace.name - ) + workspace_acl_url = self.get_api_workspace_acl_url(workspace.billing_project.name, workspace.name) self.anvil_response_mock.add( responses.GET, workspace_acl_url, @@ -3011,9 +2873,7 @@ def test_anvil_audit_one_workspace_is_not_locked_in_app_but_is_on_anvil(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) record_result = audit_results.get_result_for_model_instance(workspace) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_DIFFERENT_LOCK]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_DIFFERENT_LOCK])) def test_anvil_audit_two_workspaces_no_errors(self): """anvil_audit returns None if if two workspaces exist in both the app and AnVIL.""" @@ -3025,18 +2885,12 @@ def test_anvil_audit_two_workspaces_no_errors(self): api_url, status=200, json=[ - self.get_api_workspace_json( - workspace_1.billing_project.name, workspace_1.name, "OWNER" - ), - self.get_api_workspace_json( - workspace_2.billing_project.name, workspace_2.name, "OWNER" - ), + self.get_api_workspace_json(workspace_1.billing_project.name, workspace_1.name, "OWNER"), + self.get_api_workspace_json(workspace_2.billing_project.name, workspace_2.name, "OWNER"), ], ) # Response to check workspace access. - workspace_acl_url_1 = self.get_api_workspace_acl_url( - workspace_1.billing_project.name, workspace_1.name - ) + workspace_acl_url_1 = self.get_api_workspace_acl_url(workspace_1.billing_project.name, workspace_1.name) self.anvil_response_mock.add( responses.GET, workspace_acl_url_1, @@ -3044,9 +2898,7 @@ def test_anvil_audit_two_workspaces_no_errors(self): json=self.get_api_workspace_acl_response(), ) # Response to check workspace access. - workspace_acl_url_2 = self.get_api_workspace_acl_url( - workspace_2.billing_project.name, workspace_2.name - ) + workspace_acl_url_2 = self.get_api_workspace_acl_url(workspace_2.billing_project.name, workspace_2.name) self.anvil_response_mock.add( responses.GET, workspace_acl_url_2, @@ -3074,18 +2926,12 @@ def test_anvil_audit_two_groups_json_response_order_does_not_matter(self): api_url, status=200, json=[ - self.get_api_workspace_json( - workspace_2.billing_project.name, workspace_2.name, "OWNER" - ), - self.get_api_workspace_json( - workspace_1.billing_project.name, workspace_1.name, "OWNER" - ), + self.get_api_workspace_json(workspace_2.billing_project.name, workspace_2.name, "OWNER"), + self.get_api_workspace_json(workspace_1.billing_project.name, workspace_1.name, "OWNER"), ], ) # Response to check workspace access. - workspace_acl_url_1 = self.get_api_workspace_acl_url( - workspace_1.billing_project.name, workspace_1.name - ) + workspace_acl_url_1 = self.get_api_workspace_acl_url(workspace_1.billing_project.name, workspace_1.name) self.anvil_response_mock.add( responses.GET, workspace_acl_url_1, @@ -3093,9 +2939,7 @@ def test_anvil_audit_two_groups_json_response_order_does_not_matter(self): json=self.get_api_workspace_acl_response(), ) # Response to check workspace access. - workspace_acl_url_2 = self.get_api_workspace_acl_url( - workspace_2.billing_project.name, workspace_2.name - ) + workspace_acl_url_2 = self.get_api_workspace_acl_url(workspace_2.billing_project.name, workspace_2.name) self.anvil_response_mock.add( responses.GET, workspace_acl_url_2, @@ -3123,15 +2967,11 @@ def test_anvil_audit_two_workspaces_first_not_on_anvil(self): api_url, status=200, json=[ - self.get_api_workspace_json( - workspace_2.billing_project.name, workspace_2.name, "OWNER" - ), + self.get_api_workspace_json(workspace_2.billing_project.name, workspace_2.name, "OWNER"), ], ) # Response to check workspace access. - workspace_acl_url_2 = self.get_api_workspace_acl_url( - workspace_2.billing_project.name, workspace_2.name - ) + workspace_acl_url_2 = self.get_api_workspace_acl_url(workspace_2.billing_project.name, workspace_2.name) self.anvil_response_mock.add( responses.GET, workspace_acl_url_2, @@ -3160,18 +3000,12 @@ def test_anvil_audit_two_workspaces_first_different_access(self): api_url, status=200, json=[ - self.get_api_workspace_json( - workspace_1.billing_project.name, workspace_1.name, "READER" - ), - self.get_api_workspace_json( - workspace_2.billing_project.name, workspace_2.name, "OWNER" - ), + self.get_api_workspace_json(workspace_1.billing_project.name, workspace_1.name, "READER"), + self.get_api_workspace_json(workspace_2.billing_project.name, workspace_2.name, "OWNER"), ], ) # Response to check workspace access. - workspace_acl_url_2 = self.get_api_workspace_acl_url( - workspace_2.billing_project.name, workspace_2.name - ) + workspace_acl_url_2 = self.get_api_workspace_acl_url(workspace_2.billing_project.name, workspace_2.name) self.anvil_response_mock.add( responses.GET, workspace_acl_url_2, @@ -3186,9 +3020,7 @@ def test_anvil_audit_two_workspaces_first_different_access(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) record_result = audit_results.get_result_for_model_instance(workspace_1) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_NOT_OWNER_ON_ANVIL]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_NOT_OWNER_ON_ANVIL])) record_result = audit_results.get_result_for_model_instance(workspace_2) self.assertTrue(record_result.ok()) @@ -3258,9 +3090,7 @@ def test_anvil_audit_two_workspaces_missing_in_app(self): def test_different_billing_project(self): """A workspace is reported as missing if it has the same name but a different billing project in app.""" - workspace = factories.WorkspaceFactory.create( - billing_project__name="test-bp-app", name="test-ws" - ) + workspace = factories.WorkspaceFactory.create(billing_project__name="test-bp-app", name="test-ws") api_url = self.get_api_url() self.anvil_response_mock.add( responses.GET, @@ -3345,20 +3175,14 @@ def test_one_workspace_one_auth_domain(self): self.assertEqual(len(audit_results.get_verified_results()), 1) self.assertEqual(len(audit_results.get_error_results()), 0) self.assertEqual(len(audit_results.get_not_in_app_results()), 0) - record_result = audit_results.get_result_for_model_instance( - auth_domain.workspace - ) + record_result = audit_results.get_result_for_model_instance(auth_domain.workspace) self.assertTrue(record_result.ok()) def test_one_workspace_two_auth_domains(self): """anvil_audit works properly when there is one workspace with two auth domains.""" workspace = factories.WorkspaceFactory.create() - auth_domain_1 = factories.WorkspaceAuthorizationDomainFactory.create( - workspace=workspace - ) - auth_domain_2 = factories.WorkspaceAuthorizationDomainFactory.create( - workspace=workspace - ) + auth_domain_1 = factories.WorkspaceAuthorizationDomainFactory.create(workspace=workspace) + auth_domain_2 = factories.WorkspaceAuthorizationDomainFactory.create(workspace=workspace) api_url = self.get_api_url() self.anvil_response_mock.add( responses.GET, @@ -3374,9 +3198,7 @@ def test_one_workspace_two_auth_domains(self): ], ) # Response to check workspace access. - workspace_acl_url = self.get_api_workspace_acl_url( - workspace.billing_project.name, workspace.name - ) + workspace_acl_url = self.get_api_workspace_acl_url(workspace.billing_project.name, workspace.name) self.anvil_response_mock.add( responses.GET, workspace_acl_url, @@ -3395,12 +3217,8 @@ def test_one_workspace_two_auth_domains(self): def test_one_workspace_two_auth_domains_order_does_not_matter(self): """anvil_audit works properly when there is one workspace with two auth domains.""" workspace = factories.WorkspaceFactory.create() - auth_domain_1 = factories.WorkspaceAuthorizationDomainFactory.create( - workspace=workspace, group__name="aa" - ) - auth_domain_2 = factories.WorkspaceAuthorizationDomainFactory.create( - workspace=workspace, group__name="zz" - ) + auth_domain_1 = factories.WorkspaceAuthorizationDomainFactory.create(workspace=workspace, group__name="aa") + auth_domain_2 = factories.WorkspaceAuthorizationDomainFactory.create(workspace=workspace, group__name="zz") api_url = self.get_api_url() self.anvil_response_mock.add( responses.GET, @@ -3416,9 +3234,7 @@ def test_one_workspace_two_auth_domains_order_does_not_matter(self): ], ) # Response to check workspace access. - workspace_acl_url = self.get_api_workspace_acl_url( - workspace.billing_project.name, workspace.name - ) + workspace_acl_url = self.get_api_workspace_acl_url(workspace.billing_project.name, workspace.name) self.anvil_response_mock.add( responses.GET, workspace_acl_url, @@ -3452,9 +3268,7 @@ def test_one_workspace_no_auth_domain_in_app_one_auth_domain_on_anvil(self): ], ) # Response to check workspace access. - workspace_acl_url = self.get_api_workspace_acl_url( - workspace.billing_project.name, workspace.name - ) + workspace_acl_url = self.get_api_workspace_acl_url(workspace.billing_project.name, workspace.name) self.anvil_response_mock.add( responses.GET, workspace_acl_url, @@ -3469,9 +3283,7 @@ def test_one_workspace_no_auth_domain_in_app_one_auth_domain_on_anvil(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) record_result = audit_results.get_result_for_model_instance(workspace) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_DIFFERENT_AUTH_DOMAINS]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_DIFFERENT_AUTH_DOMAINS])) def test_one_workspace_one_auth_domain_in_app_no_auth_domain_on_anvil(self): """anvil_audit works properly when there is one workspace with one auth domain in the app but none on AnVIL.""" @@ -3506,13 +3318,9 @@ def test_one_workspace_one_auth_domain_in_app_no_auth_domain_on_anvil(self): self.assertEqual(len(audit_results.get_verified_results()), 0) self.assertEqual(len(audit_results.get_error_results()), 1) self.assertEqual(len(audit_results.get_not_in_app_results()), 0) - record_result = audit_results.get_result_for_model_instance( - auth_domain.workspace - ) + record_result = audit_results.get_result_for_model_instance(auth_domain.workspace) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_DIFFERENT_AUTH_DOMAINS]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_DIFFERENT_AUTH_DOMAINS])) def test_one_workspace_no_auth_domain_in_app_two_auth_domains_on_anvil(self): """anvil_audit works properly when there is one workspace with no auth domain in the app but two on AnVIL.""" @@ -3532,9 +3340,7 @@ def test_one_workspace_no_auth_domain_in_app_two_auth_domains_on_anvil(self): ], ) # Response to check workspace access. - workspace_acl_url = self.get_api_workspace_acl_url( - workspace.billing_project.name, workspace.name - ) + workspace_acl_url = self.get_api_workspace_acl_url(workspace.billing_project.name, workspace.name) self.anvil_response_mock.add( responses.GET, workspace_acl_url, @@ -3549,9 +3355,7 @@ def test_one_workspace_no_auth_domain_in_app_two_auth_domains_on_anvil(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) record_result = audit_results.get_result_for_model_instance(workspace) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_DIFFERENT_AUTH_DOMAINS]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_DIFFERENT_AUTH_DOMAINS])) def test_one_workspace_two_auth_domains_in_app_no_auth_domain_on_anvil(self): """anvil_audit works properly when there is one workspace with two auth domains in the app but none on AnVIL.""" @@ -3573,9 +3377,7 @@ def test_one_workspace_two_auth_domains_in_app_no_auth_domain_on_anvil(self): ], ) # Response to check workspace access. - workspace_acl_url = self.get_api_workspace_acl_url( - workspace.billing_project.name, workspace.name - ) + workspace_acl_url = self.get_api_workspace_acl_url(workspace.billing_project.name, workspace.name) self.anvil_response_mock.add( responses.GET, workspace_acl_url, @@ -3590,16 +3392,12 @@ def test_one_workspace_two_auth_domains_in_app_no_auth_domain_on_anvil(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) record_result = audit_results.get_result_for_model_instance(workspace) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_DIFFERENT_AUTH_DOMAINS]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_DIFFERENT_AUTH_DOMAINS])) def test_one_workspace_two_auth_domains_in_app_one_auth_domain_on_anvil(self): """anvil_audit works properly when there is one workspace with two auth domains in the app but one on AnVIL.""" workspace = factories.WorkspaceFactory.create() - auth_domain_1 = factories.WorkspaceAuthorizationDomainFactory.create( - workspace=workspace - ) + auth_domain_1 = factories.WorkspaceAuthorizationDomainFactory.create(workspace=workspace) factories.WorkspaceAuthorizationDomainFactory.create(workspace=workspace) api_url = self.get_api_url() self.anvil_response_mock.add( @@ -3616,9 +3414,7 @@ def test_one_workspace_two_auth_domains_in_app_one_auth_domain_on_anvil(self): ], ) # Response to check workspace access. - workspace_acl_url = self.get_api_workspace_acl_url( - workspace.billing_project.name, workspace.name - ) + workspace_acl_url = self.get_api_workspace_acl_url(workspace.billing_project.name, workspace.name) self.anvil_response_mock.add( responses.GET, workspace_acl_url, @@ -3633,15 +3429,11 @@ def test_one_workspace_two_auth_domains_in_app_one_auth_domain_on_anvil(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) record_result = audit_results.get_result_for_model_instance(workspace) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_DIFFERENT_AUTH_DOMAINS]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_DIFFERENT_AUTH_DOMAINS])) def test_one_workspace_different_auth_domains(self): """anvil_audit works properly when the app and AnVIL have different auth domains for the same workspace.""" - auth_domain = factories.WorkspaceAuthorizationDomainFactory.create( - group__name="app" - ) + auth_domain = factories.WorkspaceAuthorizationDomainFactory.create(group__name="app") api_url = self.get_api_url() self.anvil_response_mock.add( responses.GET, @@ -3672,13 +3464,9 @@ def test_one_workspace_different_auth_domains(self): self.assertEqual(len(audit_results.get_verified_results()), 0) self.assertEqual(len(audit_results.get_error_results()), 1) self.assertEqual(len(audit_results.get_not_in_app_results()), 0) - record_result = audit_results.get_result_for_model_instance( - auth_domain.workspace - ) + record_result = audit_results.get_result_for_model_instance(auth_domain.workspace) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_DIFFERENT_AUTH_DOMAINS]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_DIFFERENT_AUTH_DOMAINS])) def test_two_workspaces_first_auth_domains_do_not_match(self): """anvil_audit works properly when there are two workspaces in the app and the first has auth domain issues.""" @@ -3705,9 +3493,7 @@ def test_two_workspaces_first_auth_domains_do_not_match(self): ], ) # Response to check workspace access. - workspace_acl_url_1 = self.get_api_workspace_acl_url( - workspace_1.billing_project.name, workspace_1.name - ) + workspace_acl_url_1 = self.get_api_workspace_acl_url(workspace_1.billing_project.name, workspace_1.name) self.anvil_response_mock.add( responses.GET, workspace_acl_url_1, @@ -3715,9 +3501,7 @@ def test_two_workspaces_first_auth_domains_do_not_match(self): json=self.get_api_workspace_acl_response(), ) # Response to check workspace access. - workspace_acl_url_2 = self.get_api_workspace_acl_url( - workspace_2.billing_project.name, workspace_2.name - ) + workspace_acl_url_2 = self.get_api_workspace_acl_url(workspace_2.billing_project.name, workspace_2.name) self.anvil_response_mock.add( responses.GET, workspace_acl_url_2, @@ -3732,9 +3516,7 @@ def test_two_workspaces_first_auth_domains_do_not_match(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) record_result = audit_results.get_result_for_model_instance(workspace_1) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_DIFFERENT_AUTH_DOMAINS]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_DIFFERENT_AUTH_DOMAINS])) record_result = audit_results.get_result_for_model_instance(workspace_2) self.assertTrue(record_result.ok()) @@ -3763,9 +3545,7 @@ def test_two_workspaces_auth_domains_do_not_match_for_both(self): ], ) # Response to check workspace access. - workspace_acl_url_1 = self.get_api_workspace_acl_url( - workspace_1.billing_project.name, workspace_1.name - ) + workspace_acl_url_1 = self.get_api_workspace_acl_url(workspace_1.billing_project.name, workspace_1.name) self.anvil_response_mock.add( responses.GET, workspace_acl_url_1, @@ -3773,9 +3553,7 @@ def test_two_workspaces_auth_domains_do_not_match_for_both(self): json=self.get_api_workspace_acl_response(), ) # Response to check workspace access. - workspace_acl_url_2 = self.get_api_workspace_acl_url( - workspace_2.billing_project.name, workspace_2.name - ) + workspace_acl_url_2 = self.get_api_workspace_acl_url(workspace_2.billing_project.name, workspace_2.name) self.anvil_response_mock.add( responses.GET, workspace_acl_url_2, @@ -3790,14 +3568,10 @@ def test_two_workspaces_auth_domains_do_not_match_for_both(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) record_result = audit_results.get_result_for_model_instance(workspace_1) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_DIFFERENT_AUTH_DOMAINS]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_DIFFERENT_AUTH_DOMAINS])) record_result = audit_results.get_result_for_model_instance(workspace_2) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_DIFFERENT_AUTH_DOMAINS]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_DIFFERENT_AUTH_DOMAINS])) def test_one_workspace_with_two_errors(self): """One workspace has two errors: different auth domains and not owner.""" @@ -3808,11 +3582,7 @@ def test_one_workspace_with_two_errors(self): responses.GET, api_url, status=200, - json=[ - self.get_api_workspace_json( - workspace.billing_project.name, workspace.name, "READER" - ) - ], + json=[self.get_api_workspace_json(workspace.billing_project.name, workspace.name, "READER")], ) audit_results = audit.WorkspaceAudit() audit_results.run_audit() @@ -3851,9 +3621,7 @@ def test_fails_sharing_audit(self): ], ) # Response to check workspace access. - workspace_acl_url = self.get_api_workspace_acl_url( - workspace.billing_project.name, workspace.name - ) + workspace_acl_url = self.get_api_workspace_acl_url(workspace.billing_project.name, workspace.name) self.anvil_response_mock.add( responses.GET, workspace_acl_url, @@ -3868,9 +3636,7 @@ def test_fails_sharing_audit(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) record_result = audit_results.get_result_for_model_instance(workspace) self.assertFalse(record_result.ok()) - self.assertEqual( - record_result.errors, set([audit_results.ERROR_WORKSPACE_SHARING]) - ) + self.assertEqual(record_result.errors, set([audit_results.ERROR_WORKSPACE_SHARING])) class WorkspaceSharingAuditTest(AnVILAPIMockTestMixin, TestCase): @@ -3941,12 +3707,8 @@ def test_one_group_reader(self): def test_two_group_readers(self): """anvil_audit works correctly if this workspace has two group readers.""" - access_1 = factories.WorkspaceGroupSharingFactory.create( - workspace=self.workspace - ) - access_2 = factories.WorkspaceGroupSharingFactory.create( - workspace=self.workspace - ) + access_1 = factories.WorkspaceGroupSharingFactory.create(workspace=self.workspace) + access_2 = factories.WorkspaceGroupSharingFactory.create(workspace=self.workspace) self.update_api_response(access_1.group.email, "READER") self.update_api_response(access_2.group.email, "READER") self.anvil_response_mock.add( @@ -3983,18 +3745,12 @@ def test_one_group_reader_not_in_anvil(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) model_result = audit_results.get_result_for_model_instance(access) self.assertFalse(model_result.ok()) - self.assertEqual( - model_result.errors, set([audit_results.ERROR_NOT_SHARED_IN_ANVIL]) - ) + self.assertEqual(model_result.errors, set([audit_results.ERROR_NOT_SHARED_IN_ANVIL])) def test_two_group_readers_not_in_anvil(self): """anvil_audit works correctly if this workspace has two group readers not in anvil.""" - access_1 = factories.WorkspaceGroupSharingFactory.create( - workspace=self.workspace - ) - access_2 = factories.WorkspaceGroupSharingFactory.create( - workspace=self.workspace - ) + access_1 = factories.WorkspaceGroupSharingFactory.create(workspace=self.workspace) + access_2 = factories.WorkspaceGroupSharingFactory.create(workspace=self.workspace) self.anvil_response_mock.add( responses.GET, self.api_url, @@ -4009,14 +3765,10 @@ def test_two_group_readers_not_in_anvil(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) model_result = audit_results.get_result_for_model_instance(access_1) self.assertFalse(model_result.ok()) - self.assertEqual( - model_result.errors, set([audit_results.ERROR_NOT_SHARED_IN_ANVIL]) - ) + self.assertEqual(model_result.errors, set([audit_results.ERROR_NOT_SHARED_IN_ANVIL])) model_result = audit_results.get_result_for_model_instance(access_2) self.assertFalse(model_result.ok()) - self.assertEqual( - model_result.errors, set([audit_results.ERROR_NOT_SHARED_IN_ANVIL]) - ) + self.assertEqual(model_result.errors, set([audit_results.ERROR_NOT_SHARED_IN_ANVIL])) def test_one_group_readers_not_in_app(self): """anvil_audit works correctly if this workspace has one group reader not in the app.""" @@ -4059,9 +3811,7 @@ def test_two_group_readers_not_in_app(self): def test_one_group_members_case_insensitive(self): """anvil_audit ignores case.""" - access = factories.WorkspaceGroupSharingFactory.create( - workspace=self.workspace, group__name="tEsT-mEmBeR" - ) + access = factories.WorkspaceGroupSharingFactory.create(workspace=self.workspace, group__name="tEsT-mEmBeR") self.update_api_response("Test-Member@firecloud.org", "READER") self.anvil_response_mock.add( responses.GET, @@ -4145,9 +3895,7 @@ def test_one_group_writer_not_in_anvil(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) model_result = audit_results.get_result_for_model_instance(access) self.assertFalse(model_result.ok()) - self.assertEqual( - model_result.errors, set([audit_results.ERROR_NOT_SHARED_IN_ANVIL]) - ) + self.assertEqual(model_result.errors, set([audit_results.ERROR_NOT_SHARED_IN_ANVIL])) def test_two_group_writers_not_in_anvil(self): """anvil_audit works correctly if this workspace has two group writers not in anvil.""" @@ -4171,14 +3919,10 @@ def test_two_group_writers_not_in_anvil(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) model_result = audit_results.get_result_for_model_instance(access_1) self.assertFalse(model_result.ok()) - self.assertEqual( - model_result.errors, set([audit_results.ERROR_NOT_SHARED_IN_ANVIL]) - ) + self.assertEqual(model_result.errors, set([audit_results.ERROR_NOT_SHARED_IN_ANVIL])) model_result = audit_results.get_result_for_model_instance(access_2) self.assertFalse(model_result.ok()) - self.assertEqual( - model_result.errors, set([audit_results.ERROR_NOT_SHARED_IN_ANVIL]) - ) + self.assertEqual(model_result.errors, set([audit_results.ERROR_NOT_SHARED_IN_ANVIL])) def test_one_group_writer_not_in_app(self): """anvil_audit works correctly if this workspace has one group writer not in the app.""" @@ -4309,9 +4053,7 @@ def test_one_group_owner_not_in_anvil(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) model_result = audit_results.get_result_for_model_instance(access) self.assertFalse(model_result.ok()) - self.assertEqual( - model_result.errors, set([audit_results.ERROR_NOT_SHARED_IN_ANVIL]) - ) + self.assertEqual(model_result.errors, set([audit_results.ERROR_NOT_SHARED_IN_ANVIL])) def test_two_group_owners_not_in_anvil(self): """anvil_audit works correctly if this workspace has two group owners not in anvil.""" @@ -4335,14 +4077,10 @@ def test_two_group_owners_not_in_anvil(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) model_result = audit_results.get_result_for_model_instance(access_1) self.assertFalse(model_result.ok()) - self.assertEqual( - model_result.errors, set([audit_results.ERROR_NOT_SHARED_IN_ANVIL]) - ) + self.assertEqual(model_result.errors, set([audit_results.ERROR_NOT_SHARED_IN_ANVIL])) model_result = audit_results.get_result_for_model_instance(access_2) self.assertFalse(model_result.ok()) - self.assertEqual( - model_result.errors, set([audit_results.ERROR_NOT_SHARED_IN_ANVIL]) - ) + self.assertEqual(model_result.errors, set([audit_results.ERROR_NOT_SHARED_IN_ANVIL])) def test_one_group_owner_not_in_app(self): """anvil_audit works correctly if this workspace has one group owner not in the app.""" @@ -4426,18 +4164,14 @@ def test_group_different_access_reader_in_app_writer_in_anvil(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) model_result = audit_results.get_result_for_model_instance(access) self.assertFalse(model_result.ok()) - self.assertEqual( - model_result.errors, set([audit_results.ERROR_DIFFERENT_ACCESS]) - ) + self.assertEqual(model_result.errors, set([audit_results.ERROR_DIFFERENT_ACCESS])) def test_group_different_access_reader_in_app_owner_in_anvil(self): """anvil_audit works correctly if a group has different access to a workspace in AnVIL.""" access = factories.WorkspaceGroupSharingFactory.create( workspace=self.workspace, access=models.WorkspaceGroupSharing.READER ) - self.update_api_response( - access.group.email, "OWNER", can_compute=True, can_share=True - ) + self.update_api_response(access.group.email, "OWNER", can_compute=True, can_share=True) self.anvil_response_mock.add( responses.GET, self.api_url, @@ -4485,9 +4219,7 @@ def test_group_different_can_compute(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) model_result = audit_results.get_result_for_model_instance(access) self.assertFalse(model_result.ok()) - self.assertEqual( - model_result.errors, set([audit_results.ERROR_DIFFERENT_CAN_COMPUTE]) - ) + self.assertEqual(model_result.errors, set([audit_results.ERROR_DIFFERENT_CAN_COMPUTE])) def test_group_different_can_share(self): """anvil_audit works correctly if can_share is True in AnVIL.""" @@ -4509,15 +4241,11 @@ def test_group_different_can_share(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) model_result = audit_results.get_result_for_model_instance(access) self.assertFalse(model_result.ok()) - self.assertEqual( - model_result.errors, set([audit_results.ERROR_DIFFERENT_CAN_SHARE]) - ) + self.assertEqual(model_result.errors, set([audit_results.ERROR_DIFFERENT_CAN_SHARE])) def test_removes_service_account(self): """Removes the service account from acl if it exists.""" - self.update_api_response( - self.service_account_email, "OWNER", can_compute=True, can_share=True - ) + self.update_api_response(self.service_account_email, "OWNER", can_compute=True, can_share=True) self.anvil_response_mock.add( responses.GET, self.api_url, @@ -4538,9 +4266,7 @@ def test_group_owner_can_share_true(self): access=models.WorkspaceGroupSharing.OWNER, can_compute=True, ) - self.update_api_response( - access.group.email, "OWNER", can_compute=True, can_share=True - ) + self.update_api_response(access.group.email, "OWNER", can_compute=True, can_share=True) self.anvil_response_mock.add( responses.GET, self.api_url, @@ -4561,9 +4287,7 @@ def test_group_writer_can_share_false(self): access=models.WorkspaceGroupSharing.WRITER, can_compute=True, ) - self.update_api_response( - access.group.email, "WRITER", can_compute=True, can_share=True - ) + self.update_api_response(access.group.email, "WRITER", can_compute=True, can_share=True) self.anvil_response_mock.add( responses.GET, self.api_url, @@ -4578,9 +4302,7 @@ def test_group_writer_can_share_false(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) model_result = audit_results.get_result_for_model_instance(access) self.assertFalse(model_result.ok()) - self.assertEqual( - model_result.errors, set([audit_results.ERROR_DIFFERENT_CAN_SHARE]) - ) + self.assertEqual(model_result.errors, set([audit_results.ERROR_DIFFERENT_CAN_SHARE])) def test_group_reader_can_share_false(self): """Readers must have can_share=False.""" @@ -4589,9 +4311,7 @@ def test_group_reader_can_share_false(self): access=models.WorkspaceGroupSharing.READER, can_compute=False, ) - self.update_api_response( - access.group.email, "READER", can_compute=False, can_share=True - ) + self.update_api_response(access.group.email, "READER", can_compute=False, can_share=True) self.anvil_response_mock.add( responses.GET, self.api_url, @@ -4606,6 +4326,4 @@ def test_group_reader_can_share_false(self): self.assertEqual(len(audit_results.get_not_in_app_results()), 0) model_result = audit_results.get_result_for_model_instance(access) self.assertFalse(model_result.ok()) - self.assertEqual( - model_result.errors, set([audit_results.ERROR_DIFFERENT_CAN_SHARE]) - ) + self.assertEqual(model_result.errors, set([audit_results.ERROR_DIFFERENT_CAN_SHARE])) diff --git a/anvil_consortium_manager/tests/test_auth.py b/anvil_consortium_manager/tests/test_auth.py index e0ef3d22..3c41389c 100644 --- a/anvil_consortium_manager/tests/test_auth.py +++ b/anvil_consortium_manager/tests/test_auth.py @@ -19,9 +19,7 @@ def get_view_class(self): def test_user_with_limited_view_perms(self): """test_func returns True for a user with limited view permission.""" self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) inst = self.get_view_class()() request = self.factory.get("") @@ -32,9 +30,7 @@ def test_user_with_limited_view_perms(self): def test_user_with_view_perms(self): """test_func returns True for a user with view permission.""" self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) inst = self.get_view_class()() request = self.factory.get("") @@ -45,9 +41,7 @@ def test_user_with_view_perms(self): def test_user_with_edit_perms(self): """test_func returns False for a user with edit permission.""" self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) inst = self.get_view_class()() request = self.factory.get("") diff --git a/anvil_consortium_manager/tests/test_commands.py b/anvil_consortium_manager/tests/test_commands.py index 6b623711..73dccd78 100644 --- a/anvil_consortium_manager/tests/test_commands.py +++ b/anvil_consortium_manager/tests/test_commands.py @@ -20,11 +20,7 @@ class RunAnvilAuditTest(AnVILAPIMockTestMixin, TestCase): """Tests for the run_anvil_audit command""" def get_api_url_billing_project(self, billing_project_name): - return ( - self.api_client.rawls_entry_point - + "/api/billing/v2/" - + billing_project_name - ) + return self.api_client.rawls_entry_point + "/api/billing/v2/" + billing_project_name def test_command_output_invalid_model(self): """Appropriate error is returned when an invalid model is specified.""" @@ -72,9 +68,7 @@ def test_command_output_multiple_models(self): def test_command_output_billing_project_no_instances(self): """Test command output.""" out = StringIO() - call_command( - "run_anvil_audit", "--no-color", models=["BillingProject"], stdout=out - ) + call_command("run_anvil_audit", "--no-color", models=["BillingProject"], stdout=out) self.assertIn("BillingProjectAudit... ok!", out.getvalue()) def test_command_output_account_no_instances(self): @@ -92,9 +86,7 @@ def test_command_output_managed_group_no_instances(self): json=[], ) out = StringIO() - call_command( - "run_anvil_audit", "--no-color", models=["ManagedGroup"], stdout=out - ) + call_command("run_anvil_audit", "--no-color", models=["ManagedGroup"], stdout=out) self.assertIn("ManagedGroupAudit... ok!", out.getvalue()) def test_command_output_workspace_no_instances(self): @@ -116,9 +108,7 @@ def test_command_run_audit_one_instance_ok(self): api_url = self.get_api_url_billing_project(billing_project.name) self.anvil_response_mock.add(responses.GET, api_url, status=200) out = StringIO() - call_command( - "run_anvil_audit", "--no-color", models=["BillingProject"], stdout=out - ) + call_command("run_anvil_audit", "--no-color", models=["BillingProject"], stdout=out) self.assertIn("BillingProjectAudit... ok!", out.getvalue()) self.assertNotIn("errors", out.getvalue()) self.assertNotIn("not_in_app", out.getvalue()) @@ -176,13 +166,9 @@ def test_command_run_audit_not_ok(self): billing_project = factories.BillingProjectFactory.create() # Add a response. api_url = self.get_api_url_billing_project(billing_project.name) - self.anvil_response_mock.add( - responses.GET, api_url, status=404, json={"message": "error"} - ) + self.anvil_response_mock.add(responses.GET, api_url, status=404, json={"message": "error"}) out = StringIO() - call_command( - "run_anvil_audit", "--no-color", models=["BillingProject"], stdout=out - ) + call_command("run_anvil_audit", "--no-color", models=["BillingProject"], stdout=out) self.assertIn("BillingProjectAudit... problems found.", out.getvalue()) self.assertIn("""'errors':""", out.getvalue()) self.assertIn(audit.BillingProjectAudit.ERROR_NOT_IN_ANVIL, out.getvalue()) @@ -192,9 +178,7 @@ def test_command_run_audit_not_ok_email(self): billing_project = factories.BillingProjectFactory.create() # Add a response. api_url = self.get_api_url_billing_project(billing_project.name) - self.anvil_response_mock.add( - responses.GET, api_url, status=404, json={"message": "error"} - ) + self.anvil_response_mock.add(responses.GET, api_url, status=404, json={"message": "error"}) out = StringIO() call_command( "run_anvil_audit", @@ -222,9 +206,7 @@ def test_command_run_audit_not_ok_email_has_html_link(self): billing_project = factories.BillingProjectFactory.create() # Add a response. api_url = self.get_api_url_billing_project(billing_project.name) - self.anvil_response_mock.add( - responses.GET, api_url, status=404, json={"message": "error"} - ) + self.anvil_response_mock.add(responses.GET, api_url, status=404, json={"message": "error"}) out = StringIO() call_command( "run_anvil_audit", @@ -248,9 +230,7 @@ def test_command_run_audit_not_ok_email_has_html_link_different_domain(self): billing_project = factories.BillingProjectFactory.create() # Add a response. api_url = self.get_api_url_billing_project(billing_project.name) - self.anvil_response_mock.add( - responses.GET, api_url, status=404, json={"message": "error"} - ) + self.anvil_response_mock.add(responses.GET, api_url, status=404, json={"message": "error"}) out = StringIO() call_command( "run_anvil_audit", @@ -271,13 +251,9 @@ def test_command_run_audit_api_error(self): billing_project = factories.BillingProjectFactory.create() # Add a response. api_url = self.get_api_url_billing_project(billing_project.name) - self.anvil_response_mock.add( - responses.GET, api_url, status=500, json={"message": "error"} - ) + self.anvil_response_mock.add(responses.GET, api_url, status=500, json={"message": "error"}) out = StringIO() - call_command( - "run_anvil_audit", "--no-color", models=["BillingProject"], stdout=out - ) + call_command("run_anvil_audit", "--no-color", models=["BillingProject"], stdout=out) self.assertIn("BillingProjectAudit... API error.", out.getvalue()) # This test is complicated so skipping for now. diff --git a/anvil_consortium_manager/tests/test_forms.py b/anvil_consortium_manager/tests/test_forms.py index a2def86e..598d9de2 100644 --- a/anvil_consortium_manager/tests/test_forms.py +++ b/anvil_consortium_manager/tests/test_forms.py @@ -728,9 +728,7 @@ def test_invalid_missing_role(self): def test_invalid_parent_not_managed(self): """Form is invalid when the parent group is not managed by the app.""" - parent = factories.ManagedGroupFactory.create( - name="parent", is_managed_by_app=False - ) + parent = factories.ManagedGroupFactory.create(name="parent", is_managed_by_app=False) child = factories.ManagedGroupFactory.create(name="child") form_data = { "parent_group": parent, @@ -827,9 +825,7 @@ def test_invalid_inactive_account(self): def test_account_includes_only_active_accounts(self): """Form only displays active accounts.""" - inactive_account = factories.AccountFactory.create( - status=models.Account.INACTIVE_STATUS - ) + inactive_account = factories.AccountFactory.create(status=models.Account.INACTIVE_STATUS) active_account = factories.AccountFactory.create() form = self.form_class() self.assertIn(active_account, form.fields["account"].queryset) diff --git a/anvil_consortium_manager/tests/test_migrations.py b/anvil_consortium_manager/tests/test_migrations.py index 956bec3e..be8c491f 100644 --- a/anvil_consortium_manager/tests/test_migrations.py +++ b/anvil_consortium_manager/tests/test_migrations.py @@ -11,21 +11,15 @@ class PopulateManagedGroupEmailTest(MigratorTestCase): def prepare(self): """Prepare some data before the migration.""" - ManagedGroup = self.old_state.apps.get_model( - "anvil_consortium_manager", "ManagedGroup" - ) + ManagedGroup = self.old_state.apps.get_model("anvil_consortium_manager", "ManagedGroup") ManagedGroup.objects.create(name="mygroup") ManagedGroup.objects.create(name="AnotherGroup") def test_migration_main0011(self): """Run the test.""" - ManagedGroup = self.new_state.apps.get_model( - "anvil_consortium_manager", "ManagedGroup" - ) + ManagedGroup = self.new_state.apps.get_model("anvil_consortium_manager", "ManagedGroup") self.assertEqual(ManagedGroup.objects.count(), 2) - self.assertEqual( - ManagedGroup.objects.get(name="mygroup").email, "mygroup@firecloud.org" - ) + self.assertEqual(ManagedGroup.objects.get(name="mygroup").email, "mygroup@firecloud.org") self.assertEqual( ManagedGroup.objects.get(name="AnotherGroup").email, "anothergroup@firecloud.org", diff --git a/anvil_consortium_manager/tests/test_models.py b/anvil_consortium_manager/tests/test_models.py index 38bc5c1a..e0bdb362 100644 --- a/anvil_consortium_manager/tests/test_models.py +++ b/anvil_consortium_manager/tests/test_models.py @@ -216,9 +216,7 @@ def test_model_saving(self): self.assertIsInstance(instance, Account) def test_note_field(self): - instance = Account( - email="email@example.com", is_service_account=False, note="foo" - ) + instance = Account(email="email@example.com", is_service_account=False, note="foo") instance.save() self.assertIsInstance(instance, Account) self.assertEqual(instance.note, "foo") @@ -336,12 +334,8 @@ def test_clean_user_no_verified_email_entry(self): def test_clean_no_user_verified_email_entry(self): """The clean method fails if there is no user but a verified_email_entry.""" - email_entry = factories.UserEmailEntryFactory.create( - date_verified=timezone.now() - ) - account = factories.AccountFactory.build( - email=email_entry.email, verified_email_entry=email_entry - ) + email_entry = factories.UserEmailEntryFactory.create(date_verified=timezone.now()) + account = factories.AccountFactory.build(email=email_entry.email, verified_email_entry=email_entry) with self.assertRaises(ValidationError) as e: account.full_clean() self.assertEqual(len(e.exception.error_dict), 1) @@ -372,9 +366,7 @@ def test_clean_unverified_verified_email_entry(self): def test_clean_account_verified_email_entry_email_mismatch(self): """The clean method fails if the verified_email_entry and the account have different emails.""" - email_entry = factories.UserEmailEntryFactory.create( - date_verified=timezone.now(), email="foo@bar.com" - ) + email_entry = factories.UserEmailEntryFactory.create(date_verified=timezone.now(), email="foo@bar.com") account = factories.AccountFactory.build( user=email_entry.user, email="bar@foo.com", verified_email_entry=email_entry ) @@ -383,17 +375,13 @@ def test_clean_account_verified_email_entry_email_mismatch(self): self.assertEqual(len(e.exception.error_dict), 1) self.assertIn("email", e.exception.error_dict) self.assertEqual(len(e.exception.error_dict["email"]), 1) - self.assertIn( - Account.ERROR_MISMATCHED_EMAIL, e.exception.error_dict["email"][0].message - ) + self.assertIn(Account.ERROR_MISMATCHED_EMAIL, e.exception.error_dict["email"][0].message) def test_clean_account_verified_email_entry_user_mismatch(self): """The clean method fails if the verified_email_entry and the account have different users.""" user_1 = factories.UserFactory.create() user_2 = factories.UserFactory.create() - email_entry = factories.UserEmailEntryFactory.create( - user=user_1, date_verified=timezone.now() - ) + email_entry = factories.UserEmailEntryFactory.create(user=user_1, date_verified=timezone.now()) account = factories.AccountFactory.build( user=user_2, email=email_entry.email, verified_email_entry=email_entry ) @@ -402,9 +390,7 @@ def test_clean_account_verified_email_entry_user_mismatch(self): self.assertEqual(len(e.exception.error_dict), 1) self.assertIn("user", e.exception.error_dict) self.assertEqual(len(e.exception.error_dict["user"]), 1) - self.assertIn( - Account.ERROR_MISMATCHED_USER, e.exception.error_dict["user"][0].message - ) + self.assertIn(Account.ERROR_MISMATCHED_USER, e.exception.error_dict["user"][0].message) def test_get_accessible_workspaces_shared(self): """One workspace when the account is a member of a group and the workspace is shared with that group.""" @@ -464,16 +450,10 @@ def test_get_accessible_workspaces_shared_with_parent(self): # Set up group membership. child_group = factories.ManagedGroupFactory.create() parent_group = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - child_group=child_group, parent_group=parent_group - ) - factories.GroupAccountMembershipFactory.create( - group=child_group, account=account - ) + factories.GroupGroupMembershipFactory.create(child_group=child_group, parent_group=parent_group) + factories.GroupAccountMembershipFactory.create(group=child_group, account=account) # Set up workspace sharing. - factories.WorkspaceGroupSharingFactory.create( - workspace=workspace, group=parent_group - ) + factories.WorkspaceGroupSharingFactory.create(workspace=workspace, group=parent_group) # Tests. accessible_workspaces = account.get_accessible_workspaces() self.assertEqual(len(accessible_workspaces), 1) @@ -488,19 +468,11 @@ def test_get_accessible_workspaces_shared_with_grandparent(self): child_group = factories.ManagedGroupFactory.create() parent_group = factories.ManagedGroupFactory.create() grandparent_group = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - child_group=parent_group, parent_group=grandparent_group - ) - factories.GroupGroupMembershipFactory.create( - child_group=child_group, parent_group=parent_group - ) - factories.GroupAccountMembershipFactory.create( - group=child_group, account=account - ) + factories.GroupGroupMembershipFactory.create(child_group=parent_group, parent_group=grandparent_group) + factories.GroupGroupMembershipFactory.create(child_group=child_group, parent_group=parent_group) + factories.GroupAccountMembershipFactory.create(group=child_group, account=account) # Set up workspace sharing. - factories.WorkspaceGroupSharingFactory.create( - workspace=workspace, group=grandparent_group - ) + factories.WorkspaceGroupSharingFactory.create(workspace=workspace, group=grandparent_group) # Tests. accessible_workspaces = account.get_accessible_workspaces() self.assertEqual(len(accessible_workspaces), 1) @@ -514,13 +486,9 @@ def test_get_accessible_workspaces_in_auth_domain_shared(self): auth_domain = factories.ManagedGroupFactory.create() workspace.authorization_domains.add(auth_domain) # Set up group membership. - factories.GroupAccountMembershipFactory.create( - group=auth_domain, account=account - ) + factories.GroupAccountMembershipFactory.create(group=auth_domain, account=account) # Set up workspace sharing. - factories.WorkspaceGroupSharingFactory.create( - workspace=workspace, group=auth_domain - ) + factories.WorkspaceGroupSharingFactory.create(workspace=workspace, group=auth_domain) # Tests. accessible_workspaces = account.get_accessible_workspaces() self.assertEqual(len(accessible_workspaces), 1) @@ -534,9 +502,7 @@ def test_get_accessible_workspaces_in_auth_domain_shared_with_different_group(se auth_domain = factories.ManagedGroupFactory.create() workspace.authorization_domains.add(auth_domain) # Set up group membership. - factories.GroupAccountMembershipFactory.create( - group=auth_domain, account=account - ) + factories.GroupAccountMembershipFactory.create(group=auth_domain, account=account) group = factories.ManagedGroupFactory.create() factories.GroupAccountMembershipFactory.create(group=group, account=account) # Set up workspace sharing. @@ -554,9 +520,7 @@ def test_get_accessible_workspaces_in_auth_domain_not_shared(self): auth_domain = factories.ManagedGroupFactory.create() workspace.authorization_domains.add(auth_domain) # Set up group membership. - factories.GroupAccountMembershipFactory.create( - group=auth_domain, account=account - ) + factories.GroupAccountMembershipFactory.create(group=auth_domain, account=account) # Set up workspace sharing. # Tests. self.assertEqual(len(account.get_accessible_workspaces()), 0) @@ -570,9 +534,7 @@ def test_get_accessible_workspaces_not_in_auth_domain_shared(self): workspace.authorization_domains.add(auth_domain) # Set up group membership. # Set up workspace sharing. - factories.WorkspaceGroupSharingFactory.create( - workspace=workspace, group=auth_domain - ) + factories.WorkspaceGroupSharingFactory.create(workspace=workspace, group=auth_domain) # Tests. self.assertEqual(len(account.get_accessible_workspaces()), 0) @@ -585,14 +547,10 @@ def test_get_accessible_workspaces_in_auth_domain_as_parent_shared(self): workspace.authorization_domains.add(auth_domain) # Set up group membership. group = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - child_group=group, parent_group=auth_domain - ) + factories.GroupGroupMembershipFactory.create(child_group=group, parent_group=auth_domain) factories.GroupAccountMembershipFactory.create(group=group, account=account) # Set up workspace sharing. - factories.WorkspaceGroupSharingFactory.create( - workspace=workspace, group=auth_domain - ) + factories.WorkspaceGroupSharingFactory.create(workspace=workspace, group=auth_domain) # Tests. accessible_workspaces = account.get_accessible_workspaces() self.assertEqual(len(accessible_workspaces), 1) @@ -608,19 +566,11 @@ def test_get_accessible_workspaces_in_auth_domain_as_grandparent_shared(self): # Set up group membership. child_group = factories.ManagedGroupFactory.create() parent_group = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - child_group=child_group, parent_group=parent_group - ) - factories.GroupGroupMembershipFactory.create( - child_group=parent_group, parent_group=auth_domain - ) - factories.GroupAccountMembershipFactory.create( - group=child_group, account=account - ) + factories.GroupGroupMembershipFactory.create(child_group=child_group, parent_group=parent_group) + factories.GroupGroupMembershipFactory.create(child_group=parent_group, parent_group=auth_domain) + factories.GroupAccountMembershipFactory.create(group=child_group, account=account) # Set up workspace sharing. - factories.WorkspaceGroupSharingFactory.create( - workspace=workspace, group=auth_domain - ) + factories.WorkspaceGroupSharingFactory.create(workspace=workspace, group=auth_domain) # Tests. accessible_workspaces = account.get_accessible_workspaces() self.assertEqual(len(accessible_workspaces), 1) @@ -636,21 +586,13 @@ def test_get_accessible_workspaces_in_auth_domain_shared_with_different_parent( auth_domain = factories.ManagedGroupFactory.create() workspace.authorization_domains.add(auth_domain) # Set up group membership. - factories.GroupAccountMembershipFactory.create( - group=auth_domain, account=account - ) + factories.GroupAccountMembershipFactory.create(group=auth_domain, account=account) child_group = factories.ManagedGroupFactory.create() parent_group = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - child_group=child_group, parent_group=parent_group - ) - factories.GroupAccountMembershipFactory.create( - group=child_group, account=account - ) + factories.GroupGroupMembershipFactory.create(child_group=child_group, parent_group=parent_group) + factories.GroupAccountMembershipFactory.create(group=child_group, account=account) # Set up workspace sharing. - factories.WorkspaceGroupSharingFactory.create( - workspace=workspace, group=parent_group - ) + factories.WorkspaceGroupSharingFactory.create(workspace=workspace, group=parent_group) # Tests. accessible_workspaces = account.get_accessible_workspaces() self.assertEqual(len(accessible_workspaces), 1) @@ -666,25 +608,15 @@ def test_get_accessible_worspaces_in_auth_domain_shared_with_different_grandpare auth_domain = factories.ManagedGroupFactory.create() workspace.authorization_domains.add(auth_domain) # Set up group membership. - factories.GroupAccountMembershipFactory.create( - group=auth_domain, account=account - ) + factories.GroupAccountMembershipFactory.create(group=auth_domain, account=account) child_group = factories.ManagedGroupFactory.create() - factories.GroupAccountMembershipFactory.create( - group=child_group, account=account - ) + factories.GroupAccountMembershipFactory.create(group=child_group, account=account) parent_group = factories.ManagedGroupFactory.create() grandparent_group = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - child_group=child_group, parent_group=parent_group - ) - factories.GroupGroupMembershipFactory.create( - child_group=parent_group, parent_group=grandparent_group - ) + factories.GroupGroupMembershipFactory.create(child_group=child_group, parent_group=parent_group) + factories.GroupGroupMembershipFactory.create(child_group=parent_group, parent_group=grandparent_group) # Set up workspace sharing. - factories.WorkspaceGroupSharingFactory.create( - workspace=workspace, group=grandparent_group - ) + factories.WorkspaceGroupSharingFactory.create(workspace=workspace, group=grandparent_group) # Tests. accessible_workspaces = account.get_accessible_workspaces() self.assertEqual(len(accessible_workspaces), 1) @@ -699,16 +631,10 @@ def test_get_accessible_workspaces_two_auth_domains_in_both_shared_with_one(self auth_domain_2 = factories.ManagedGroupFactory.create() workspace.authorization_domains.add(auth_domain_1, auth_domain_2) # Set up group membership. - factories.GroupAccountMembershipFactory.create( - group=auth_domain_1, account=account - ) - factories.GroupAccountMembershipFactory.create( - group=auth_domain_2, account=account - ) + factories.GroupAccountMembershipFactory.create(group=auth_domain_1, account=account) + factories.GroupAccountMembershipFactory.create(group=auth_domain_2, account=account) # Set up workspace sharing. - factories.WorkspaceGroupSharingFactory.create( - workspace=workspace, group=auth_domain_1 - ) + factories.WorkspaceGroupSharingFactory.create(workspace=workspace, group=auth_domain_1) # Tests. accessible_workspaces = account.get_accessible_workspaces() self.assertEqual(len(accessible_workspaces), 1) @@ -723,13 +649,9 @@ def test_get_accessible_workspaces_two_auth_domains_in_one_shared(self): auth_domain_2 = factories.ManagedGroupFactory.create() workspace.authorization_domains.add(auth_domain_1, auth_domain_2) # Set up group membership. - factories.GroupAccountMembershipFactory.create( - group=auth_domain_1, account=account - ) + factories.GroupAccountMembershipFactory.create(group=auth_domain_1, account=account) # Set up workspace sharing. - factories.WorkspaceGroupSharingFactory.create( - workspace=workspace, group=auth_domain_1 - ) + factories.WorkspaceGroupSharingFactory.create(workspace=workspace, group=auth_domain_1) # Tests. self.assertEqual(len(account.get_accessible_workspaces()), 0) @@ -744,12 +666,8 @@ def test_get_accessible_workspaces_two_auth_domains_in_both_shared_different_gro auth_domain_2 = factories.ManagedGroupFactory.create() workspace.authorization_domains.add(auth_domain_1, auth_domain_2) # Set up group membership. - factories.GroupAccountMembershipFactory.create( - account=account, group=auth_domain_1 - ) - factories.GroupAccountMembershipFactory.create( - account=account, group=auth_domain_2 - ) + factories.GroupAccountMembershipFactory.create(account=account, group=auth_domain_1) + factories.GroupAccountMembershipFactory.create(account=account, group=auth_domain_2) group = factories.ManagedGroupFactory.create() factories.GroupAccountMembershipFactory.create(group=group, account=account) # Set up workspace sharing. @@ -770,12 +688,8 @@ def test_get_accessible_workspaces_workspace_only_appears_once(self): group_2 = factories.ManagedGroupFactory.create() factories.GroupAccountMembershipFactory.create(group=group_2, account=account) # Set up workspace sharing. - factories.WorkspaceGroupSharingFactory.create( - workspace=workspace, group=group_1 - ) - factories.WorkspaceGroupSharingFactory.create( - workspace=workspace, group=group_2 - ) + factories.WorkspaceGroupSharingFactory.create(workspace=workspace, group=group_1) + factories.WorkspaceGroupSharingFactory.create(workspace=workspace, group=group_2) # Tests. accessible_workspaces = account.get_accessible_workspaces() self.assertEqual(len(accessible_workspaces), 1) @@ -796,9 +710,7 @@ def test_get_all_groups_one_parent(self): child = factories.ManagedGroupFactory.create() factories.GroupAccountMembershipFactory.create(group=child, account=account) parent = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) groups = account.get_all_groups() self.assertEqual(len(groups), 2) self.assertIn(parent, groups) @@ -810,9 +722,7 @@ def test_get_all_groups_one_parent_account_in_both(self): child = factories.ManagedGroupFactory.create() factories.GroupAccountMembershipFactory.create(group=child, account=account) parent = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) factories.GroupAccountMembershipFactory.create(group=parent, account=account) groups = account.get_all_groups() self.assertEqual(len(groups), 2) @@ -825,13 +735,9 @@ def test_get_all_groups_one_grandparent(self): child = factories.ManagedGroupFactory.create() factories.GroupAccountMembershipFactory.create(group=child, account=account) parent = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) grandparent = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent, child_group=parent - ) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent, child_group=parent) groups = account.get_all_groups() self.assertEqual(len(groups), 3) self.assertIn(parent, groups) @@ -844,17 +750,11 @@ def test_get_all_groups_one_parent_two_grandparents(self): child = factories.ManagedGroupFactory.create() factories.GroupAccountMembershipFactory.create(group=child, account=account) parent = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) grandparent_1 = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent_1, child_group=parent - ) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent_1, child_group=parent) grandparent_2 = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent_2, child_group=parent - ) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent_2, child_group=parent) groups = account.get_all_groups() self.assertEqual(len(groups), 4) self.assertIn(parent, groups) @@ -868,16 +768,10 @@ def test_get_all_groups_grandparent_is_also_parent(self): child = factories.ManagedGroupFactory.create() factories.GroupAccountMembershipFactory.create(group=child, account=account) parent = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) grandparent = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent, child_group=parent - ) - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent, child_group=parent) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent, child_group=child) groups = account.get_all_groups() self.assertEqual(len(groups), 3) self.assertIn(parent, groups) @@ -889,9 +783,7 @@ def test_get_all_groups_one_child(self): account = factories.AccountFactory.create() child = factories.ManagedGroupFactory.create() parent = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) factories.GroupAccountMembershipFactory.create(group=parent, account=account) groups = account.get_all_groups() self.assertEqual(len(groups), 1) @@ -964,14 +856,10 @@ def test_unique_email(self): def test_is_managed_by_app(self): """Can set the is_managed_by_app field.""" - instance = ManagedGroup( - name="my-group", is_managed_by_app=True, email="foo1@bar.com" - ) + instance = ManagedGroup(name="my-group", is_managed_by_app=True, email="foo1@bar.com") instance.full_clean() instance.save() - instance_2 = ManagedGroup( - name="my-group-2", is_managed_by_app=False, email="foo2@bar.com" - ) + instance_2 = ManagedGroup(name="my-group-2", is_managed_by_app=False, email="foo2@bar.com") instance_2.full_clean() instance_2.save() @@ -990,9 +878,7 @@ def test_cannot_delete_group_that_is_a_member_of_another_group(self): This is a behavior enforced by AnVIL.""" parent = factories.ManagedGroupFactory.create() child = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) with self.assertRaises(ProtectedError): child.delete() # Both groups still exist. @@ -1004,9 +890,7 @@ def test_can_delete_group_if_it_has_child_groups(self): """A group can be deleted if it has other groups as members.""" parent = factories.ManagedGroupFactory.create() child = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) parent.delete() # Only the child group still exists. self.assertEqual(ManagedGroup.objects.count(), 1) @@ -1047,31 +931,21 @@ def test_cannot_delete_group_if_it_has_access_to_a_workspace(self): def test_get_direct_parents_no_parents(self): group = factories.ManagedGroupFactory(name="group") self.assertEqual(group.get_direct_parents().count(), 0) - self.assertQuerySetEqual( - group.get_direct_parents(), ManagedGroup.objects.none() - ) + self.assertQuerySetEqual(group.get_direct_parents(), ManagedGroup.objects.none()) def test_get_direct_parents_one_parent(self): parent = factories.ManagedGroupFactory(name="parent-group") child = factories.ManagedGroupFactory(name="child-group") - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) self.assertEqual(child.get_direct_parents().count(), 1) - self.assertQuerySetEqual( - child.get_direct_parents(), ManagedGroup.objects.filter(pk=parent.pk) - ) + self.assertQuerySetEqual(child.get_direct_parents(), ManagedGroup.objects.filter(pk=parent.pk)) def test_get_direct_parents_one_child_two_parents(self): parent_1 = factories.ManagedGroupFactory(name="parent-group-1") parent_2 = factories.ManagedGroupFactory(name="parent-group-2") child = factories.ManagedGroupFactory(name="child-group") - factories.GroupGroupMembershipFactory.create( - parent_group=parent_1, child_group=child - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent_2, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=parent_1, child_group=child) + factories.GroupGroupMembershipFactory.create(parent_group=parent_2, child_group=child) self.assertEqual(child.get_direct_parents().count(), 2) self.assertQuerySetEqual( child.get_direct_parents(), @@ -1083,20 +957,12 @@ def test_get_direct_parents_two_children_one_parent(self): parent = factories.ManagedGroupFactory(name="parent-group-1") child_1 = factories.ManagedGroupFactory(name="child-group-1") child_2 = factories.ManagedGroupFactory(name="child-group-2") - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child_1 - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child_2 - ) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child_1) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child_2) self.assertEqual(child_1.get_direct_parents().count(), 1) - self.assertQuerySetEqual( - child_1.get_direct_parents(), ManagedGroup.objects.filter(pk=parent.pk) - ) + self.assertQuerySetEqual(child_1.get_direct_parents(), ManagedGroup.objects.filter(pk=parent.pk)) self.assertEqual(child_2.get_direct_parents().count(), 1) - self.assertQuerySetEqual( - child_2.get_direct_parents(), ManagedGroup.objects.filter(pk=parent.pk) - ) + self.assertQuerySetEqual(child_2.get_direct_parents(), ManagedGroup.objects.filter(pk=parent.pk)) def test_get_direct_parents_with_other_group(self): # Create a relationship not involving the group in question. @@ -1108,54 +974,36 @@ def test_get_direct_parents_with_other_group(self): def test_get_direct_parents_with_only_child(self): parent = factories.ManagedGroupFactory(name="parent-group") child = factories.ManagedGroupFactory(name="child-group") - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) self.assertEqual(parent.get_direct_parents().count(), 0) def test_get_direct_parents_with_grandparent(self): grandparent = factories.ManagedGroupFactory(name="grandparent-group") parent = factories.ManagedGroupFactory(name="parent-group") child = factories.ManagedGroupFactory(name="child-group") - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent, child_group=parent - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent, child_group=parent) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) self.assertEqual(child.get_direct_parents().count(), 1) - self.assertQuerySetEqual( - child.get_direct_parents(), ManagedGroup.objects.filter(pk=parent.pk) - ) + self.assertQuerySetEqual(child.get_direct_parents(), ManagedGroup.objects.filter(pk=parent.pk)) def test_get_direct_children_no_children(self): group = factories.ManagedGroupFactory(name="group") self.assertEqual(group.get_direct_children().count(), 0) - self.assertQuerySetEqual( - group.get_direct_children(), ManagedGroup.objects.none() - ) + self.assertQuerySetEqual(group.get_direct_children(), ManagedGroup.objects.none()) def test_get_direct_children_one_child(self): parent = factories.ManagedGroupFactory(name="parent-group") child = factories.ManagedGroupFactory(name="child-group") - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) self.assertEqual(parent.get_direct_children().count(), 1) - self.assertQuerySetEqual( - parent.get_direct_children(), ManagedGroup.objects.filter(pk=child.pk) - ) + self.assertQuerySetEqual(parent.get_direct_children(), ManagedGroup.objects.filter(pk=child.pk)) def test_get_direct_children_one_parent_two_children(self): child_1 = factories.ManagedGroupFactory(name="child-group-1") child_2 = factories.ManagedGroupFactory(name="child-group-2") parent = factories.ManagedGroupFactory(name="parent-group") - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child_1 - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child_2 - ) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child_1) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child_2) self.assertEqual(parent.get_direct_children().count(), 2) self.assertQuerySetEqual( parent.get_direct_children(), @@ -1167,20 +1015,12 @@ def test_get_direct_parents_two_parents_one_child(self): child = factories.ManagedGroupFactory(name="child-group-1") parent_1 = factories.ManagedGroupFactory(name="parent-group-1") parent_2 = factories.ManagedGroupFactory(name="parent-group-2") - factories.GroupGroupMembershipFactory.create( - parent_group=parent_1, child_group=child - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent_2, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=parent_1, child_group=child) + factories.GroupGroupMembershipFactory.create(parent_group=parent_2, child_group=child) self.assertEqual(parent_1.get_direct_children().count(), 1) - self.assertQuerySetEqual( - parent_1.get_direct_children(), ManagedGroup.objects.filter(pk=child.pk) - ) + self.assertQuerySetEqual(parent_1.get_direct_children(), ManagedGroup.objects.filter(pk=child.pk)) self.assertEqual(parent_2.get_direct_children().count(), 1) - self.assertQuerySetEqual( - parent_2.get_direct_children(), ManagedGroup.objects.filter(pk=child.pk) - ) + self.assertQuerySetEqual(parent_2.get_direct_children(), ManagedGroup.objects.filter(pk=child.pk)) def test_get_direct_children_with_other_group(self): # Create a relationship not involving the group in question. @@ -1192,25 +1032,17 @@ def test_get_direct_children_with_other_group(self): def test_get_direct_children_with_only_parent(self): parent = factories.ManagedGroupFactory(name="parent-group") child = factories.ManagedGroupFactory(name="child-group") - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) self.assertEqual(child.get_direct_children().count(), 0) def test_get_direct_children_with_grandchildren(self): grandparent = factories.ManagedGroupFactory(name="grandparent-group") parent = factories.ManagedGroupFactory(name="parent-group") child = factories.ManagedGroupFactory(name="child-group") - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent, child_group=parent - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent, child_group=parent) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) self.assertEqual(grandparent.get_direct_children().count(), 1) - self.assertQuerySetEqual( - grandparent.get_direct_children(), ManagedGroup.objects.filter(pk=parent.pk) - ) + self.assertQuerySetEqual(grandparent.get_direct_children(), ManagedGroup.objects.filter(pk=parent.pk)) def test_get_all_parents_no_parents(self): group = factories.ManagedGroupFactory(name="group") @@ -1220,24 +1052,16 @@ def test_get_all_parents_no_parents(self): def test_get_all_parents_one_parent(self): parent = factories.ManagedGroupFactory(name="parent-group") child = factories.ManagedGroupFactory(name="child-group") - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) self.assertEqual(child.get_all_parents().count(), 1) - self.assertQuerySetEqual( - child.get_all_parents(), ManagedGroup.objects.filter(pk=parent.pk) - ) + self.assertQuerySetEqual(child.get_all_parents(), ManagedGroup.objects.filter(pk=parent.pk)) def test_get_all_parents_one_grandparent(self): grandparent = factories.ManagedGroupFactory(name="grandparent-group") parent = factories.ManagedGroupFactory(name="parent-group") child = factories.ManagedGroupFactory(name="child-group") - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent, child_group=parent - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent, child_group=parent) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) self.assertEqual(child.get_all_parents().count(), 2) self.assertQuerySetEqual( child.get_all_parents(), @@ -1250,21 +1074,13 @@ def test_get_all_parents_two_grandparents_same_parent(self): grandparent_2 = factories.ManagedGroupFactory(name="grandparent-group-2") parent = factories.ManagedGroupFactory(name="parent-group") child = factories.ManagedGroupFactory(name="child-group") - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent_1, child_group=parent - ) - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent_2, child_group=parent - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent_1, child_group=parent) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent_2, child_group=parent) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) self.assertEqual(child.get_all_parents().count(), 3) self.assertQuerySetEqual( child.get_all_parents(), - ManagedGroup.objects.filter( - pk__in=[grandparent_1.pk, grandparent_2.pk, parent.pk] - ), + ManagedGroup.objects.filter(pk__in=[grandparent_1.pk, grandparent_2.pk, parent.pk]), ordered=False, ) @@ -1274,24 +1090,14 @@ def test_get_all_parents_two_grandparents_two_parents(self): parent_1 = factories.ManagedGroupFactory(name="parent-group-1") parent_2 = factories.ManagedGroupFactory(name="parent-group-2") child = factories.ManagedGroupFactory(name="child-group") - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent_1, child_group=parent_1 - ) - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent_2, child_group=parent_2 - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent_1, child_group=child - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent_2, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent_1, child_group=parent_1) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent_2, child_group=parent_2) + factories.GroupGroupMembershipFactory.create(parent_group=parent_1, child_group=child) + factories.GroupGroupMembershipFactory.create(parent_group=parent_2, child_group=child) self.assertEqual(child.get_all_parents().count(), 4) self.assertQuerySetEqual( child.get_all_parents(), - ManagedGroup.objects.filter( - pk__in=[grandparent_1.pk, grandparent_2.pk, parent_1.pk, parent_2.pk] - ), + ManagedGroup.objects.filter(pk__in=[grandparent_1.pk, grandparent_2.pk, parent_1.pk, parent_2.pk]), ordered=False, ) @@ -1300,16 +1106,10 @@ def test_get_all_parents_multiple_paths_to_same_group(self): parent = factories.ManagedGroupFactory(name="parent-group") child = factories.ManagedGroupFactory(name="child-group") # Create the standard grandparent-parent-child relationship - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent, child_group=parent - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent, child_group=parent) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) # Then create a grandparent-child direct relationship. - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent, child_group=child) self.assertEqual(child.get_all_parents().count(), 2) self.assertQuerySetEqual( child.get_all_parents(), @@ -1323,21 +1123,13 @@ def test_all_parents_greatgrandparent(self): parent = factories.ManagedGroupFactory(name="parent-group") child = factories.ManagedGroupFactory(name="child-group") # Create the standard grandparent-parent-child relationship - factories.GroupGroupMembershipFactory.create( - parent_group=greatgrandparent, child_group=grandparent - ) - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent, child_group=parent - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=greatgrandparent, child_group=grandparent) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent, child_group=parent) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) self.assertEqual(child.get_all_parents().count(), 3) self.assertQuerySetEqual( child.get_all_parents(), - ManagedGroup.objects.filter( - pk__in=[greatgrandparent.pk, grandparent.pk, parent.pk] - ), + ManagedGroup.objects.filter(pk__in=[greatgrandparent.pk, grandparent.pk, parent.pk]), ordered=False, ) @@ -1346,12 +1138,8 @@ def test_get_all_parents_with_other_group(self): parent = factories.ManagedGroupFactory(name="parent-group") child = factories.ManagedGroupFactory(name="child-group") # Create the standard grandparent-parent-child relationship - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent, child_group=parent - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent, child_group=parent) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) # Create a group with no relationships group = factories.ManagedGroupFactory.create(name="other-group") self.assertEqual(group.get_all_parents().count(), 0) @@ -1364,24 +1152,16 @@ def test_get_all_children_no_children(self): def test_get_all_children_one_child(self): parent = factories.ManagedGroupFactory(name="parent-group") child = factories.ManagedGroupFactory(name="child-group") - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) self.assertEqual(parent.get_all_children().count(), 1) - self.assertQuerySetEqual( - parent.get_all_children(), ManagedGroup.objects.filter(pk=child.pk) - ) + self.assertQuerySetEqual(parent.get_all_children(), ManagedGroup.objects.filter(pk=child.pk)) def test_get_all_children_one_grandchild(self): grandparent = factories.ManagedGroupFactory(name="grandparent-group") parent = factories.ManagedGroupFactory(name="parent-group") child = factories.ManagedGroupFactory(name="child-group") - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent, child_group=parent - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent, child_group=parent) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) self.assertEqual(grandparent.get_all_children().count(), 2) self.assertQuerySetEqual( grandparent.get_all_children(), @@ -1394,15 +1174,9 @@ def test_get_all_children_two_grandchildren_same_parent(self): parent = factories.ManagedGroupFactory(name="parent-group") child_1 = factories.ManagedGroupFactory(name="child-group-1") child_2 = factories.ManagedGroupFactory(name="child-group-2") - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent, child_group=parent - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child_1 - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child_2 - ) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent, child_group=parent) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child_1) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child_2) self.assertEqual(grandparent.get_all_children().count(), 3) self.assertQuerySetEqual( grandparent.get_all_children(), @@ -1416,24 +1190,14 @@ def test_get_all_children_two_grandchildren_two_parents(self): parent_2 = factories.ManagedGroupFactory(name="parent-group-2") child_1 = factories.ManagedGroupFactory(name="child-group-1") child_2 = factories.ManagedGroupFactory(name="child-group-2") - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent, child_group=parent_1 - ) - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent, child_group=parent_2 - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent_1, child_group=child_1 - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent_2, child_group=child_2 - ) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent, child_group=parent_1) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent, child_group=parent_2) + factories.GroupGroupMembershipFactory.create(parent_group=parent_1, child_group=child_1) + factories.GroupGroupMembershipFactory.create(parent_group=parent_2, child_group=child_2) self.assertEqual(grandparent.get_all_children().count(), 4) self.assertQuerySetEqual( grandparent.get_all_children(), - ManagedGroup.objects.filter( - pk__in=[parent_1.pk, parent_2.pk, child_1.pk, child_2.pk] - ), + ManagedGroup.objects.filter(pk__in=[parent_1.pk, parent_2.pk, child_1.pk, child_2.pk]), ordered=False, ) @@ -1442,16 +1206,10 @@ def test_get_all_children_multiple_paths_to_same_group(self): parent = factories.ManagedGroupFactory(name="parent-group") child = factories.ManagedGroupFactory(name="child-group") # Create the standard grandparent-parent-child relationship - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent, child_group=parent - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent, child_group=parent) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) # Then create a grandparent-child direct relationship. - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent, child_group=child) self.assertEqual(grandparent.get_all_children().count(), 2) self.assertQuerySetEqual( grandparent.get_all_children(), @@ -1465,15 +1223,9 @@ def test_all_children_greatgrandparent(self): parent = factories.ManagedGroupFactory(name="parent-group") child = factories.ManagedGroupFactory(name="child-group") # Create the standard grandparent-parent-child relationship - factories.GroupGroupMembershipFactory.create( - parent_group=greatgrandparent, child_group=grandparent - ) - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent, child_group=parent - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=greatgrandparent, child_group=grandparent) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent, child_group=parent) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) self.assertEqual(greatgrandparent.get_all_children().count(), 3) self.assertQuerySetEqual( greatgrandparent.get_all_children(), @@ -1486,12 +1238,8 @@ def test_get_all_children_with_other_group(self): parent = factories.ManagedGroupFactory(name="parent-group") child = factories.ManagedGroupFactory(name="child-group") # Create the standard grandparent-parent-child relationship - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent, child_group=parent - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent, child_group=parent) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) # Create a group with no relationships group = factories.ManagedGroupFactory.create(name="other-group") self.assertEqual(group.get_all_children().count(), 0) @@ -1518,15 +1266,9 @@ def test_get_full_graph(self): parent_group_1 = groups[1] parent_group_2 = groups[2] child_group_1 = groups[3] - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent_group, child_group=parent_group_1 - ) - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent_group, child_group=parent_group_2 - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent_group_1, child_group=child_group_1 - ) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent_group, child_group=parent_group_1) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent_group, child_group=parent_group_2) + factories.GroupGroupMembershipFactory.create(parent_group=parent_group_1, child_group=child_group_1) G = ManagedGroup.get_full_graph() # Check nodes. self.assertIsInstance(G, nx.DiGraph) @@ -1548,15 +1290,9 @@ def test_get_graph(self): parent_group_1 = groups[1] parent_group_2 = groups[2] child_group_1 = groups[3] - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent_group, child_group=parent_group_1 - ) - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent_group, child_group=parent_group_2 - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent_group_1, child_group=child_group_1 - ) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent_group, child_group=parent_group_1) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent_group, child_group=parent_group_2) + factories.GroupGroupMembershipFactory.create(parent_group=parent_group_1, child_group=child_group_1) G = parent_group_1.get_graph() # Check nodes. self.assertIsInstance(G, nx.DiGraph) @@ -1657,9 +1393,7 @@ def test_history_foreign_key_billing_project(self): obj.billing_project.delete() self.assertEqual(Workspace.history.count(), 2) # Make sure you can access it. - self.assertEqual( - Workspace.history.all()[1].billing_project_id, billing_project_pk - ) + self.assertEqual(Workspace.history.all()[1].billing_project_id, billing_project_pk) def test_workspace_on_delete_is_in_authorization_domain(self): """Workspace can be deleted if it has an authorization domain.""" @@ -1704,12 +1438,8 @@ def test_cannot_have_duplicated_billing_project_and_name(self): def test_can_have_same_name_in_different_billing_project(self): """Can have two workspaces with the same name but in different billing_projects.""" name = "test-name" - billing_project_1 = factories.BillingProjectFactory.create( - name="test-project-1" - ) - billing_project_2 = factories.BillingProjectFactory.create( - name="test-project-2" - ) + billing_project_1 = factories.BillingProjectFactory.create(name="test-project-1") + billing_project_2 = factories.BillingProjectFactory.create(name="test-project-2") instance1 = Workspace(billing_project=billing_project_1, name=name) instance1.save() instance2 = Workspace(billing_project=billing_project_2, name=name) @@ -1755,12 +1485,8 @@ def test_two_is_in_authorization_domains(self): instance.save() instance.authorization_domains.set(ManagedGroup.objects.all()) self.assertEqual(len(instance.authorization_domains.all()), 2) - self.assertIn( - is_in_authorization_domain_1, instance.authorization_domains.all() - ) - self.assertIn( - is_in_authorization_domain_2, instance.authorization_domains.all() - ) + self.assertIn(is_in_authorization_domain_1, instance.authorization_domains.all()) + self.assertIn(is_in_authorization_domain_2, instance.authorization_domains.all()) def test_is_in_authorization_domain_unique(self): """Adding the same auth domain twice does nothing.""" @@ -1796,9 +1522,7 @@ def test_get_anvil_url(self): def test_workspace_type_not_registered(self): """A ValidationError is raised if the workspace_type is not a registered adapter type.""" billing_project = factories.BillingProjectFactory.create() - instance = factories.WorkspaceFactory.build( - billing_project=billing_project, workspace_type="foo" - ) + instance = factories.WorkspaceFactory.build(billing_project=billing_project, workspace_type="foo") with self.assertRaises(ValidationError) as e: instance.clean_fields() self.assertIn("not a registered adapter type", str(e.exception)) @@ -1913,13 +1637,9 @@ def test_is_in_auth_domain_child(self): self.workspace.authorization_domains.add(self.auth_domain) child_group = factories.ManagedGroupFactory.create() # Add the child group to the auth domain. - factories.GroupGroupMembershipFactory.create( - parent_group=self.auth_domain, child_group=child_group - ) + factories.GroupGroupMembershipFactory.create(parent_group=self.auth_domain, child_group=child_group) # Add the child group to the group. - factories.GroupGroupMembershipFactory.create( - parent_group=self.group, child_group=child_group - ) + factories.GroupGroupMembershipFactory.create(parent_group=self.group, child_group=child_group) # Do not add the group itself to the auth domain. self.assertFalse(self.workspace.is_in_authorization_domain(self.group)) self.assertFalse(self.group.is_in_authorization_domain(self.workspace)) @@ -1931,9 +1651,7 @@ def test_is_shared_not_shared(self): def test_is_shared_is_shared(self): """Returns True when the workspace is shared with the group.""" - factories.WorkspaceGroupSharingFactory.create( - workspace=self.workspace, group=self.group - ) + factories.WorkspaceGroupSharingFactory.create(workspace=self.workspace, group=self.group) self.assertTrue(self.workspace.is_shared(self.group)) self.assertTrue(self.group.is_shared(self.workspace)) @@ -1941,13 +1659,9 @@ def test_is_shared_shared_with_parent(self): """Returns False when the workspace is shared with a parent group.""" # Create the parent group structure. parent_group = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - parent_group=parent_group, child_group=self.group - ) + factories.GroupGroupMembershipFactory.create(parent_group=parent_group, child_group=self.group) # Share with the parent. - factories.WorkspaceGroupSharingFactory.create( - workspace=self.workspace, group=parent_group - ) + factories.WorkspaceGroupSharingFactory.create(workspace=self.workspace, group=parent_group) self.assertTrue(self.workspace.is_shared(self.group)) self.assertTrue(self.group.is_shared(self.workspace)) @@ -1956,37 +1670,25 @@ def test_is_shared_shared_with_grandparent(self): # Create the grandparent group structure. grandparent_group = factories.ManagedGroupFactory.create() parent_group = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent_group, child_group=parent_group - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent_group, child_group=self.group - ) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent_group, child_group=parent_group) + factories.GroupGroupMembershipFactory.create(parent_group=parent_group, child_group=self.group) # Share with the grandparent. - factories.WorkspaceGroupSharingFactory.create( - workspace=self.workspace, group=grandparent_group - ) + factories.WorkspaceGroupSharingFactory.create(workspace=self.workspace, group=grandparent_group) self.assertTrue(self.workspace.is_shared(self.group)) self.assertTrue(self.group.is_shared(self.workspace)) def test_is_shared_shared_with_child(self): """Returns False when the workspace is shared with a child group but not the group itself.""" child_group = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - parent_group=self.group, child_group=child_group - ) + factories.GroupGroupMembershipFactory.create(parent_group=self.group, child_group=child_group) # Share with the child. - factories.WorkspaceGroupSharingFactory.create( - workspace=self.workspace, group=child_group - ) + factories.WorkspaceGroupSharingFactory.create(workspace=self.workspace, group=child_group) self.assertFalse(self.workspace.is_shared(self.group)) self.assertFalse(self.group.is_shared(self.workspace)) def test_has_access_shared_no_auth_domain(self): """Returns True when the group is shared and there is no auth domain.""" - factories.WorkspaceGroupSharingFactory.create( - workspace=self.workspace, group=self.group - ) + factories.WorkspaceGroupSharingFactory.create(workspace=self.workspace, group=self.group) self.assertTrue(self.workspace.has_access(self.group)) self.assertTrue(self.group.has_access(self.workspace)) @@ -1998,39 +1700,29 @@ def test_has_access_not_shared_no_auth_domain(self): def test_has_access_shared_in_auth_domain(self): """Returns True when the group is shared and in the auth domain.""" self.workspace.authorization_domains.add(self.auth_domain) - factories.GroupGroupMembershipFactory.create( - parent_group=self.auth_domain, child_group=self.group - ) - factories.WorkspaceGroupSharingFactory.create( - workspace=self.workspace, group=self.group - ) + factories.GroupGroupMembershipFactory.create(parent_group=self.auth_domain, child_group=self.group) + factories.WorkspaceGroupSharingFactory.create(workspace=self.workspace, group=self.group) self.assertTrue(self.workspace.has_access(self.group)) self.assertTrue(self.group.has_access(self.workspace)) def test_has_access_shared_not_in_auth_domain(self): """Returns False when the group is shared but not in the auth domain.""" self.workspace.authorization_domains.add(self.auth_domain) - factories.WorkspaceGroupSharingFactory.create( - workspace=self.workspace, group=self.group - ) + factories.WorkspaceGroupSharingFactory.create(workspace=self.workspace, group=self.group) self.assertFalse(self.workspace.has_access(self.group)) self.assertFalse(self.group.has_access(self.workspace)) def test_has_access_not_shared_in_auth_domain(self): """Returns False when the group is not shared but in the auth domain.""" self.workspace.authorization_domains.add(self.auth_domain) - factories.GroupGroupMembershipFactory.create( - parent_group=self.auth_domain, child_group=self.group - ) + factories.GroupGroupMembershipFactory.create(parent_group=self.auth_domain, child_group=self.group) self.assertFalse(self.workspace.has_access(self.group)) self.assertFalse(self.group.has_access(self.workspace)) def test_has_access_not_shared_not_in_auth_domain(self): """Returns False when the group is not shared and not in the auth domain.""" self.workspace.authorization_domains.add(self.auth_domain) - factories.WorkspaceGroupSharingFactory.create( - workspace=self.workspace, group=self.group - ) + factories.WorkspaceGroupSharingFactory.create(workspace=self.workspace, group=self.group) self.assertFalse(self.workspace.has_access(self.group)) self.assertFalse(self.group.has_access(self.workspace)) @@ -2042,9 +1734,7 @@ def test_get_absolute_url(self): """get_absolute_url returns the url of the workspace.""" workspace = factories.WorkspaceFactory.create() workspace_data = DefaultWorkspaceData(workspace=workspace) - self.assertEqual( - workspace_data.get_absolute_url(), workspace.get_absolute_url() - ) + self.assertEqual(workspace_data.get_absolute_url(), workspace.get_absolute_url()) def test_str(self): workspace = factories.WorkspaceFactory.create() @@ -2094,9 +1784,7 @@ def test_history_foreign_key_workspace(self): workspace.delete() self.assertEqual(WorkspaceAuthorizationDomain.history.count(), 2) # Make sure you can access it. - self.assertEqual( - WorkspaceAuthorizationDomain.history.earliest().workspace_id, workspace_pk - ) + self.assertEqual(WorkspaceAuthorizationDomain.history.earliest().workspace_id, workspace_pk) def test_history_foreign_key_group(self): """History is retained when a workspace foreign key object is deleted.""" @@ -2110,9 +1798,7 @@ def test_history_foreign_key_group(self): group.delete() self.assertEqual(WorkspaceAuthorizationDomain.history.count(), 2) # Make sure you can still access the history. - self.assertEqual( - WorkspaceAuthorizationDomain.history.earliest().group_id, group_pk - ) + self.assertEqual(WorkspaceAuthorizationDomain.history.earliest().group_id, group_pk) class GroupGroupMembershipTest(TestCase): @@ -2120,18 +1806,14 @@ def test_model_saving(self): """Creation using the model constructor and .save() works.""" parent_group = factories.ManagedGroupFactory.create(name="parent") child_group = factories.ManagedGroupFactory.create(name="child") - instance = GroupGroupMembership( - parent_group=parent_group, child_group=child_group - ) + instance = GroupGroupMembership(parent_group=parent_group, child_group=child_group) self.assertIsInstance(instance, GroupGroupMembership) def test_str_method(self): """The custom __str__ method returns the correct string.""" parent_group = factories.ManagedGroupFactory.create(name="parent") child_group = factories.ManagedGroupFactory.create(name="child") - instance = GroupGroupMembership( - parent_group=parent_group, child_group=child_group - ) + instance = GroupGroupMembership(parent_group=parent_group, child_group=child_group) self.assertIsInstance(instance.__str__(), str) expected_string = "child as MEMBER in parent" self.assertEqual(instance.__str__(), expected_string) @@ -2143,9 +1825,7 @@ def test_get_absolute_url(self): def test_history(self): """A simple history record is created when model is updated.""" - obj = factories.GroupGroupMembershipFactory.create( - role=GroupGroupMembership.MEMBER - ) + obj = factories.GroupGroupMembershipFactory.create(role=GroupGroupMembership.MEMBER) # History was created. self.assertEqual(obj.history.count(), 1) # A new entry was created after update. @@ -2164,9 +1844,7 @@ def test_history_foreign_key_parent_group(self): obj.parent_group.delete() self.assertEqual(GroupGroupMembership.history.count(), 2) # Make sure you can access it. - self.assertEqual( - GroupGroupMembership.history.earliest().parent_group_id, parent_group_pk - ) + self.assertEqual(GroupGroupMembership.history.earliest().parent_group_id, parent_group_pk) def test_history_foreign_key_child_group(self): """History is retained when a child group foreign key object is deleted.""" @@ -2177,9 +1855,7 @@ def test_history_foreign_key_child_group(self): obj.child_group.delete() self.assertEqual(GroupGroupMembership.history.count(), 2) # Make sure you can access it. - self.assertEqual( - GroupGroupMembership.history.earliest().child_group_id, child_group_pk - ) + self.assertEqual(GroupGroupMembership.history.earliest().child_group_id, child_group_pk) def test_same_group_with_two_parent_groups(self): """The same group can be a child in two groups.""" @@ -2241,24 +1917,18 @@ def test_cannot_have_duplicated_parent_and_child_with_different_role(self): def test_cant_add_a_group_to_itself_member(self): group = factories.ManagedGroupFactory() - instance = GroupGroupMembership( - parent_group=group, child_group=group, role=GroupGroupMembership.MEMBER - ) + instance = GroupGroupMembership(parent_group=group, child_group=group, role=GroupGroupMembership.MEMBER) with self.assertRaises(ValidationError): instance.clean() def test_cant_add_a_group_to_itself_admin(self): group = factories.ManagedGroupFactory() - instance = GroupGroupMembership( - parent_group=group, child_group=group, role=GroupGroupMembership.ADMIN - ) + instance = GroupGroupMembership(parent_group=group, child_group=group, role=GroupGroupMembership.ADMIN) with self.assertRaisesRegex(ValidationError, "add a group to itself"): instance.clean() def test_circular_cant_add_parent_group_as_a_child(self): - obj = factories.GroupGroupMembershipFactory.create( - role=GroupGroupMembership.MEMBER - ) + obj = factories.GroupGroupMembershipFactory.create(role=GroupGroupMembership.MEMBER) instance = GroupGroupMembership( parent_group=obj.child_group, child_group=obj.parent_group, @@ -2271,12 +1941,8 @@ def test_circular_cant_add_grandparent_group_as_a_grandchild(self): grandparent = factories.ManagedGroupFactory(name="grandparent-group") parent = factories.ManagedGroupFactory(name="parent-group") child = factories.ManagedGroupFactory(name="child-group") - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent, child_group=parent - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent, child_group=parent) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) instance = GroupGroupMembership( parent_group=child, child_group=grandparent, @@ -2289,16 +1955,10 @@ def test_circular_multiple_paths(self): grandparent = factories.ManagedGroupFactory(name="grandparent-group") parent = factories.ManagedGroupFactory(name="parent-group") child = factories.ManagedGroupFactory(name="child-group") - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent, child_group=parent - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent, child_group=parent) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) # Also create a grandparent-child relationship. - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent, child_group=child) instance = GroupGroupMembership( parent_group=child, child_group=grandparent, @@ -2322,14 +1982,10 @@ def test_str_method(self): group = "test-group" account = factories.AccountFactory(email=email) group = factories.ManagedGroupFactory(name=group) - instance = GroupAccountMembership( - account=account, group=group, role=GroupAccountMembership.MEMBER - ) + instance = GroupAccountMembership(account=account, group=group, role=GroupAccountMembership.MEMBER) instance.save() self.assertIsInstance(instance.__str__(), str) - expected_string = "{email} as MEMBER in {group}".format( - email=email, group=group - ) + expected_string = "{email} as MEMBER in {group}".format(email=email, group=group) self.assertEqual(instance.__str__(), expected_string) def test_get_absolute_url(self): @@ -2339,9 +1995,7 @@ def test_get_absolute_url(self): def test_history(self): """A simple history record is created when model is updated.""" - obj = factories.GroupAccountMembershipFactory.create( - role=GroupAccountMembership.MEMBER - ) + obj = factories.GroupAccountMembershipFactory.create(role=GroupAccountMembership.MEMBER) # History was created. self.assertEqual(obj.history.count(), 1) # A new entry was created after update. @@ -2374,9 +2028,7 @@ def test_history_foreign_key_account(self): obj.account.delete() self.assertEqual(GroupAccountMembership.history.count(), 2) # Make sure you can access it. - self.assertEqual( - GroupAccountMembership.history.earliest().account_id, account_pk - ) + self.assertEqual(GroupAccountMembership.history.earliest().account_id, account_pk) def test_history_inactive_user(self): """Account active/inactive status is correct at time of history check.""" @@ -2398,9 +2050,7 @@ def test_history_inactive_user(self): # Check the history at timestamp to make sure the account shows active. record = obj.history.as_of(current_time) - self.assertEqual( - account.history.as_of(current_time).status, record.account.ACTIVE_STATUS - ) + self.assertEqual(account.history.as_of(current_time).status, record.account.ACTIVE_STATUS) self.assertEqual(record.account.status, record.account.ACTIVE_STATUS) def test_same_account_in_two_groups(self): @@ -2427,13 +2077,9 @@ def test_cannot_have_duplicated_account_and_group_with_same_role(self): """Cannot have the same account in the same group with the same role twice.""" account = factories.AccountFactory() group = factories.ManagedGroupFactory() - instance_1 = GroupAccountMembership( - account=account, group=group, role=GroupAccountMembership.MEMBER - ) + instance_1 = GroupAccountMembership(account=account, group=group, role=GroupAccountMembership.MEMBER) instance_1.save() - instance_2 = GroupAccountMembership( - account=account, group=group, role=GroupAccountMembership.MEMBER - ) + instance_2 = GroupAccountMembership(account=account, group=group, role=GroupAccountMembership.MEMBER) with self.assertRaises(IntegrityError): instance_2.save() @@ -2441,13 +2087,9 @@ def test_cannot_have_duplicated_account_and_group_with_different_role(self): """Cannot have the same account in the same group with different roles twice.""" account = factories.AccountFactory() group = factories.ManagedGroupFactory() - instance_1 = GroupAccountMembership( - account=account, group=group, role=GroupAccountMembership.MEMBER - ) + instance_1 = GroupAccountMembership(account=account, group=group, role=GroupAccountMembership.MEMBER) instance_1.save() - instance_2 = GroupAccountMembership( - account=account, group=group, role=GroupAccountMembership.ADMIN - ) + instance_2 = GroupAccountMembership(account=account, group=group, role=GroupAccountMembership.ADMIN) with self.assertRaises(IntegrityError): instance_2.save() @@ -2472,12 +2114,8 @@ def test_str_method(self): group_name = "test-group" billing_project = factories.BillingProjectFactory(name=billing_project_name) group = factories.ManagedGroupFactory(name=group_name) - workspace = factories.WorkspaceFactory( - billing_project=billing_project, name=workspace_name - ) - instance = WorkspaceGroupSharing( - group=group, workspace=workspace, access=WorkspaceGroupSharing.READER - ) + workspace = factories.WorkspaceFactory(billing_project=billing_project, name=workspace_name) + instance = WorkspaceGroupSharing(group=group, workspace=workspace, access=WorkspaceGroupSharing.READER) instance.save() self.assertIsInstance(instance.__str__(), str) expected_string = "test-group with READER to test-namespace/test-workspace" @@ -2546,9 +2184,7 @@ def test_clean_owner_can_compute_false(self): def test_history(self): """A simple history record is created when model is updated.""" - obj = factories.WorkspaceGroupSharingFactory.create( - access=WorkspaceGroupSharing.READER - ) + obj = factories.WorkspaceGroupSharingFactory.create(access=WorkspaceGroupSharing.READER) # History was created. self.assertEqual(obj.history.count(), 1) # A new entry was created after update. @@ -2569,9 +2205,7 @@ def test_history_foreign_key_workspace(self): obj.workspace.delete() self.assertEqual(WorkspaceGroupSharing.history.count(), 2) # Make sure you can access it. - self.assertEqual( - WorkspaceGroupSharing.history.earliest().workspace_id, workspace_pk - ) + self.assertEqual(WorkspaceGroupSharing.history.earliest().workspace_id, workspace_pk) def test_history_foreign_key_group(self): """History is retained when a group foreign key object is deleted.""" @@ -2608,13 +2242,9 @@ def test_cannot_have_duplicated_account_and_group_with_same_access(self): """Cannot have the same account in the same group with the same access levels twice.""" group = factories.ManagedGroupFactory() workspace = factories.WorkspaceFactory() - instance_1 = WorkspaceGroupSharing( - group=group, workspace=workspace, access=WorkspaceGroupSharing.READER - ) + instance_1 = WorkspaceGroupSharing(group=group, workspace=workspace, access=WorkspaceGroupSharing.READER) instance_1.save() - instance_2 = WorkspaceGroupSharing( - group=group, workspace=workspace, access=WorkspaceGroupSharing.READER - ) + instance_2 = WorkspaceGroupSharing(group=group, workspace=workspace, access=WorkspaceGroupSharing.READER) with self.assertRaises(IntegrityError): instance_2.save() @@ -2624,12 +2254,8 @@ def test_cannot_have_duplicated_account_and_group_with_different_access( """Cannot have the same account in the same group with different access levels twice.""" group = factories.ManagedGroupFactory() workspace = factories.WorkspaceFactory() - instance_1 = WorkspaceGroupSharing( - group=group, workspace=workspace, access=WorkspaceGroupSharing.READER - ) + instance_1 = WorkspaceGroupSharing(group=group, workspace=workspace, access=WorkspaceGroupSharing.READER) instance_1.save() - instance_2 = WorkspaceGroupSharing( - group=group, workspace=workspace, access=WorkspaceGroupSharing.WRITER - ) + instance_2 = WorkspaceGroupSharing(group=group, workspace=workspace, access=WorkspaceGroupSharing.WRITER) with self.assertRaises(IntegrityError): instance_2.save() diff --git a/anvil_consortium_manager/tests/test_models_anvil_api_unit.py b/anvil_consortium_manager/tests/test_models_anvil_api_unit.py index d6bd165b..5ddf70aa 100644 --- a/anvil_consortium_manager/tests/test_models_anvil_api_unit.py +++ b/anvil_consortium_manager/tests/test_models_anvil_api_unit.py @@ -15,18 +15,14 @@ class BillingProjectAnVILAPIMockTest(AnVILAPIMockTestMixin, TestCase): def setUp(self): super().setUp() self.object = factories.BillingProjectFactory() - self.url = ( - self.api_client.rawls_entry_point + "/api/billing/v2/" + self.object.name - ) + self.url = self.api_client.rawls_entry_point + "/api/billing/v2/" + self.object.name def test_anvil_exists_does_exist(self): self.anvil_response_mock.add(responses.GET, self.url, status=200) self.assertIs(self.object.anvil_exists(), True) def test_anvil_exists_does_not_exist(self): - self.anvil_response_mock.add( - responses.GET, self.url, status=404, json={"message": "mock message"} - ) + self.anvil_response_mock.add(responses.GET, self.url, status=404, json={"message": "mock message"}) self.assertIs(self.object.anvil_exists(), False) @@ -34,11 +30,7 @@ class BillingProjectAnVILImportAnVILAPIMockTest(AnVILAPIMockTestMixin, TestCase) """Tests for the BillingProject.anvil_import method.""" def get_api_url(self, billing_project_name): - return ( - self.api_client.rawls_entry_point - + "/api/billing/v2/" - + billing_project_name - ) + return self.api_client.rawls_entry_point + "/api/billing/v2/" + billing_project_name def get_api_json_response(self): return { @@ -54,9 +46,7 @@ def test_can_import_billing_project_where_we_are_users(self): status=200, json=self.get_api_json_response(), ) - billing_project = models.BillingProject.anvil_import( - billing_project_name, note="test note" - ) + billing_project = models.BillingProject.anvil_import(billing_project_name, note="test note") # Check values. self.assertEqual(billing_project.name, billing_project_name) self.assertEqual(billing_project.note, "test note") @@ -87,9 +77,7 @@ def test_billing_project_already_exists_in_db(self): models.BillingProject.anvil_import(billing_project.name) # Check that it was not saved. self.assertEqual(models.BillingProject.objects.count(), 1) - self.assertEqual( - models.BillingProject.objects.get(pk=billing_project.pk), billing_project - ) + self.assertEqual(models.BillingProject.objects.get(pk=billing_project.pk), billing_project) def test_anvil_import_api_internal_error(self): """No BillingProjects are created if there is an internal error from the AnVIL API.""" @@ -134,9 +122,7 @@ class UserEmailEntryAnVILAPIMockTest(AnVILAPIMockTestMixin, TestCase): def setUp(self): super().setUp() self.object = factories.UserEmailEntryFactory.create() - self.api_url = ( - self.api_client.sam_entry_point + "/api/users/v1/" + self.object.email - ) + self.api_url = self.api_client.sam_entry_point + "/api/users/v1/" + self.object.email def get_api_user_json_response(self, email): id = fake.bothify(text="#" * 21) @@ -156,9 +142,7 @@ def test_anvil_account_exists_does_exist(self): self.assertIs(self.object.anvil_account_exists(), True) def test_anvil_account_exists_does_not_exist(self): - self.anvil_response_mock.add( - responses.GET, self.api_url, status=404, json={"message": "mock message"} - ) + self.anvil_response_mock.add(responses.GET, self.api_url, status=404, json={"message": "mock message"}) self.assertIs(self.object.anvil_account_exists(), False) def test_anvil_account_exists_associated_with_group(self): @@ -170,27 +154,13 @@ class AccountAnVILAPIMockTest(AnVILAPIMockTestMixin, TestCase): def setUp(self): super().setUp() self.object = factories.AccountFactory.create() - self.api_url = ( - self.api_client.sam_entry_point + "/api/users/v1/" + self.object.email - ) + self.api_url = self.api_client.sam_entry_point + "/api/users/v1/" + self.object.email def get_api_add_to_group_url(self, group_name): - return ( - self.api_client.sam_entry_point - + "/api/groups/v1/" - + group_name - + "/member/" - + self.object.email - ) + return self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/member/" + self.object.email def get_api_remove_from_group_url(self, group_name): - return ( - self.api_client.sam_entry_point - + "/api/groups/v1/" - + group_name - + "/member/" - + self.object.email - ) + return self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/member/" + self.object.email def get_api_user_json_response(self, email): id = fake.bothify(text="#" * 21) @@ -210,9 +180,7 @@ def test_anvil_exists_does_exist(self): self.assertIs(self.object.anvil_exists(), True) def test_anvil_exists_does_not_exist(self): - self.anvil_response_mock.add( - responses.GET, self.api_url, status=404, json={"message": "mock message"} - ) + self.anvil_response_mock.add(responses.GET, self.api_url, status=404, json={"message": "mock message"}) self.assertIs(self.object.anvil_exists(), False) def test_anvil_exists_email_is_group(self): @@ -229,28 +197,20 @@ def test_anvil_remove_from_groups_in_one_group(self): membership = factories.GroupAccountMembershipFactory.create(account=self.object) group = membership.group remove_from_group_url = self.get_api_remove_from_group_url(group.name) - self.anvil_response_mock.add( - responses.DELETE, remove_from_group_url, status=204 - ) + self.anvil_response_mock.add(responses.DELETE, remove_from_group_url, status=204) self.object.anvil_remove_from_groups() # The membership was removed. self.assertEqual(models.GroupAccountMembership.objects.count(), 1) def test_anvil_remove_from_groups_in_two_groups(self): """anvil_remove_from_groups succeeds if the account is in two groups.""" - memberships = factories.GroupAccountMembershipFactory.create_batch( - 2, account=self.object - ) + memberships = factories.GroupAccountMembershipFactory.create_batch(2, account=self.object) group_1 = memberships[0].group group_2 = memberships[1].group remove_from_group_url_1 = self.get_api_remove_from_group_url(group_1.name) remove_from_group_url_2 = self.get_api_remove_from_group_url(group_2.name) - self.anvil_response_mock.add( - responses.DELETE, remove_from_group_url_1, status=204 - ) - self.anvil_response_mock.add( - responses.DELETE, remove_from_group_url_2, status=204 - ) + self.anvil_response_mock.add(responses.DELETE, remove_from_group_url_1, status=204) + self.anvil_response_mock.add(responses.DELETE, remove_from_group_url_2, status=204) self.object.anvil_remove_from_groups() # The membership was removed. self.assertEqual(models.GroupAccountMembership.objects.count(), 2) @@ -262,9 +222,7 @@ def test_anvil_remove_from_groups_api_failure(self): group_2 = self.object.groupaccountmembership_set.all()[1].group remove_from_group_url_1 = self.get_api_remove_from_group_url(group_1.name) remove_from_group_url_2 = self.get_api_remove_from_group_url(group_2.name) - self.anvil_response_mock.add( - responses.DELETE, remove_from_group_url_1, status=204 - ) + self.anvil_response_mock.add(responses.DELETE, remove_from_group_url_1, status=204) self.anvil_response_mock.add( responses.DELETE, remove_from_group_url_2, @@ -288,9 +246,7 @@ def test_deactivate_one_group(self): membership = factories.GroupAccountMembershipFactory.create(account=self.object) group = membership.group remove_from_group_url = self.get_api_remove_from_group_url(group.name) - self.anvil_response_mock.add( - responses.DELETE, remove_from_group_url, status=204 - ) + self.anvil_response_mock.add(responses.DELETE, remove_from_group_url, status=204) self.object.deactivate() self.object.refresh_from_db() self.assertEqual(self.object.status, self.object.INACTIVE_STATUS) @@ -299,19 +255,13 @@ def test_deactivate_one_group(self): def test_deactivate_two_groups(self): """deactivate succeeds if the account is in two groups.""" - memberships = factories.GroupAccountMembershipFactory.create_batch( - 2, account=self.object - ) + memberships = factories.GroupAccountMembershipFactory.create_batch(2, account=self.object) group_1 = memberships[0].group group_2 = memberships[1].group remove_from_group_url_1 = self.get_api_remove_from_group_url(group_1.name) remove_from_group_url_2 = self.get_api_remove_from_group_url(group_2.name) - self.anvil_response_mock.add( - responses.DELETE, remove_from_group_url_1, status=204 - ) - self.anvil_response_mock.add( - responses.DELETE, remove_from_group_url_2, status=204 - ) + self.anvil_response_mock.add(responses.DELETE, remove_from_group_url_1, status=204) + self.anvil_response_mock.add(responses.DELETE, remove_from_group_url_2, status=204) self.object.deactivate() self.object.refresh_from_db() self.assertEqual(self.object.status, self.object.INACTIVE_STATUS) @@ -345,9 +295,7 @@ def test_reactivate_two_groups(self): """reactivate succeeds if the account is in two groups.""" self.object.status = self.object.INACTIVE_STATUS self.object.save() - memberships = factories.GroupAccountMembershipFactory.create_batch( - 2, account=self.object - ) + memberships = factories.GroupAccountMembershipFactory.create_batch(2, account=self.object) group_1 = memberships[0].group group_2 = memberships[1].group add_to_group_url_1 = self.get_api_add_to_group_url(group_1.name) @@ -365,20 +313,12 @@ class ManagedGroupAnVILAPIMockTest(AnVILAPIMockTestMixin, TestCase): def setUp(self, *args, **kwargs): super().setUp() self.object = factories.ManagedGroupFactory() - self.api_url_exists = ( - self.api_client.sam_entry_point + "/api/groups/v1/" + self.object.name - ) - self.api_url_create = ( - self.api_client.sam_entry_point + "/api/groups/v1/" + self.object.name - ) - self.api_url_delete = ( - self.api_client.sam_entry_point + "/api/groups/v1/" + self.object.name - ) + self.api_url_exists = self.api_client.sam_entry_point + "/api/groups/v1/" + self.object.name + self.api_url_create = self.api_client.sam_entry_point + "/api/groups/v1/" + self.object.name + self.api_url_delete = self.api_client.sam_entry_point + "/api/groups/v1/" + self.object.name def test_anvil_exists_does_exist(self): - self.anvil_response_mock.add( - responses.GET, self.api_url_exists, status=200, json=self.object.email - ) + self.anvil_response_mock.add(responses.GET, self.api_url_exists, status=200, json=self.object.email) self.assertIs(self.object.anvil_exists(), True) def test_anvil_exists_does_not_exist(self): @@ -500,15 +440,11 @@ def get_api_url(self): def get_api_url_members(self, group_name): """Return the API url being called by the method.""" - return ( - self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/member" - ) + return self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/member" def get_api_url_admins(self, group_name): """Return the API url being called by the method.""" - return ( - self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/admin" - ) + return self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/admin" def test_anvil_import_admin_on_anvil(self): group_name = "test-group" @@ -618,9 +554,7 @@ def test_anvil_import_member_on_anvil_uppercase(self): response=[ api_factories.GroupDetailsFactory(), api_factories.GroupDetailsFactory(), - api_factories.GroupDetailsMemberFactory( - groupName=group_name, role="Member" - ), + api_factories.GroupDetailsMemberFactory(groupName=group_name, role="Member"), ] ).response, ) @@ -833,17 +767,13 @@ def test_imports_group_and_account_membership(self): responses.GET, self.get_api_url_members(group_name), status=200, - json=api_factories.GetGroupMembershipResponseFactory( - response=[account.email] - ).response, + json=api_factories.GetGroupMembershipResponseFactory(response=[account.email]).response, ) self.anvil_response_mock.add( responses.GET, self.get_api_url_admins(group_name), status=200, - json=api_factories.GetGroupMembershipAdminResponseFactory( - response=[child_group.email] - ).response, + json=api_factories.GetGroupMembershipAdminResponseFactory(response=[child_group.email]).response, ) group = models.ManagedGroup.anvil_import(group_name) self.assertEqual(models.GroupGroupMembership.objects.count(), 1) @@ -865,15 +795,11 @@ def get_api_url(self): def get_api_url_members(self, group_name): """Return the API url being called by the method.""" - return ( - self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/member" - ) + return self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/member" def get_api_url_admins(self, group_name): """Return the API url being called by the method.""" - return ( - self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/admin" - ) + return self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/admin" def test_not_managed_by_app(self): group = factories.ManagedGroupFactory.create(is_managed_by_app=False) @@ -918,9 +844,7 @@ def test_group_admin_exists_in_app(self): responses.GET, self.get_api_url_admins(group.name), status=200, - json=api_factories.GetGroupMembershipAdminResponseFactory( - response=[child_group.email] - ).response, + json=api_factories.GetGroupMembershipAdminResponseFactory(response=[child_group.email]).response, ) group.anvil_import_membership() self.assertEqual(models.GroupGroupMembership.objects.count(), 1) @@ -944,9 +868,7 @@ def test_group_admin_exists_in_app_case_insensitive(self): responses.GET, self.get_api_url_admins(group.name), status=200, - json=api_factories.GetGroupMembershipAdminResponseFactory( - response=["fOo@bAR.com"] - ).response, + json=api_factories.GetGroupMembershipAdminResponseFactory(response=["fOo@bAR.com"]).response, ) group.anvil_import_membership() self.assertEqual(models.GroupGroupMembership.objects.count(), 1) @@ -964,9 +886,7 @@ def test_group_member_exists_in_app(self): responses.GET, self.get_api_url_members(group.name), status=200, - json=api_factories.GetGroupMembershipResponseFactory( - response=[child_group.email] - ).response, + json=api_factories.GetGroupMembershipResponseFactory(response=[child_group.email]).response, ) self.anvil_response_mock.add( responses.GET, @@ -990,9 +910,7 @@ def test_group_member_exists_in_app_case_insensitive(self): responses.GET, self.get_api_url_members(group.name), status=200, - json=api_factories.GetGroupMembershipResponseFactory( - response=["fOo@BaR.com"] - ).response, + json=api_factories.GetGroupMembershipResponseFactory(response=["fOo@BaR.com"]).response, ) self.anvil_response_mock.add( responses.GET, @@ -1021,9 +939,7 @@ def test_group_admin_not_in_app(self): responses.GET, self.get_api_url_admins(group.name), status=200, - json=api_factories.GetGroupMembershipAdminResponseFactory( - response=["test@example.com"] - ).response, + json=api_factories.GetGroupMembershipAdminResponseFactory(response=["test@example.com"]).response, ) group.anvil_import_membership() self.assertEqual(models.GroupGroupMembership.objects.count(), 0) @@ -1036,9 +952,7 @@ def test_group_member_not_in_app(self): responses.GET, self.get_api_url_members(group.name), status=200, - json=api_factories.GetGroupMembershipResponseFactory( - response=["test@example.com"] - ).response, + json=api_factories.GetGroupMembershipResponseFactory(response=["test@example.com"]).response, ) self.anvil_response_mock.add( responses.GET, @@ -1058,17 +972,13 @@ def test_same_group_both_admin_and_member(self): responses.GET, self.get_api_url_members(group.name), status=200, - json=api_factories.GetGroupMembershipResponseFactory( - response=[child_group.email] - ).response, + json=api_factories.GetGroupMembershipResponseFactory(response=[child_group.email]).response, ) self.anvil_response_mock.add( responses.GET, self.get_api_url_admins(group.name), status=200, - json=api_factories.GetGroupMembershipAdminResponseFactory( - response=[child_group.email] - ).response, + json=api_factories.GetGroupMembershipAdminResponseFactory(response=[child_group.email]).response, ) group.anvil_import_membership() self.assertEqual(models.GroupGroupMembership.objects.count(), 1) @@ -1086,27 +996,19 @@ def test_one_member_one_admin(self): responses.GET, self.get_api_url_members(group.name), status=200, - json=api_factories.GetGroupMembershipResponseFactory( - response=[child_group_1.email] - ).response, + json=api_factories.GetGroupMembershipResponseFactory(response=[child_group_1.email]).response, ) self.anvil_response_mock.add( responses.GET, self.get_api_url_admins(group.name), status=200, - json=api_factories.GetGroupMembershipAdminResponseFactory( - response=[child_group_2.email] - ).response, + json=api_factories.GetGroupMembershipAdminResponseFactory(response=[child_group_2.email]).response, ) group.anvil_import_membership() self.assertEqual(models.GroupGroupMembership.objects.count(), 2) - membership = models.GroupGroupMembership.objects.get( - parent_group=group, child_group=child_group_1 - ) + membership = models.GroupGroupMembership.objects.get(parent_group=group, child_group=child_group_1) self.assertEqual(membership.role, membership.MEMBER) - membership = models.GroupGroupMembership.objects.get( - parent_group=group, child_group=child_group_2 - ) + membership = models.GroupGroupMembership.objects.get(parent_group=group, child_group=child_group_2) self.assertEqual(membership.role, membership.ADMIN) def test_two_group_admins(self): @@ -1131,13 +1033,9 @@ def test_two_group_admins(self): ) group.anvil_import_membership() self.assertEqual(models.GroupGroupMembership.objects.count(), 2) - membership = models.GroupGroupMembership.objects.get( - parent_group=group, child_group=child_group_1 - ) + membership = models.GroupGroupMembership.objects.get(parent_group=group, child_group=child_group_1) self.assertEqual(membership.role, membership.ADMIN) - membership = models.GroupGroupMembership.objects.get( - parent_group=group, child_group=child_group_2 - ) + membership = models.GroupGroupMembership.objects.get(parent_group=group, child_group=child_group_2) self.assertEqual(membership.role, membership.ADMIN) def test_two_group_members(self): @@ -1162,13 +1060,9 @@ def test_two_group_members(self): ) group.anvil_import_membership() self.assertEqual(models.GroupGroupMembership.objects.count(), 2) - membership = models.GroupGroupMembership.objects.get( - parent_group=group, child_group=child_group_1 - ) + membership = models.GroupGroupMembership.objects.get(parent_group=group, child_group=child_group_1) self.assertEqual(membership.role, membership.MEMBER) - membership = models.GroupGroupMembership.objects.get( - parent_group=group, child_group=child_group_2 - ) + membership = models.GroupGroupMembership.objects.get(parent_group=group, child_group=child_group_2) self.assertEqual(membership.role, membership.MEMBER) def test_account_admin_exists_in_app(self): @@ -1186,9 +1080,7 @@ def test_account_admin_exists_in_app(self): responses.GET, self.get_api_url_admins(group.name), status=200, - json=api_factories.GetGroupMembershipAdminResponseFactory( - response=[account.email] - ).response, + json=api_factories.GetGroupMembershipAdminResponseFactory(response=[account.email]).response, ) group.anvil_import_membership() self.assertEqual(models.GroupAccountMembership.objects.count(), 1) @@ -1212,9 +1104,7 @@ def test_account_admin_exists_in_app_case_insensitive(self): responses.GET, self.get_api_url_admins(group.name), status=200, - json=api_factories.GetGroupMembershipAdminResponseFactory( - response=["fOo@bAR.com"] - ).response, + json=api_factories.GetGroupMembershipAdminResponseFactory(response=["fOo@bAR.com"]).response, ) group.anvil_import_membership() self.assertEqual(models.GroupAccountMembership.objects.count(), 1) @@ -1232,9 +1122,7 @@ def test_account_member_exists_in_app(self): responses.GET, self.get_api_url_members(group.name), status=200, - json=api_factories.GetGroupMembershipResponseFactory( - response=[account.email] - ).response, + json=api_factories.GetGroupMembershipResponseFactory(response=[account.email]).response, ) self.anvil_response_mock.add( responses.GET, @@ -1258,9 +1146,7 @@ def test_gaccount_member_exists_in_app_case_insensitive(self): responses.GET, self.get_api_url_members(group.name), status=200, - json=api_factories.GetGroupMembershipResponseFactory( - response=["fOo@BaR.com"] - ).response, + json=api_factories.GetGroupMembershipResponseFactory(response=["fOo@BaR.com"]).response, ) self.anvil_response_mock.add( responses.GET, @@ -1289,9 +1175,7 @@ def test_account_admin_not_in_app(self): responses.GET, self.get_api_url_admins(group.name), status=200, - json=api_factories.GetGroupMembershipAdminResponseFactory( - response=["test@example.com"] - ).response, + json=api_factories.GetGroupMembershipAdminResponseFactory(response=["test@example.com"]).response, ) group.anvil_import_membership() self.assertEqual(models.GroupAccountMembership.objects.count(), 0) @@ -1304,9 +1188,7 @@ def test_account_member_not_in_app(self): responses.GET, self.get_api_url_members(group.name), status=200, - json=api_factories.GetGroupMembershipResponseFactory( - response=["test@example.com"] - ).response, + json=api_factories.GetGroupMembershipResponseFactory(response=["test@example.com"]).response, ) self.anvil_response_mock.add( responses.GET, @@ -1326,17 +1208,13 @@ def test_same_account_both_admin_and_member(self): responses.GET, self.get_api_url_members(group.name), status=200, - json=api_factories.GetGroupMembershipResponseFactory( - response=[account.email] - ).response, + json=api_factories.GetGroupMembershipResponseFactory(response=[account.email]).response, ) self.anvil_response_mock.add( responses.GET, self.get_api_url_admins(group.name), status=200, - json=api_factories.GetGroupMembershipAdminResponseFactory( - response=[account.email] - ).response, + json=api_factories.GetGroupMembershipAdminResponseFactory(response=[account.email]).response, ) group.anvil_import_membership() self.assertEqual(models.GroupAccountMembership.objects.count(), 1) @@ -1354,27 +1232,19 @@ def test_account_one_member_one_admin(self): responses.GET, self.get_api_url_members(group.name), status=200, - json=api_factories.GetGroupMembershipResponseFactory( - response=[account_1.email] - ).response, + json=api_factories.GetGroupMembershipResponseFactory(response=[account_1.email]).response, ) self.anvil_response_mock.add( responses.GET, self.get_api_url_admins(group.name), status=200, - json=api_factories.GetGroupMembershipAdminResponseFactory( - response=[account_2.email] - ).response, + json=api_factories.GetGroupMembershipAdminResponseFactory(response=[account_2.email]).response, ) group.anvil_import_membership() self.assertEqual(models.GroupAccountMembership.objects.count(), 2) - membership = models.GroupAccountMembership.objects.get( - group=group, account=account_1 - ) + membership = models.GroupAccountMembership.objects.get(group=group, account=account_1) self.assertEqual(membership.role, membership.MEMBER) - membership = models.GroupAccountMembership.objects.get( - group=group, account=account_2 - ) + membership = models.GroupAccountMembership.objects.get(group=group, account=account_2) self.assertEqual(membership.role, membership.ADMIN) def test_two_account_admins(self): @@ -1399,13 +1269,9 @@ def test_two_account_admins(self): ) group.anvil_import_membership() self.assertEqual(models.GroupAccountMembership.objects.count(), 2) - membership = models.GroupAccountMembership.objects.get( - group=group, account=account_1 - ) + membership = models.GroupAccountMembership.objects.get(group=group, account=account_1) self.assertEqual(membership.role, membership.ADMIN) - membership = models.GroupAccountMembership.objects.get( - group=group, account=account_2 - ) + membership = models.GroupAccountMembership.objects.get(group=group, account=account_2) self.assertEqual(membership.role, membership.ADMIN) def test_two_account_members(self): @@ -1418,9 +1284,7 @@ def test_two_account_members(self): responses.GET, self.get_api_url_members(group.name), status=200, - json=api_factories.GetGroupMembershipResponseFactory( - response=[account_1.email, account_2.email] - ).response, + json=api_factories.GetGroupMembershipResponseFactory(response=[account_1.email, account_2.email]).response, ) self.anvil_response_mock.add( responses.GET, @@ -1430,13 +1294,9 @@ def test_two_account_members(self): ) group.anvil_import_membership() self.assertEqual(models.GroupAccountMembership.objects.count(), 2) - membership = models.GroupAccountMembership.objects.get( - group=group, account=account_1 - ) + membership = models.GroupAccountMembership.objects.get(group=group, account=account_1) self.assertEqual(membership.role, membership.MEMBER) - membership = models.GroupAccountMembership.objects.get( - group=group, account=account_2 - ) + membership = models.GroupAccountMembership.objects.get(group=group, account=account_2) self.assertEqual(membership.role, membership.MEMBER) def test_one_account_one_group(self): @@ -1449,9 +1309,7 @@ def test_one_account_one_group(self): responses.GET, self.get_api_url_members(group.name), status=200, - json=api_factories.GetGroupMembershipResponseFactory( - response=[child_group.email, account.email] - ).response, + json=api_factories.GetGroupMembershipResponseFactory(response=[child_group.email, account.email]).response, ) self.anvil_response_mock.add( responses.GET, @@ -1461,14 +1319,10 @@ def test_one_account_one_group(self): ) group.anvil_import_membership() self.assertEqual(models.GroupAccountMembership.objects.count(), 1) - membership = models.GroupAccountMembership.objects.get( - group=group, account=account - ) + membership = models.GroupAccountMembership.objects.get(group=group, account=account) self.assertEqual(membership.role, membership.MEMBER) self.assertEqual(models.GroupGroupMembership.objects.count(), 1) - membership = models.GroupGroupMembership.objects.get( - parent_group=group, child_group=child_group - ) + membership = models.GroupGroupMembership.objects.get(parent_group=group, child_group=child_group) self.assertEqual(membership.role, membership.MEMBER) def test_api_error_group_member_call(self): @@ -1507,9 +1361,7 @@ def test_api_error_group_admin_call(self): responses.GET, self.get_api_url_members(group.name), status=200, - json=api_factories.ErrorResponseFactory( - response=[child_group.email, account.email] - ).response, + json=api_factories.ErrorResponseFactory(response=[child_group.email, account.email]).response, ) self.anvil_response_mock.add( responses.GET, @@ -2196,9 +2048,7 @@ def test_error_authorization_domain_exists_in_app_but_not_on_anvil(self): "namespace": billing_project.name, "name": "test-workspace", "attributes": {}, - "authorizationDomain": [ - {"membersGroupName": new_auth_domain.name} - ], + "authorizationDomain": [{"membersGroupName": new_auth_domain.name}], "copyFilesWithPrefix": "notebooks", } ) @@ -2247,25 +2097,13 @@ class WorkspaceAnVILImportAnVILAPIMockTest(AnVILAPIMockTestMixin, TestCase): def setUp(self): super().setUp() self.api_json_response_acl = {"acl": {}} - self.add_api_json_response_acl( - self.service_account_email, "OWNER", can_compute=True, can_share=True - ) + self.add_api_json_response_acl(self.service_account_email, "OWNER", can_compute=True, can_share=True) def get_billing_project_api_url(self, billing_project_name): - return ( - self.api_client.rawls_entry_point - + "/api/billing/v2/" - + billing_project_name - ) + return self.api_client.rawls_entry_point + "/api/billing/v2/" + billing_project_name def get_api_url(self, billing_project_name, workspace_name): - 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, @@ -2298,9 +2136,7 @@ def get_api_url_acl(self, billing_project_name, workspace_name): + "/acl" ) - def add_api_json_response_acl( - self, email, access, can_compute=False, can_share=False - ): + def add_api_json_response_acl(self, email, access, can_compute=False, can_share=False): """Add a record to the API response for the workspace ACL call.""" self.api_json_response_acl["acl"][email] = { "accessLevel": access, @@ -2385,9 +2221,7 @@ def test_anvil_import_locked(self): responses.GET, self.get_api_url(billing_project.name, workspace_name), status=200, # successful response code. - json=self.get_api_json_response( - billing_project.name, workspace_name, is_locked=True - ), + json=self.get_api_json_response(billing_project.name, workspace_name, is_locked=True), ) # Response for ACL query. self.anvil_response_mock.add( @@ -2502,9 +2336,7 @@ def test_anvil_import_not_owners_of_workspace(self): responses.GET, self.get_api_url(billing_project_name, workspace_name), status=200, # successful response code. - json=self.get_api_json_response( - billing_project_name, workspace_name, access="READER" - ), + json=self.get_api_json_response(billing_project_name, workspace_name, access="READER"), ) with self.assertRaises(exceptions.AnVILNotWorkspaceOwnerError): models.Workspace.anvil_import( @@ -2520,18 +2352,14 @@ def test_anvil_import_not_owners_of_workspace(self): def test_anvil_import_not_owners_of_workspace_billing_project_exists(self): """Cannot import a workspace if we are not owners of the workspace but the billing project exists.""" - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") workspace_name = "test-workspace" # No billing project API calls. self.anvil_response_mock.add( responses.GET, self.get_api_url(billing_project.name, workspace_name), status=200, # successful response code. - json=self.get_api_json_response( - billing_project.name, workspace_name, access="READER" - ), + json=self.get_api_json_response(billing_project.name, workspace_name, access="READER"), ) with self.assertRaises(exceptions.AnVILNotWorkspaceOwnerError): models.Workspace.anvil_import( @@ -2574,9 +2402,7 @@ def test_anvil_import_no_access_to_anvil_workspace(self): def test_anvil_import_no_access_to_anvil_workspace_billing_project_exist(self): """A workspace cannot be imported from AnVIL if we do not have access but the BillingProject is in Django.""" - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") workspace_name = "test-workspace" # No API call for billing projects. self.anvil_response_mock.add( @@ -2737,12 +2563,8 @@ def test_anvil_import_invalid_workspace_name(self): def test_anvil_import_different_billing_project_same_workspace_name(self): """Can import a workspace in a different billing project with the same name as another workspace.""" workspace_name = "test-workspace" - other_billing_project = factories.BillingProjectFactory.create( - name="billing-project-1" - ) - factories.WorkspaceFactory.create( - billing_project=other_billing_project, name=workspace_name - ) + other_billing_project = factories.BillingProjectFactory.create(name="billing-project-1") + factories.WorkspaceFactory.create(billing_project=other_billing_project, name=workspace_name) billing_project_name = "billing-project-2" self.anvil_response_mock.add( responses.GET, @@ -2780,9 +2602,7 @@ def test_anvil_import_same_billing_project_different_workspace_name(self): """Can import a workspace in the same billing project with with a different name as another workspace.""" workspace_name = "test-workspace-2" billing_project = factories.BillingProjectFactory.create() - factories.WorkspaceFactory.create( - billing_project=billing_project, name="test-workspace-1" - ) + factories.WorkspaceFactory.create(billing_project=billing_project, name="test-workspace-1") # No billing project API calls. self.anvil_response_mock.add( responses.GET, @@ -2811,9 +2631,7 @@ def test_anvil_import_same_billing_project_different_workspace_name(self): def test_anvil_import_one_auth_group_member_does_not_exist_in_django(self): """Imports an auth group that the app is a member of for a workspace.""" - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") workspace_name = "test-workspace" # Response for workspace query. workspace_url = self.get_api_url(billing_project.name, workspace_name) @@ -2821,9 +2639,7 @@ def test_anvil_import_one_auth_group_member_does_not_exist_in_django(self): responses.GET, workspace_url, status=200, # successful response code. - json=self.get_api_json_response( - billing_project.name, workspace_name, auth_domains=["auth-group"] - ), + json=self.get_api_json_response(billing_project.name, workspace_name, auth_domains=["auth-group"]), ) # Response for group query. group_url = self.api_client.sam_entry_point + "/api/groups/v1" @@ -2868,9 +2684,7 @@ def test_anvil_import_one_auth_group_member_does_not_exist_in_django(self): def test_anvil_import_one_auth_group_exists_in_django(self): """Imports a workspace with an auth group that already exists in the app with app as member.""" - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") workspace_name = "test-workspace" group = factories.ManagedGroupFactory.create(name="auth-group") # Response for workspace query. @@ -2879,9 +2693,7 @@ def test_anvil_import_one_auth_group_exists_in_django(self): responses.GET, workspace_url, status=200, # successful response code. - json=self.get_api_json_response( - billing_project.name, workspace_name, auth_domains=["auth-group"] - ), + json=self.get_api_json_response(billing_project.name, workspace_name, auth_domains=["auth-group"]), ) # Response for ACL query. self.anvil_response_mock.add( @@ -2910,9 +2722,7 @@ def test_anvil_import_one_auth_group_exists_in_django(self): def test_anvil_import_one_auth_group_admin_does_not_exist_in_django(self): """Imports a workspace with an auth group that the app is a member.""" - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") workspace_name = "test-workspace" # Response for workspace query. workspace_url = self.get_api_url(billing_project.name, workspace_name) @@ -2920,9 +2730,7 @@ def test_anvil_import_one_auth_group_admin_does_not_exist_in_django(self): responses.GET, workspace_url, status=200, # successful response code. - json=self.get_api_json_response( - billing_project.name, workspace_name, auth_domains=["auth-group"] - ), + json=self.get_api_json_response(billing_project.name, workspace_name, auth_domains=["auth-group"]), ) # Response for ACL query. self.anvil_response_mock.add( @@ -2980,9 +2788,7 @@ def test_anvil_import_one_auth_group_admin_does_not_exist_in_django(self): def test_anvil_import_two_auth_groups(self): """Imports two auth groups for a workspace.""" - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") workspace_name = "test-workspace" # Response for ACL query. self.anvil_response_mock.add( @@ -3063,18 +2869,14 @@ def test_api_internal_error_group_call(self): workspace_name = "test-workspace" # Response for billing project query. billing_project_url = self.get_billing_project_api_url(billing_project_name) - self.anvil_response_mock.add( - responses.GET, billing_project_url, status=200 # successful response code. - ) + self.anvil_response_mock.add(responses.GET, billing_project_url, status=200) # successful response code. # Response for workspace query. workspace_url = self.get_api_url(billing_project_name, workspace_name) self.anvil_response_mock.add( responses.GET, workspace_url, status=200, # successful response code. - json=self.get_api_json_response( - billing_project_name, workspace_name, auth_domains=["auth-group"] - ), + json=self.get_api_json_response(billing_project_name, workspace_name, auth_domains=["auth-group"]), ) # Response for group query. group_url = self.api_client.sam_entry_point + "/api/groups/v1" @@ -3114,9 +2916,7 @@ def test_imports_group_sharing_one_group_in_app_reader(self): json=self.get_api_json_response(billing_project.name, workspace_name), ) # Response for ACL query. - self.add_api_json_response_acl( - group.email, "READER", can_compute=False, can_share=False - ) + self.add_api_json_response_acl(group.email, "READER", can_compute=False, can_share=False) self.anvil_response_mock.add( responses.GET, self.get_api_url_acl(billing_project.name, workspace_name), @@ -3148,9 +2948,7 @@ def test_imports_group_sharing_one_group_in_app_writer(self): json=self.get_api_json_response(billing_project.name, workspace_name), ) # Response for ACL query. - self.add_api_json_response_acl( - group.email, "WRITER", can_compute=False, can_share=False - ) + self.add_api_json_response_acl(group.email, "WRITER", can_compute=False, can_share=False) self.anvil_response_mock.add( responses.GET, self.get_api_url_acl(billing_project.name, workspace_name), @@ -3182,9 +2980,7 @@ def test_imports_group_sharing_one_group_in_app_owner(self): json=self.get_api_json_response(billing_project.name, workspace_name), ) # Response for ACL query. - self.add_api_json_response_acl( - group.email, "OWNER", can_compute=False, can_share=False - ) + self.add_api_json_response_acl(group.email, "OWNER", can_compute=False, can_share=False) self.anvil_response_mock.add( responses.GET, self.get_api_url_acl(billing_project.name, workspace_name), @@ -3216,9 +3012,7 @@ def test_imports_group_sharing_one_group_in_app_case_insensitive(self): json=self.get_api_json_response(billing_project.name, workspace_name), ) # Response for ACL query. - self.add_api_json_response_acl( - group.email, "reader", can_compute=False, can_share=False - ) + self.add_api_json_response_acl(group.email, "reader", can_compute=False, can_share=False) self.anvil_response_mock.add( responses.GET, self.get_api_url_acl(billing_project.name, workspace_name), @@ -3251,12 +3045,8 @@ def test_imports_group_sharing_two_groups_in_app(self): json=self.get_api_json_response(billing_project.name, workspace_name), ) # Response for ACL query. - self.add_api_json_response_acl( - group_1.email, "READER", can_compute=False, can_share=False - ) - self.add_api_json_response_acl( - group_2.email, "WRITER", can_compute=False, can_share=False - ) + self.add_api_json_response_acl(group_1.email, "READER", can_compute=False, can_share=False) + self.add_api_json_response_acl(group_2.email, "WRITER", can_compute=False, can_share=False) self.anvil_response_mock.add( responses.GET, self.get_api_url_acl(billing_project.name, workspace_name), @@ -3292,9 +3082,7 @@ def test_imports_group_sharing_group_not_in_app(self): json=self.get_api_json_response(billing_project.name, workspace_name), ) # Response for ACL query. - self.add_api_json_response_acl( - "foobar@firecloud.org", "READER", can_compute=False, can_share=False - ) + self.add_api_json_response_acl("foobar@firecloud.org", "READER", can_compute=False, can_share=False) self.anvil_response_mock.add( responses.GET, self.get_api_url_acl(billing_project.name, workspace_name), @@ -3320,9 +3108,7 @@ def test_imports_group_sharing_shared_with_user(self): json=self.get_api_json_response(billing_project.name, workspace_name), ) # Response for ACL query. - self.add_api_json_response_acl( - "test_email@example.com", "READER", can_compute=False, can_share=False - ) + self.add_api_json_response_acl("test_email@example.com", "READER", can_compute=False, can_share=False) self.anvil_response_mock.add( responses.GET, self.get_api_url_acl(billing_project.name, workspace_name), @@ -3344,9 +3130,7 @@ def test_acl_api_error(self): factories.ManagedGroupFactory.create() # Response for billing project query. billing_project_url = self.get_billing_project_api_url(billing_project_name) - self.anvil_response_mock.add( - responses.GET, billing_project_url, status=200 # successful response code. - ) + self.anvil_response_mock.add(responses.GET, billing_project_url, status=200) # successful response code. # Response for workspace query. workspace_url = self.get_api_url(billing_project_name, workspace_name) self.anvil_response_mock.add( @@ -3387,12 +3171,10 @@ def setUp(self, *args, **kwargs): role=models.GroupGroupMembership.MEMBER, ) self.api_url_create = ( - self.api_client.sam_entry_point - + "/api/groups/v1/parent-group/member/child-group@firecloud.org" + self.api_client.sam_entry_point + "/api/groups/v1/parent-group/member/child-group@firecloud.org" ) self.api_url_delete = ( - self.api_client.sam_entry_point - + "/api/groups/v1/parent-group/member/child-group@firecloud.org" + self.api_client.sam_entry_point + "/api/groups/v1/parent-group/member/child-group@firecloud.org" ) def test_anvil_create_successful(self): @@ -3406,10 +3188,7 @@ def test_anvil_create_successful_different_email(self): child_group__email="foo@bar.com", parent_group=self.parent_group, ) - api_url_create = ( - self.api_client.sam_entry_point - + "/api/groups/v1/parent-group/member/foo@bar.com" - ) + api_url_create = self.api_client.sam_entry_point + "/api/groups/v1/parent-group/member/foo@bar.com" self.anvil_response_mock.add(responses.PUT, api_url_create, status=204) other_child_membership.anvil_create() @@ -3464,10 +3243,7 @@ def test_anvil_delete_successful_different_email(self): child_group__email="foo@bar.com", parent_group=self.parent_group, ) - api_url_delete = ( - self.api_client.sam_entry_point - + "/api/groups/v1/parent-group/member/foo@bar.com" - ) + api_url_delete = self.api_client.sam_entry_point + "/api/groups/v1/parent-group/member/foo@bar.com" self.anvil_response_mock.add(responses.DELETE, api_url_delete, status=204) other_child_membership.anvil_delete() @@ -3521,12 +3297,10 @@ def setUp(self, *args, **kwargs): group=group, account=account, role=models.GroupAccountMembership.MEMBER ) self.api_url_create = ( - self.api_client.sam_entry_point - + "/api/groups/v1/test-group/member/test-account@example.com" + self.api_client.sam_entry_point + "/api/groups/v1/test-group/member/test-account@example.com" ) self.api_url_delete = ( - self.api_client.sam_entry_point - + "/api/groups/v1/test-group/member/test-account@example.com" + self.api_client.sam_entry_point + "/api/groups/v1/test-group/member/test-account@example.com" ) def test_anvil_create_successful(self): @@ -3625,12 +3399,8 @@ def test_anvil_delete_unsuccessful_other(self): class WorkspaceGroupSharingAnVILAPIMockTest(AnVILAPIMockTestMixin, TestCase): def setUp(self, *args, **kwargs): super().setUp() - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) - workspace = factories.WorkspaceFactory.create( - billing_project=billing_project, name="test-workspace" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") + workspace = factories.WorkspaceFactory.create(billing_project=billing_project, name="test-workspace") group = factories.ManagedGroupFactory.create(name="test-group") self.object = factories.WorkspaceGroupSharingFactory( workspace=workspace, group=group, access=models.WorkspaceGroupSharing.READER @@ -3657,9 +3427,7 @@ def setUp(self, *args, **kwargs): } ] - def get_api_json_response( - self, invites_sent=[], users_not_found=[], users_updated=[] - ): + def get_api_json_response(self, invites_sent=[], users_not_found=[], users_updated=[]): return { "invitesSent": invites_sent, "usersNotFound": users_not_found, diff --git a/anvil_consortium_manager/tests/test_views.py b/anvil_consortium_manager/tests/test_views.py index 99f1db37..091ad4b8 100644 --- a/anvil_consortium_manager/tests/test_views.py +++ b/anvil_consortium_manager/tests/test_views.py @@ -32,10 +32,7 @@ from .test_app.adapters import TestWorkspaceAdapter from .test_app.factories import TestWorkspaceDataFactory from .test_app.filters import TestAccountListFilter -from .utils import ( # Redefined to work with Django < 4.2 and Django=4.2. - AnVILAPIMockTestMixin, - TestCase, -) +from .utils import AnVILAPIMockTestMixin, TestCase # Redefined to work with Django < 4.2 and Django=4.2. fake = Faker() @@ -49,9 +46,7 @@ def setUp(self): # Create a user with view permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -66,9 +61,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.""" @@ -78,13 +71,9 @@ def test_status_code_with_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -93,9 +82,7 @@ def test_access_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): @@ -158,28 +145,20 @@ def setUp(self): # Create a user with view permission. self.view_user = User.objects.create_user(username="test_view", password="view") self.view_user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) # Create a user with view permission. self.edit_user = User.objects.create_user(username="test_edit", password="test") self.edit_user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ), - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ), + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME), + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME), ) def test_view_navbar(self): """Links to edit required do not appear in the index when user only has view permission.""" self.client.force_login(self.view_user) # Test with the BillingProjectList page for now, since we're testing the navbar only. - response = self.client.get( - reverse("anvil_consortium_manager:billing_projects:list") - ) + response = self.client.get(reverse("anvil_consortium_manager:billing_projects:list")) for url in self.edit_urls: self.assertNotContains(response, url) for url in self.view_urls: @@ -189,9 +168,7 @@ def test_edit_navbar(self): """Links to edit required do not appear in the index when user only has view permission.""" self.client.force_login(self.edit_user) # Test with the BillingProjectList page for now, since we're testing the navbar only. - response = self.client.get( - reverse("anvil_consortium_manager:billing_projects:list") - ) + response = self.client.get(reverse("anvil_consortium_manager:billing_projects:list")) for url in self.edit_urls: self.assertContains(response, url) for url in self.view_urls: @@ -225,9 +202,7 @@ def setUp(self): # Create a user with view permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_json_me_data(self): @@ -260,29 +235,21 @@ 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.""" url_me = self.api_client.firecloud_entry_point + "/me?userDetailsOnly=true" - self.anvil_response_mock.add( - responses.GET, url_me, status=200, json=self.get_json_me_data() - ) + self.anvil_response_mock.add(responses.GET, url_me, status=200, json=self.get_json_me_data()) url_status = self.api_client.firecloud_entry_point + "/status" - self.anvil_response_mock.add( - responses.GET, url_status, status=200, json=self.get_json_status_data() - ) + self.anvil_response_mock.add(responses.GET, url_status, status=200, json=self.get_json_status_data()) self.client.force_login(self.user) response = self.client.get(self.get_url()) 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()) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -290,13 +257,9 @@ def test_access_without_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -306,13 +269,9 @@ def test_access_with_limited_view_permission(self): def test_context_data_anvil_status_ok(self): """Context data contains anvil_status.""" url_me = self.api_client.firecloud_entry_point + "/me?userDetailsOnly=true" - self.anvil_response_mock.add( - responses.GET, url_me, status=200, json=self.get_json_me_data() - ) + self.anvil_response_mock.add(responses.GET, url_me, status=200, json=self.get_json_me_data()) url_status = self.api_client.firecloud_entry_point + "/status" - self.anvil_response_mock.add( - responses.GET, url_status, status=200, json=self.get_json_status_data() - ) + self.anvil_response_mock.add(responses.GET, url_status, status=200, json=self.get_json_status_data()) self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertEqual(response.status_code, 200) @@ -323,9 +282,7 @@ def test_context_data_anvil_status_ok(self): def test_context_data_anvil_status_not_ok(self): """Context data contains anvil_status.""" url_me = self.api_client.firecloud_entry_point + "/me?userDetailsOnly=true" - self.anvil_response_mock.add( - responses.GET, url_me, status=200, json=self.get_json_me_data() - ) + self.anvil_response_mock.add(responses.GET, url_me, status=200, json=self.get_json_me_data()) url_status = self.api_client.firecloud_entry_point + "/status" self.anvil_response_mock.add( responses.GET, @@ -343,9 +300,7 @@ def test_context_data_anvil_status_not_ok(self): def test_context_data_status_api_error(self): """Page still loads if there is an AnVIL API error in the status call.""" url_me = self.api_client.firecloud_entry_point + "/me?userDetailsOnly=true" - self.anvil_response_mock.add( - responses.GET, url_me, status=200, json=self.get_json_me_data() - ) + self.anvil_response_mock.add(responses.GET, url_me, status=200, json=self.get_json_me_data()) # Error in status API url_status = self.api_client.firecloud_entry_point + "/status" self.anvil_response_mock.add(responses.GET, url_status, status=499) @@ -398,23 +353,15 @@ 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) def get_api_url(self, billing_project_name): """Get the AnVIL API url that is called by the anvil_exists method.""" - return ( - self.api_client.rawls_entry_point - + "/api/billing/v2/" - + billing_project_name - ) + return self.api_client.rawls_entry_point + "/api/billing/v2/" + billing_project_name def get_api_json_response(self): return { @@ -433,9 +380,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.""" @@ -445,13 +390,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user_with_view_perm @@ -460,13 +401,9 @@ def test_access_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -475,9 +412,7 @@ def test_access_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): @@ -488,17 +423,13 @@ def test_has_form_in_context(self): self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertTrue("form" in response.context_data) - self.assertIsInstance( - response.context_data["form"], forms.BillingProjectImportForm - ) + self.assertIsInstance(response.context_data["form"], forms.BillingProjectImportForm) def test_can_create_an_object(self): """Posting valid data to the form creates an object.""" billing_project_name = "test-billing" url = self.get_api_url(billing_project_name) - self.anvil_response_mock.add( - responses.GET, url, status=200, json=self.get_api_json_response() - ) + self.anvil_response_mock.add(responses.GET, url, status=200, json=self.get_api_json_response()) # Need a client for messages. self.client.force_login(self.user) response = self.client.post(self.get_url(), {"name": billing_project_name}) @@ -515,14 +446,10 @@ def test_can_set_note(self): """Can set the note when creating a billing project.""" billing_project_name = "test-billing" url = self.get_api_url(billing_project_name) - self.anvil_response_mock.add( - responses.GET, url, status=200, json=self.get_api_json_response() - ) + self.anvil_response_mock.add(responses.GET, url, status=200, json=self.get_api_json_response()) # Need a client for messages. self.client.force_login(self.user) - response = self.client.post( - self.get_url(), {"name": billing_project_name, "note": "test note"} - ) + response = self.client.post(self.get_url(), {"name": billing_project_name, "note": "test note"}) self.assertEqual(response.status_code, 302) new_object = models.BillingProject.objects.latest("pk") self.assertEqual(new_object.note, "test note") @@ -531,13 +458,9 @@ def test_success_message(self): """Response includes a success message if successful.""" billing_project_name = "test-billing" url = self.get_api_url(billing_project_name) - self.anvil_response_mock.add( - responses.GET, url, status=200, json=self.get_api_json_response() - ) + self.anvil_response_mock.add(responses.GET, url, status=200, json=self.get_api_json_response()) self.client.force_login(self.user) - response = self.client.post( - self.get_url(), {"name": billing_project_name}, follow=True - ) + response = self.client.post(self.get_url(), {"name": billing_project_name}, follow=True) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) self.assertEqual(views.BillingProjectImport.success_message, str(messages[0])) @@ -547,9 +470,7 @@ def test_redirects_to_new_object_detail(self): # This needs to use the client because the RequestFactory doesn't handle redirects. billing_project_name = "test-billing" url = self.get_api_url(billing_project_name) - self.anvil_response_mock.add( - responses.GET, url, status=200, json=self.get_api_json_response() - ) + self.anvil_response_mock.add(responses.GET, url, status=200, json=self.get_api_json_response()) self.client.force_login(self.user) response = self.client.post(self.get_url(), {"name": billing_project_name}) new_object = models.BillingProject.objects.latest("pk") @@ -612,9 +533,7 @@ def test_not_users_of_billing_project(self): """Posting valid data to the form does not create an object if we are not users on AnVIL.""" billing_project_name = "test-billing" url = self.get_api_url(billing_project_name) - self.anvil_response_mock.add( - responses.GET, url, status=404, json={"message": "other"} - ) + self.anvil_response_mock.add(responses.GET, url, status=404, json={"message": "other"}) # Need a client to check messages. self.client.force_login(self.user) response = self.client.post(self.get_url(), {"name": billing_project_name}) @@ -669,14 +588,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -691,9 +606,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("foo")) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url("foo") - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url("foo")) def test_status_code_with_user_permission(self): """Returns successful response code.""" @@ -704,13 +617,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo")) request.user = user_with_view_perm @@ -719,13 +628,9 @@ def test_access_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo")) request.user = user @@ -734,9 +639,7 @@ def test_access_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("foo")) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -755,9 +658,7 @@ def test_has_form_in_context(self): self.client.force_login(self.user) response = self.client.get(self.get_url(instance.name)) self.assertTrue("form" in response.context_data) - self.assertIsInstance( - response.context_data["form"], forms.BillingProjectUpdateForm - ) + self.assertIsInstance(response.context_data["form"], forms.BillingProjectUpdateForm) def test_can_modify_note(self): """Can set the note when creating a billing project.""" @@ -794,9 +695,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -811,9 +710,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("foo")) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url("foo") - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url("foo")) def test_status_code_with_user_permission(self): """Returns successful response code.""" @@ -824,9 +721,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("foo")) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -834,13 +729,9 @@ def test_access_without_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo")) request.user = user @@ -869,9 +760,7 @@ def test_workspace_table(self): self.client.force_login(self.user) response = self.client.get(self.get_url(obj.name)) self.assertIn("workspace_table", response.context_data) - self.assertIsInstance( - response.context_data["workspace_table"], tables.WorkspaceTable - ) + self.assertIsInstance(response.context_data["workspace_table"], tables.WorkspaceTable) def test_workspace_table_none(self): """No workspaces are shown if the billing project does not have any workspaces.""" @@ -917,9 +806,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -934,9 +821,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.""" @@ -946,13 +831,9 @@ def test_status_code_with_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -967,9 +848,7 @@ def test_template_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): @@ -979,9 +858,7 @@ def test_view_has_correct_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.BillingProjectTable - ) + self.assertIsInstance(response.context_data["table"], tables.BillingProjectTable) def test_view_with_no_objects(self): self.client.force_login(self.user) @@ -1019,9 +896,7 @@ def test_view_with_filter_returns_one_object_exact(self): instance = factories.BillingProjectFactory.create(name="billing_project") factories.BillingProjectFactory.create(name="project") self.client.force_login(self.user) - response = self.client.get( - self.get_url(), {"name__icontains": "billing_project"} - ) + response = self.client.get(self.get_url(), {"name__icontains": "billing_project"}) self.assertEqual(response.status_code, 200) self.assertIn("table", response.context_data) self.assertEqual(len(response.context_data["table"].rows), 1) @@ -1031,9 +906,7 @@ def test_view_with_filter_returns_one_object_case_insensitive(self): instance = factories.BillingProjectFactory.create(name="Billing_project") factories.BillingProjectFactory.create(name="Project") self.client.force_login(self.user) - response = self.client.get( - self.get_url(), {"name__icontains": "billing_project"} - ) + response = self.client.get(self.get_url(), {"name__icontains": "billing_project"}) self.assertEqual(response.status_code, 200) self.assertIn("table", response.context_data) self.assertEqual(len(response.context_data["table"].rows), 1) @@ -1066,16 +939,12 @@ 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): """Get the url for the view being tested.""" - return reverse( - "anvil_consortium_manager:billing_projects:autocomplete", args=args - ) + return reverse("anvil_consortium_manager:billing_projects:autocomplete", args=args) def get_view(self): """Return the view being tested.""" @@ -1085,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()) - 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.""" @@ -1097,9 +964,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): @@ -1107,13 +972,9 @@ def test_access_without_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -1125,24 +986,16 @@ def test_returns_all_objects(self): objects = factories.BillingProjectFactory.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 name.""" object = factories.BillingProjectFactory.create(name="test-bp") self.client.force_login(self.user) response = self.client.get(self.get_url(), {"q": "test-bp"}) - 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) @@ -1151,10 +1004,7 @@ def test_returns_correct_object_starting_with_query(self): object = factories.BillingProjectFactory.create(name="test-bp") self.client.force_login(self.user) response = self.client.get(self.get_url(), {"q": "test"}) - 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) @@ -1163,10 +1013,7 @@ def test_returns_correct_object_containing_query(self): object = factories.BillingProjectFactory.create(name="test-bp") self.client.force_login(self.user) response = self.client.get(self.get_url(), {"q": "bp"}) - 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) @@ -1175,10 +1022,7 @@ def test_returns_correct_object_case_insensitive(self): object = factories.BillingProjectFactory.create(name="TEST-BP") self.client.force_login(self.user) response = self.client.get(self.get_url(), {"q": "test-bp"}) - 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) @@ -1200,9 +1044,7 @@ def setUp(self): # Create a user with only view permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -1210,11 +1052,7 @@ def get_url(self, *args): return reverse("anvil_consortium_manager:billing_projects:audit", args=args) def get_api_url(self, billing_project_name): - return ( - self.api_client.rawls_entry_point - + "/api/billing/v2/" - + billing_project_name - ) + return self.api_client.rawls_entry_point + "/api/billing/v2/" + billing_project_name def get_api_json_response(self): return { @@ -1229,9 +1067,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.""" @@ -1241,9 +1077,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): @@ -1251,13 +1085,9 @@ def test_access_without_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -1275,9 +1105,7 @@ def test_audit_verified(self): self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertIn("verified_table", response.context_data) - self.assertIsInstance( - response.context_data["verified_table"], audit.VerifiedTable - ) + self.assertIsInstance(response.context_data["verified_table"], audit.VerifiedTable) self.assertEqual(len(response.context_data["verified_table"].rows), 0) def test_audit_verified_one_record(self): @@ -1323,9 +1151,7 @@ def test_audit_not_in_app(self): self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertIn("not_in_app_table", response.context_data) - self.assertIsInstance( - response.context_data["not_in_app_table"], audit.NotInAppTable - ) + self.assertIsInstance(response.context_data["not_in_app_table"], audit.NotInAppTable) self.assertEqual(len(response.context_data["not_in_app_table"].rows), 0) def test_audit_ok_is_ok(self): @@ -1365,9 +1191,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def tearDown(self): @@ -1390,9 +1214,7 @@ def test_view_redirect_not_logged_in(self): # Need a client for redirects. uuid = uuid4() response = self.client.get(self.get_url(uuid)) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(uuid) - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(uuid)) def test_status_code_with_user_permission(self): """Returns successful response code.""" @@ -1404,9 +1226,7 @@ def test_status_code_with_user_permission(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" uuid = uuid4() - 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(uuid)) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -1414,13 +1234,9 @@ def test_access_without_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url(uuid4())) request.user = user @@ -1442,9 +1258,7 @@ def test_context_active_account(self): def test_context_inactive_account(self): """An is_inactive flag is included in the context.""" - active_account = factories.AccountFactory.create( - status=models.Account.INACTIVE_STATUS - ) + active_account = factories.AccountFactory.create(status=models.Account.INACTIVE_STATUS) self.client.force_login(self.user) response = self.client.get(self.get_url(active_account.uuid)) context = response.context_data @@ -1485,9 +1299,7 @@ def test_group_account_membership_table(self): self.client.force_login(self.user) response = self.client.get(self.get_url(obj.uuid)) self.assertIn("group_table", response.context_data) - self.assertIsInstance( - response.context_data["group_table"], tables.GroupAccountMembershipTable - ) + self.assertIsInstance(response.context_data["group_table"], tables.GroupAccountMembershipTable) def test_group_account_membership_none(self): """No groups are shown if the account is not part of any groups.""" @@ -1529,12 +1341,8 @@ def test_edit_permission(self): """Links to reactivate/deactivate/delete pages appear if the user has edit permission.""" edit_user = User.objects.create_user(username="edit", password="test") edit_user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ), - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ), + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME), + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME), ) self.client.force_login(edit_user) account = factories.AccountFactory.create() @@ -1553,9 +1361,7 @@ def test_view_permission(self): """Links to reactivate/deactivate/delete pages appear if the user has edit permission.""" view_user = User.objects.create_user(username="view", password="test") view_user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ), + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME), ) self.client.force_login(view_user) account = factories.AccountFactory.create() @@ -1587,9 +1393,7 @@ def test_accessible_workspace_none(self): self.client.force_login(self.user) response = self.client.get(self.get_url(account.uuid)) self.assertIn("accessible_workspace_table", response.context_data) - self.assertEqual( - len(response.context_data["accessible_workspace_table"].rows), 0 - ) + self.assertEqual(len(response.context_data["accessible_workspace_table"].rows), 0) def test_accessible_workspace_one(self): """One accessible_workspace is shown if there is one accessible workspace for the account.""" @@ -1601,9 +1405,7 @@ def test_accessible_workspace_one(self): self.client.force_login(self.user) response = self.client.get(self.get_url(account.uuid)) self.assertIn("accessible_workspace_table", response.context_data) - self.assertEqual( - len(response.context_data["accessible_workspace_table"].rows), 1 - ) + self.assertEqual(len(response.context_data["accessible_workspace_table"].rows), 1) def test_accessible_workspace_two(self): """Two accessible_workspaces are shown if there are two accessible workspaces for the account.""" @@ -1612,18 +1414,12 @@ def test_accessible_workspace_two(self): workspace_2 = factories.WorkspaceFactory.create() group = factories.ManagedGroupFactory.create() factories.GroupAccountMembershipFactory.create(group=group, account=account) - factories.WorkspaceGroupSharingFactory.create( - workspace=workspace_2, group=group - ) - factories.WorkspaceGroupSharingFactory.create( - workspace=workspace_1, group=group - ) + factories.WorkspaceGroupSharingFactory.create(workspace=workspace_2, group=group) + factories.WorkspaceGroupSharingFactory.create(workspace=workspace_1, group=group) self.client.force_login(self.user) response = self.client.get(self.get_url(account.uuid)) self.assertIn("accessible_workspace_table", response.context_data) - self.assertEqual( - len(response.context_data["accessible_workspace_table"].rows), 2 - ) + self.assertEqual(len(response.context_data["accessible_workspace_table"].rows), 2) def test_accessible_workspace_for_only_that_user(self): """Only shows accessible_workspace that is accessible to the account.""" @@ -1634,9 +1430,7 @@ def test_accessible_workspace_for_only_that_user(self): self.client.force_login(self.user) response = self.client.get(self.get_url(account.uuid)) self.assertIn("accessible_workspace_table", response.context_data) - self.assertEqual( - len(response.context_data["accessible_workspace_table"].rows), 0 - ) + self.assertEqual(len(response.context_data["accessible_workspace_table"].rows), 0) def test_accessible_workspace_one_workspace_shared_twice(self): """Two records are shown for the same workspace if it is shared with an account twice.""" @@ -1659,9 +1453,7 @@ def test_accessible_workspace_one_workspace_shared_twice(self): self.client.force_login(self.user) response = self.client.get(self.get_url(account.uuid)) self.assertIn("accessible_workspace_table", response.context_data) - self.assertEqual( - len(response.context_data["accessible_workspace_table"].rows), 2 - ) + self.assertEqual(len(response.context_data["accessible_workspace_table"].rows), 2) def test_accessible_workspace_only_groups_for_this_account(self): """Only shows workspaces shared with one of the account's groups (or parent groups).""" @@ -1669,14 +1461,10 @@ def test_accessible_workspace_only_groups_for_this_account(self): workspace = factories.WorkspaceFactory.create() group = factories.ManagedGroupFactory.create() factories.GroupAccountMembershipFactory.create(group=group, account=account) - sharing = factories.WorkspaceGroupSharingFactory.create( - workspace=workspace, group=group - ) + sharing = factories.WorkspaceGroupSharingFactory.create(workspace=workspace, group=group) # Share the workspace with a different group that the account is not part of. other_group = factories.ManagedGroupFactory.create() - factories.WorkspaceGroupSharingFactory.create( - workspace=workspace, group=other_group - ) + factories.WorkspaceGroupSharingFactory.create(workspace=workspace, group=other_group) self.client.force_login(self.user) response = self.client.get(self.get_url(account.uuid)) table = response.context_data["accessible_workspace_table"] @@ -1692,9 +1480,7 @@ def foo(self): UserModel = get_user_model() setattr(UserModel, "get_absolute_url", foo) user = UserModel.objects.create(username="testuser2", password="testpassword") - account = factories.AccountFactory.create( - verified=True, verified_email_entry__user=user - ) + account = factories.AccountFactory.create(verified=True, verified_email_entry__user=user) self.client.force_login(self.user) response = self.client.get(self.get_url(account.uuid)) self.assertInHTML( @@ -1711,14 +1497,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) def get_api_url(self, email): @@ -1745,9 +1527,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.""" @@ -1757,13 +1537,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user_with_view_perm @@ -1772,13 +1548,9 @@ def test_access_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -1787,9 +1559,7 @@ def test_access_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): @@ -1833,9 +1603,7 @@ def test_can_create_an_object_with_note(self): ) # Need a client because messages are added. self.client.force_login(self.user) - response = self.client.post( - self.get_url(), {"email": email, "note": "test note"} - ) + response = self.client.post(self.get_url(), {"email": email, "note": "test note"}) self.assertEqual(response.status_code, 302) new_object = models.Account.objects.latest("pk") self.assertIsInstance(new_object, models.Account) @@ -1938,9 +1706,7 @@ def test_can_create_service_account(self): ) # Need a client because messages are added. self.client.force_login(self.user) - response = self.client.post( - self.get_url(), {"email": email, "is_service_account": True} - ) + response = self.client.post(self.get_url(), {"email": email, "is_service_account": True}) self.assertEqual(response.status_code, 302) new_object = models.Account.objects.latest("pk") self.assertIsInstance(new_object, models.Account) @@ -1969,9 +1735,7 @@ def test_does_not_exist_on_anvil(self): # ...but the account doesn't exist on AnVIL messages = list(response.context["messages"]) self.assertEqual(len(messages), 1) - self.assertEqual( - str(messages[0]), views.AccountImport.message_account_does_not_exist - ) + self.assertEqual(str(messages[0]), views.AccountImport.message_account_does_not_exist) # No accounts were created. self.assertEqual(models.Account.objects.count(), 0) @@ -1994,9 +1758,7 @@ def test_email_is_associated_with_group(self): # ...but there was some error from the API. messages = list(response.context["messages"]) self.assertEqual(len(messages), 1) - self.assertEqual( - views.AccountImport.message_account_does_not_exist, str(messages[0]) - ) + self.assertEqual(views.AccountImport.message_account_does_not_exist, str(messages[0])) # No accounts were created. self.assertEqual(models.Account.objects.count(), 0) @@ -2033,14 +1795,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -2056,9 +1814,7 @@ def test_view_redirect_not_logged_in(self): # Need a client for redirects. uuid = uuid4() response = self.client.get(self.get_url(uuid)) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(uuid) - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(uuid)) def test_status_code_with_user_permission(self): """Returns successful response code.""" @@ -2070,13 +1826,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.""" uuid = uuid4() - 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url(uuid)) request.user = user_with_view_perm @@ -2085,13 +1837,9 @@ def test_access_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url(uuid4())) request.user = user @@ -2101,9 +1849,7 @@ def test_access_with_limited_view_permission(self): def test_access_without_user_permission(self): """Raises permission denied if user has no permissions.""" uuid = uuid4() - 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(uuid)) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -2163,9 +1909,7 @@ 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=models.AnVILProjectManagerAccess.ACCOUNT_LINK_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.ACCOUNT_LINK_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -2191,15 +1935,11 @@ 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()) - 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_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): @@ -2207,13 +1947,9 @@ def test_access_without_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -2237,9 +1973,7 @@ def test_can_create_an_entry(self): """Posting valid data to the form works as expected.""" email = "test@example.com" api_url = self.get_api_url(email) - self.anvil_response_mock.add( - responses.GET, api_url, status=200, json=self.get_api_json_response(email) - ) + self.anvil_response_mock.add(responses.GET, api_url, status=200, json=self.get_api_json_response(email)) timestamp_lower_limit = timezone.now() # Need a client because messages are added. self.client.force_login(self.user) @@ -2252,9 +1986,7 @@ def test_can_create_an_entry(self): self.assertEqual(new_object.email, email) self.assertEqual(new_object.user, self.user) self.assertIsNotNone(new_object.date_verification_email_sent) - self.assertGreaterEqual( - new_object.date_verification_email_sent, timestamp_lower_limit - ) + self.assertGreaterEqual(new_object.date_verification_email_sent, timestamp_lower_limit) self.assertLessEqual(new_object.date_verification_email_sent, timezone.now()) self.assertIsNone(new_object.date_verified) # No account is linked. @@ -2269,9 +2001,7 @@ def test_success_message(self): """A success message is added.""" email = "test@example.com" api_url = self.get_api_url(email) - self.anvil_response_mock.add( - responses.GET, api_url, status=200, json=self.get_api_json_response(email) - ) + self.anvil_response_mock.add(responses.GET, api_url, status=200, json=self.get_api_json_response(email)) # Need a client because messages are added. self.client.force_login(self.user) response = self.client.post(self.get_url(), {"email": email}, follow=True) @@ -2283,9 +2013,7 @@ def test_redirect(self): """View redirects to the correct URL.""" email = "test@example.com" api_url = self.get_api_url(email) - self.anvil_response_mock.add( - responses.GET, api_url, status=200, json=self.get_api_json_response(email) - ) + self.anvil_response_mock.add(responses.GET, api_url, status=200, json=self.get_api_json_response(email)) # Need a client because messages are added. self.client.force_login(self.user) response = self.client.post(self.get_url(), {"email": email}) @@ -2299,9 +2027,7 @@ def test_email_is_sent(self): """An email is sent when the form is submitted correctly.""" email = "test@example.com" api_url = self.get_api_url(email) - self.anvil_response_mock.add( - responses.GET, api_url, status=200, json=self.get_api_json_response(email) - ) + self.anvil_response_mock.add(responses.GET, api_url, status=200, json=self.get_api_json_response(email)) # Need a client because messages are added. self.client.force_login(self.user) self.client.post(self.get_url(), {"email": email}) @@ -2325,9 +2051,7 @@ def test_email_is_sent_site_domain(self): site.save() email = "test@example.com" api_url = self.get_api_url(email) - self.anvil_response_mock.add( - responses.GET, api_url, status=200, json=self.get_api_json_response(email) - ) + self.anvil_response_mock.add(responses.GET, api_url, status=200, json=self.get_api_json_response(email)) # Need a client because messages are added. self.client.force_login(self.user) self.client.post(self.get_url(), {"email": email}) @@ -2360,9 +2084,7 @@ def test_get_user_already_linked_to_an_existing_verified_account(self): # A message is included. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - str(messages[0]), views.AccountLink.message_user_already_linked - ) + self.assertEqual(str(messages[0]), views.AccountLink.message_user_already_linked) def test_post_user_already_linked_to_an_existing_verified_account(self): """View redirects with a message when the user already has an AnVIL account linked.""" @@ -2371,9 +2093,7 @@ def test_post_user_already_linked_to_an_existing_verified_account(self): # No API call should be made, so do not add a mocked response. # Need a client because messages are added. self.client.force_login(self.user) - response = self.client.post( - self.get_url(), {"email": "foo@bar.com"}, follow=True - ) + response = self.client.post(self.get_url(), {"email": "foo@bar.com"}, follow=True) self.assertRedirects(response, "/test_home/") # No new user entry is created. self.assertEqual(models.UserEmailEntry.objects.count(), 1) @@ -2383,9 +2103,7 @@ def test_post_user_already_linked_to_an_existing_verified_account(self): # A message is included. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - str(messages[0]), views.AccountLink.message_user_already_linked - ) + self.assertEqual(str(messages[0]), views.AccountLink.message_user_already_linked) def test_same_user_same_email_unverified(self): """A UserEmailEntry record already exists for this user and email combo, but it is not verified yet.""" @@ -2395,9 +2113,7 @@ def test_same_user_same_email_unverified(self): user=self.user, email=email, date_verification_email_sent=original_date ) api_url = self.get_api_url(email) - self.anvil_response_mock.add( - responses.GET, api_url, status=200, json=self.get_api_json_response(email) - ) + self.anvil_response_mock.add(responses.GET, api_url, status=200, json=self.get_api_json_response(email)) # Need a client because messages are added. timestamp_lower_limit = timezone.now() self.client.force_login(self.user) @@ -2409,9 +2125,7 @@ def test_same_user_same_email_unverified(self): self.assertIn(email_entry, models.UserEmailEntry.objects.all()) # date_verification_email_sent is updated. self.assertGreater(email_entry.date_verification_email_sent, original_date) - self.assertGreaterEqual( - email_entry.date_verification_email_sent, timestamp_lower_limit - ) + self.assertGreaterEqual(email_entry.date_verification_email_sent, timestamp_lower_limit) # An email is sent. self.assertEqual(len(mail.outbox), 1) # But it still does not have a verified account. @@ -2426,9 +2140,7 @@ def test_account_already_linked_to_different_user_and_verified(self): """A different user already has already verified this email.""" email = "test@example.com" other_user = User.objects.create_user(username="test2", password="test2") - other_account = factories.AccountFactory.create( - user=other_user, email=email, verified=True - ) + other_account = factories.AccountFactory.create(user=other_user, email=email, verified=True) other_email_entry = other_account.verified_email_entry # No API call should be made, so do not add a mocked response. # Need a client because messages are added. @@ -2443,17 +2155,13 @@ def test_account_already_linked_to_different_user_and_verified(self): # A message is added. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - str(messages[0]), views.AccountLink.message_account_already_exists - ) + self.assertEqual(str(messages[0]), views.AccountLink.message_account_already_exists) def test_account_does_not_exist_on_anvil(self): """Page is reloaded with a message if the account does not exist on AnVIL.""" email = "test@example.com" api_url = self.get_api_url(email) - self.anvil_response_mock.add( - responses.GET, api_url, status=404, json={"message": "mock message"} - ) + self.anvil_response_mock.add(responses.GET, api_url, status=404, json={"message": "mock message"}) # Need a client because messages are added. self.client.force_login(self.user) response = self.client.post(self.get_url(), {"email": email}) @@ -2467,9 +2175,7 @@ def test_account_does_not_exist_on_anvil(self): # A message is added. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - str(messages[0]), views.AccountLink.message_account_does_not_exist - ) + self.assertEqual(str(messages[0]), views.AccountLink.message_account_does_not_exist) # No new Accounts are created. self.assertEqual(models.Account.objects.count(), 0) # API call to AnVIL was made. @@ -2512,9 +2218,7 @@ def test_account_exists_with_email_but_not_linked_to_user(self): # A message is added. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - str(messages[0]), views.AccountLink.message_account_already_exists - ) + self.assertEqual(str(messages[0]), views.AccountLink.message_account_already_exists) # This test occasionally fails if the time flips one second between sending the email and # regenerating the token. Use freezegun's freeze_time decorator to fix the time and avoid @@ -2530,9 +2234,7 @@ def test_user_can_enter_two_different_emails(self): ) email = "test@example.com" api_url = self.get_api_url(email) - self.anvil_response_mock.add( - responses.GET, api_url, status=200, json=self.get_api_json_response(email) - ) + self.anvil_response_mock.add(responses.GET, api_url, status=200, json=self.get_api_json_response(email)) timestamp_lower_limit = timezone.now() # Need a client because messages are added. self.client.force_login(self.user) @@ -2546,9 +2248,7 @@ def test_user_can_enter_two_different_emails(self): self.assertEqual(new_object.email, email) self.assertEqual(new_object.user, self.user) self.assertIsNotNone(new_object.date_verification_email_sent) - self.assertGreaterEqual( - new_object.date_verification_email_sent, timestamp_lower_limit - ) + self.assertGreaterEqual(new_object.date_verification_email_sent, timestamp_lower_limit) self.assertLessEqual(new_object.date_verification_email_sent, timezone.now()) with self.assertRaises(ObjectDoesNotExist): new_object.verified_account @@ -2556,17 +2256,11 @@ def test_user_can_enter_two_different_emails(self): self.assertEqual(len(mail.outbox), 1) # The contents have the correct link. self.assertIn(str(new_object.uuid), mail.outbox[0].body) - self.assertIn( - account_verification_token.make_token(new_object), mail.outbox[0].body - ) + self.assertIn(account_verification_token.make_token(new_object), mail.outbox[0].body) # The timestamp on the other entry hasn't changed. other_email_entry.refresh_from_db() - self.assertLess( - other_email_entry.date_verification_email_sent, timestamp_lower_limit - ) - self.assertEqual( - other_email_entry.date_verification_email_sent, other_timestamp - ) + self.assertLess(other_email_entry.date_verification_email_sent, timestamp_lower_limit) + self.assertEqual(other_email_entry.date_verification_email_sent, other_timestamp) self.assertEqual(other_email_entry.history.count(), 1) self.assertEqual(other_email_entry.history.latest().history_type, "+") # History is added. @@ -2587,9 +2281,7 @@ def test_two_different_users_can_attempt_to_link_same_email(self): user=other_user, email=email, date_verification_email_sent=other_timestamp ) api_url = self.get_api_url(email) - self.anvil_response_mock.add( - responses.GET, api_url, status=200, json=self.get_api_json_response(email) - ) + self.anvil_response_mock.add(responses.GET, api_url, status=200, json=self.get_api_json_response(email)) timestamp_lower_limit = timezone.now() # Need a client because messages are added. self.client.force_login(self.user) @@ -2603,9 +2295,7 @@ def test_two_different_users_can_attempt_to_link_same_email(self): self.assertEqual(new_object.email, email) self.assertEqual(new_object.user, self.user) self.assertIsNotNone(new_object.date_verification_email_sent) - self.assertGreaterEqual( - new_object.date_verification_email_sent, timestamp_lower_limit - ) + self.assertGreaterEqual(new_object.date_verification_email_sent, timestamp_lower_limit) self.assertLessEqual(new_object.date_verification_email_sent, timezone.now()) with self.assertRaises(ObjectDoesNotExist): new_object.verified_account @@ -2613,19 +2303,13 @@ def test_two_different_users_can_attempt_to_link_same_email(self): self.assertEqual(len(mail.outbox), 1) # The contents have the correct link. self.assertIn(str(new_object.uuid), mail.outbox[0].body) - self.assertIn( - account_verification_token.make_token(new_object), mail.outbox[0].body - ) + self.assertIn(account_verification_token.make_token(new_object), mail.outbox[0].body) # The other entry hasn't changed. other_email_entry.refresh_from_db() self.assertEqual(other_email_entry.email, email) self.assertEqual(other_email_entry.user, other_user) - self.assertLess( - other_email_entry.date_verification_email_sent, timestamp_lower_limit - ) - self.assertEqual( - other_email_entry.date_verification_email_sent, other_timestamp - ) + self.assertLess(other_email_entry.date_verification_email_sent, timestamp_lower_limit) + self.assertEqual(other_email_entry.date_verification_email_sent, other_timestamp) self.assertEqual(other_email_entry.history.count(), 1) self.assertEqual(other_email_entry.history.latest().history_type, "+") # History is added. @@ -2647,9 +2331,7 @@ def test_email_case_insensitive(self): ) # API call will be made with the existing entry. api_url = self.get_api_url(email_entry.email) - self.anvil_response_mock.add( - responses.GET, api_url, status=200, json=self.get_api_json_response(email) - ) + self.anvil_response_mock.add(responses.GET, api_url, status=200, json=self.get_api_json_response(email)) # Need a client because messages are added. timestamp_lower_limit = timezone.now() self.client.force_login(self.user) @@ -2661,16 +2343,12 @@ def test_email_case_insensitive(self): self.assertIn(email_entry, models.UserEmailEntry.objects.all()) # date_verification_email_sent is updated. self.assertGreater(email_entry.date_verification_email_sent, original_date) - self.assertGreaterEqual( - email_entry.date_verification_email_sent, timestamp_lower_limit - ) + self.assertGreaterEqual(email_entry.date_verification_email_sent, timestamp_lower_limit) # An email is sent. self.assertEqual(len(mail.outbox), 1) # The email has the correct link generated from the lowercase email. self.assertIn(str(email_entry.uuid), mail.outbox[0].body) - self.assertIn( - account_verification_token.make_token(email_entry), mail.outbox[0].body - ) + self.assertIn(account_verification_token.make_token(email_entry), mail.outbox[0].body) # But it still does not have a verified account. with self.assertRaises(ObjectDoesNotExist): email_entry.verified_account @@ -2723,9 +2401,7 @@ def test_email_associated_with_group(self): # ...but there was some error from the API. messages = list(response.context["messages"]) self.assertEqual(len(messages), 1) - self.assertEqual( - views.AccountLink.message_account_does_not_exist, str(messages[0]) - ) + self.assertEqual(views.AccountLink.message_account_does_not_exist, str(messages[0])) # No accounts were created. self.assertEqual(models.UserEmailEntry.objects.count(), 0) # No email is sent. @@ -2742,9 +2418,7 @@ def setUp(self): # Create a user with no special permissions. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.ACCOUNT_LINK_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.ACCOUNT_LINK_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -2778,9 +2452,7 @@ def test_view_redirect_not_logged_in(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(uuid4(), "bar")) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -2788,13 +2460,9 @@ def test_access_without_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url(uuid4(), "bar")) request.user = user @@ -2804,14 +2472,10 @@ def test_access_with_limited_view_permission(self): def test_user_with_perms_can_verify_email(self): """A user can successfully verify their email.""" email = "test@example.com" - email_entry = factories.UserEmailEntryFactory.create( - user=self.user, email=email - ) + email_entry = factories.UserEmailEntryFactory.create(user=self.user, email=email) token = account_verification_token.make_token(email_entry) api_url = self.get_api_url(email) - self.anvil_response_mock.add( - responses.GET, api_url, status=200, json=self.get_api_json_response(email) - ) + self.anvil_response_mock.add(responses.GET, api_url, status=200, json=self.get_api_json_response(email)) timestamp_threshold = timezone.now() # Need a client because messages are added. self.client.force_login(self.user) @@ -2857,9 +2521,7 @@ def test_user_email_entry_does_not_exist(self): def test_this_user_already_verified_this_email(self): """The user has already verified their email.""" email = "test@example.com" - account = factories.AccountFactory.create( - user=self.user, email=email, verified=True - ) + account = factories.AccountFactory.create(user=self.user, email=email, verified=True) email_entry = account.verified_email_entry token = account_verification_token.make_token(email_entry) # No API calls are made, so do not add a mocked response. @@ -2875,20 +2537,14 @@ def test_this_user_already_verified_this_email(self): # A message is added. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - str(messages[0]), views.AccountLinkVerify.message_already_linked - ) + self.assertEqual(str(messages[0]), views.AccountLinkVerify.message_already_linked) def test_user_already_verified_different_email(self): """The user already verified a different email.""" email = "test@example.com" - existing_account = factories.AccountFactory.create( - user=self.user, email="foo@bar.com", verified=True - ) + existing_account = factories.AccountFactory.create(user=self.user, email="foo@bar.com", verified=True) existing_email_entry = existing_account.verified_email_entry - email_entry = factories.UserEmailEntryFactory.create( - user=self.user, email=email - ) + email_entry = factories.UserEmailEntryFactory.create(user=self.user, email=email) token = account_verification_token.make_token(email_entry) # No API calls are made, so do not add a mocked response. # Need a client because messages are added. @@ -2903,18 +2559,12 @@ def test_user_already_verified_different_email(self): # A message is added. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - str(messages[0]), views.AccountLinkVerify.message_already_linked - ) + self.assertEqual(str(messages[0]), views.AccountLinkVerify.message_already_linked) def test_token_does_not_match(self): """The token does not match.""" - other_email_entry = factories.UserEmailEntryFactory.create( - user=self.user, email="foo@bar.com" - ) - email_entry = factories.UserEmailEntryFactory.create( - user=self.user, email="test@example.com" - ) + other_email_entry = factories.UserEmailEntryFactory.create(user=self.user, email="foo@bar.com") + email_entry = factories.UserEmailEntryFactory.create(user=self.user, email="test@example.com") # Use the uid from this email entry, but the token from the other email entry. token = account_verification_token.make_token(other_email_entry) # No API calls are made, so do not add a mocked response. @@ -2937,13 +2587,9 @@ def test_different_user_verified_this_email(self): email = "test@example.com" other_user = factories.UserFactory.create() # Create an email entry record for both users with the same email - other_account = factories.AccountFactory.create( - user=other_user, email=email, verified=True - ) + other_account = factories.AccountFactory.create(user=other_user, email=email, verified=True) other_email_entry = other_account.verified_email_entry - email_entry = factories.UserEmailEntryFactory.create( - user=self.user, email=email - ) + email_entry = factories.UserEmailEntryFactory.create(user=self.user, email=email) token = account_verification_token.make_token(email_entry) # No API calls are made, so do not add a mocked response. # Need a client because messages are added. @@ -2963,17 +2609,13 @@ def test_different_user_verified_this_email(self): # A message is added. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - str(messages[0]), views.AccountLinkVerify.message_account_already_exists - ) + self.assertEqual(str(messages[0]), views.AccountLinkVerify.message_account_already_exists) def test_anvil_account_no_longer_exists(self): """The email no longer has an associated AnVIL account.""" email_entry = factories.UserEmailEntryFactory.create() api_url = self.get_api_url(email_entry.email) - self.anvil_response_mock.add( - responses.GET, api_url, status=404, json={"message": "mock message"} - ) + self.anvil_response_mock.add(responses.GET, api_url, status=404, json={"message": "mock message"}) token = account_verification_token.make_token(email_entry) # No API calls are made, so do not add a mocked response. # Need a client because messages are added. @@ -2990,9 +2632,7 @@ def test_anvil_account_no_longer_exists(self): # A message is added. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - str(messages[0]), views.AccountLinkVerify.message_account_does_not_exist - ) + self.assertEqual(str(messages[0]), views.AccountLinkVerify.message_account_does_not_exist) def test_email_associated_with_group(self): """The email is associated with a group on AnVIL.""" @@ -3015,17 +2655,13 @@ def test_email_associated_with_group(self): # A message is added. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - str(messages[0]), views.AccountLinkVerify.message_account_does_not_exist - ) + self.assertEqual(str(messages[0]), views.AccountLinkVerify.message_account_does_not_exist) def test_api_call_fails(self): """The API call to AnVIL fails.""" email_entry = factories.UserEmailEntryFactory.create() api_url = self.get_api_url(email_entry.email) - self.anvil_response_mock.add( - responses.GET, api_url, status=500, json={"message": "other error"} - ) + self.anvil_response_mock.add(responses.GET, api_url, status=500, json={"message": "other error"}) token = account_verification_token.make_token(email_entry) # No API calls are made, so do not add a mocked response. # Need a client because messages are added. @@ -3047,14 +2683,10 @@ def test_api_call_fails(self): def test_no_notification_email(self): """Notification email is not sent if ANVIL_ACCOUNT_VERIFY_NOTIFICATION_EMAIL is not set""" email = "test@example.com" - email_entry = factories.UserEmailEntryFactory.create( - user=self.user, email=email - ) + email_entry = factories.UserEmailEntryFactory.create(user=self.user, email=email) token = account_verification_token.make_token(email_entry) api_url = self.get_api_url(email) - self.anvil_response_mock.add( - responses.GET, api_url, status=200, json=self.get_api_json_response(email) - ) + self.anvil_response_mock.add(responses.GET, api_url, status=200, json=self.get_api_json_response(email)) self.client.force_login(self.user) response = self.client.get(self.get_url(email_entry.uuid, token)) self.assertEqual(response.status_code, 302) @@ -3065,14 +2697,10 @@ def test_no_notification_email(self): def test_notification_email(self): """Notification email is sent if ANVIL_ACCOUNT_VERIFY_NOTIFICATION_EMAIL set.""" email = "test1@example.com" - email_entry = factories.UserEmailEntryFactory.create( - user=self.user, email=email - ) + email_entry = factories.UserEmailEntryFactory.create(user=self.user, email=email) token = account_verification_token.make_token(email_entry) api_url = self.get_api_url(email) - self.anvil_response_mock.add( - responses.GET, api_url, status=200, json=self.get_api_json_response(email) - ) + self.anvil_response_mock.add(responses.GET, api_url, status=200, json=self.get_api_json_response(email)) self.client.force_login(self.user) response = self.client.get(self.get_url(email_entry.uuid, token)) self.assertEqual(response.status_code, 302) @@ -3085,14 +2713,10 @@ def test_notification_email(self): def test_no_notification_email_when_none(self): """Notification email is sent if ANVIL_ACCOUNT_VERIFY_NOTIFICATION_EMAIL set.""" email = "test@example.com" - email_entry = factories.UserEmailEntryFactory.create( - user=self.user, email=email - ) + email_entry = factories.UserEmailEntryFactory.create(user=self.user, email=email) token = account_verification_token.make_token(email_entry) api_url = self.get_api_url(email) - self.anvil_response_mock.add( - responses.GET, api_url, status=200, json=self.get_api_json_response(email) - ) + self.anvil_response_mock.add(responses.GET, api_url, status=200, json=self.get_api_json_response(email)) self.client.force_login(self.user) response = self.client.get(self.get_url(email_entry.uuid, token)) self.assertEqual(response.status_code, 302) @@ -3107,9 +2731,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -3124,9 +2746,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.""" @@ -3136,9 +2756,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): @@ -3146,13 +2764,9 @@ def test_access_without_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -3194,9 +2808,7 @@ def test_filterset_class(self): self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertIn("filter", response.context_data) - self.assertIsInstance( - response.context_data["filter"], filters.AccountListFilter - ) + self.assertIsInstance(response.context_data["filter"], filters.AccountListFilter) def test_view_with_filter_return_no_object(self): factories.AccountFactory.create(email="account_test1@example.com") @@ -3211,9 +2823,7 @@ def test_view_with_filter_returns_one_object_exact(self): instance = factories.AccountFactory.create(email="account_test1@example.com") factories.AccountFactory.create(email="account@example.com") self.client.force_login(self.user) - response = self.client.get( - self.get_url(), {"email__icontains": "account_test1@example.com"} - ) + response = self.client.get(self.get_url(), {"email__icontains": "account_test1@example.com"}) self.assertEqual(response.status_code, 200) self.assertIn("table", response.context_data) self.assertEqual(len(response.context_data["table"].rows), 1) @@ -3223,9 +2833,7 @@ def test_view_with_filter_returns_one_object_case_insensitive(self): instance = factories.AccountFactory.create(email="account_Test1@example.com") factories.AccountFactory.create(email="account@example.com") self.client.force_login(self.user) - response = self.client.get( - self.get_url(), {"email__icontains": "account_test1@example.com"} - ) + response = self.client.get(self.get_url(), {"email__icontains": "account_test1@example.com"}) self.assertEqual(response.status_code, 200) self.assertIn("table", response.context_data) self.assertEqual(len(response.context_data["table"].rows), 1) @@ -3242,12 +2850,8 @@ def test_view_with_filter_returns_one_object_contains(self): self.assertIn(instance, response.context_data["table"].data) def test_view_with_filter_status(self): - factories.AccountFactory.create( - email="account1@example.com", status=models.Account.ACTIVE_STATUS - ) - factories.AccountFactory.create( - email="account2@example.com", status=models.Account.INACTIVE_STATUS - ) + factories.AccountFactory.create(email="account1@example.com", status=models.Account.ACTIVE_STATUS) + factories.AccountFactory.create(email="account2@example.com", status=models.Account.INACTIVE_STATUS) self.client.force_login(self.user) response = self.client.get(self.get_url(), {"email__icontains": "account"}) self.assertEqual(response.status_code, 200) @@ -3285,17 +2889,13 @@ def test_view_with_active_and_inactive_accounts(self): self.assertIn(active_object, response.context_data["table"].data) self.assertIn(inactive_object, response.context_data["table"].data) - @override_settings( - ANVIL_ACCOUNT_ADAPTER="anvil_consortium_manager.tests.test_app.adapters.TestAccountAdapter" - ) + @override_settings(ANVIL_ACCOUNT_ADAPTER="anvil_consortium_manager.tests.test_app.adapters.TestAccountAdapter") def test_adapter(self): """Displays the correct table if specified in the adapter.""" 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"], app_tables.TestAccountTable - ) + self.assertIsInstance(response.context_data["table"], app_tables.TestAccountTable) self.assertIsInstance(response.context_data["filter"], TestAccountListFilter) @@ -3306,9 +2906,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -3323,9 +2921,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.""" @@ -3335,9 +2931,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): @@ -3345,13 +2939,9 @@ def test_access_without_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -3370,9 +2960,7 @@ def test_filterset_class(self): self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertIn("filter", response.context_data) - self.assertIsInstance( - response.context_data["filter"], filters.AccountListFilter - ) + self.assertIsInstance(response.context_data["filter"], filters.AccountListFilter) def test_view_with_no_objects(self): self.client.force_login(self.user) @@ -3398,12 +2986,8 @@ def test_view_with_two_objects(self): self.assertEqual(len(response.context_data["table"].rows), 2) def test_view_with_filter_return_no_object(self): - factories.AccountFactory.create( - email="account_test1@example.com", status=models.Account.ACTIVE_STATUS - ) - factories.AccountFactory.create( - email="account@example.com", status=models.Account.ACTIVE_STATUS - ) + factories.AccountFactory.create(email="account_test1@example.com", status=models.Account.ACTIVE_STATUS) + factories.AccountFactory.create(email="account@example.com", status=models.Account.ACTIVE_STATUS) self.client.force_login(self.user) response = self.client.get(self.get_url(), {"email__icontains": "abc"}) self.assertEqual(response.status_code, 200) @@ -3414,13 +2998,9 @@ def test_view_with_filter_returns_one_object_exact(self): instance = factories.AccountFactory.create( email="account_test1@example.com", status=models.Account.ACTIVE_STATUS ) - factories.AccountFactory.create( - email="account@example.com", status=models.Account.ACTIVE_STATUS - ) + factories.AccountFactory.create(email="account@example.com", status=models.Account.ACTIVE_STATUS) self.client.force_login(self.user) - response = self.client.get( - self.get_url(), {"email__icontains": "account_test1@example.com"} - ) + response = self.client.get(self.get_url(), {"email__icontains": "account_test1@example.com"}) self.assertEqual(response.status_code, 200) self.assertIn("table", response.context_data) self.assertEqual(len(response.context_data["table"].rows), 1) @@ -3430,25 +3010,17 @@ def test_view_with_filter_returns_one_object_case_insensitive(self): instance = factories.AccountFactory.create( email="account_Test1@example.com", status=models.Account.ACTIVE_STATUS ) - factories.AccountFactory.create( - email="account@example.com", status=models.Account.ACTIVE_STATUS - ) + factories.AccountFactory.create(email="account@example.com", status=models.Account.ACTIVE_STATUS) self.client.force_login(self.user) - response = self.client.get( - self.get_url(), {"email__icontains": "account_test1@example.com"} - ) + response = self.client.get(self.get_url(), {"email__icontains": "account_test1@example.com"}) self.assertEqual(response.status_code, 200) self.assertIn("table", response.context_data) self.assertEqual(len(response.context_data["table"].rows), 1) self.assertIn(instance, response.context_data["table"].data) def test_view_with_filter_returns_one_object_active_only(self): - instance = factories.AccountFactory.create( - email="account1@example.com", status=models.Account.ACTIVE_STATUS - ) - factories.AccountFactory.create( - email="account2@example.com", status=models.Account.INACTIVE_STATUS - ) + instance = factories.AccountFactory.create(email="account1@example.com", status=models.Account.ACTIVE_STATUS) + factories.AccountFactory.create(email="account2@example.com", status=models.Account.INACTIVE_STATUS) self.client.force_login(self.user) response = self.client.get(self.get_url(), {"email__icontains": "account"}) self.assertEqual(response.status_code, 200) @@ -3460,9 +3032,7 @@ def test_view_with_filter_returns_one_object_contains(self): instance = factories.AccountFactory.create( email="account_test1@example.com", status=models.Account.ACTIVE_STATUS ) - factories.AccountFactory.create( - email="account@example.com", status=models.Account.ACTIVE_STATUS - ) + factories.AccountFactory.create(email="account@example.com", status=models.Account.ACTIVE_STATUS) self.client.force_login(self.user) response = self.client.get(self.get_url(), {"email__icontains": "test1"}) self.assertEqual(response.status_code, 200) @@ -3471,12 +3041,8 @@ def test_view_with_filter_returns_one_object_contains(self): self.assertIn(instance, response.context_data["table"].data) def test_view_with_filter_returns_all_objects(self): - factories.AccountFactory.create( - email="account1@example.com", status=models.Account.ACTIVE_STATUS - ) - factories.AccountFactory.create( - email="account2@example.com", status=models.Account.ACTIVE_STATUS - ) + factories.AccountFactory.create(email="account1@example.com", status=models.Account.ACTIVE_STATUS) + factories.AccountFactory.create(email="account2@example.com", status=models.Account.ACTIVE_STATUS) self.client.force_login(self.user) response = self.client.get(self.get_url(), {"email__icontains": "example"}) self.assertEqual(response.status_code, 200) @@ -3505,17 +3071,13 @@ def test_view_with_active_and_inactive_accounts(self): self.assertIn(active_object, response.context_data["table"].data) self.assertNotIn(inactive_object, response.context_data["table"].data) - @override_settings( - ANVIL_ACCOUNT_ADAPTER="anvil_consortium_manager.tests.test_app.adapters.TestAccountAdapter" - ) + @override_settings(ANVIL_ACCOUNT_ADAPTER="anvil_consortium_manager.tests.test_app.adapters.TestAccountAdapter") def test_adapter(self): """Displays the correct table if specified in the adapter.""" 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"], app_tables.TestAccountTable - ) + self.assertIsInstance(response.context_data["table"], app_tables.TestAccountTable) self.assertIsInstance(response.context_data["filter"], TestAccountListFilter) @@ -3526,9 +3088,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -3543,9 +3103,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.""" @@ -3555,9 +3113,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): @@ -3565,13 +3121,9 @@ def test_access_without_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -3590,9 +3142,7 @@ def test_filterset_class(self): self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertIn("filter", response.context_data) - self.assertIsInstance( - response.context_data["filter"], filters.AccountListFilter - ) + self.assertIsInstance(response.context_data["filter"], filters.AccountListFilter) def test_view_with_no_objects(self): self.client.force_login(self.user) @@ -3618,12 +3168,8 @@ def test_view_with_two_objects(self): self.assertEqual(len(response.context_data["table"].rows), 2) def test_view_with_filter_return_no_object(self): - factories.AccountFactory.create( - email="account1@example.com", status=models.Account.INACTIVE_STATUS - ) - factories.AccountFactory.create( - email="account2@example.com", status=models.Account.INACTIVE_STATUS - ) + factories.AccountFactory.create(email="account1@example.com", status=models.Account.INACTIVE_STATUS) + factories.AccountFactory.create(email="account2@example.com", status=models.Account.INACTIVE_STATUS) self.client.force_login(self.user) response = self.client.get(self.get_url(), {"email__icontains": "abc"}) self.assertEqual(response.status_code, 200) @@ -3631,44 +3177,28 @@ def test_view_with_filter_return_no_object(self): self.assertEqual(len(response.context_data["table"].rows), 0) def test_view_with_filter_returns_one_object_exact(self): - instance = factories.AccountFactory.create( - email="account1@example.com", status=models.Account.INACTIVE_STATUS - ) - factories.AccountFactory.create( - email="account2@example.com", status=models.Account.ACTIVE_STATUS - ) + instance = factories.AccountFactory.create(email="account1@example.com", status=models.Account.INACTIVE_STATUS) + factories.AccountFactory.create(email="account2@example.com", status=models.Account.ACTIVE_STATUS) self.client.force_login(self.user) - response = self.client.get( - self.get_url(), {"email__icontains": "account1@example.com"} - ) + response = self.client.get(self.get_url(), {"email__icontains": "account1@example.com"}) self.assertEqual(response.status_code, 200) self.assertIn("table", response.context_data) self.assertEqual(len(response.context_data["table"].rows), 1) self.assertIn(instance, response.context_data["table"].data) def test_view_with_filter_returns_one_object_case_insensitive(self): - instance = factories.AccountFactory.create( - email="account1@example.com", status=models.Account.INACTIVE_STATUS - ) - factories.AccountFactory.create( - email="account2@example.com", status=models.Account.INACTIVE_STATUS - ) + instance = factories.AccountFactory.create(email="account1@example.com", status=models.Account.INACTIVE_STATUS) + factories.AccountFactory.create(email="account2@example.com", status=models.Account.INACTIVE_STATUS) self.client.force_login(self.user) - response = self.client.get( - self.get_url(), {"email__icontains": "Account1@example.com"} - ) + response = self.client.get(self.get_url(), {"email__icontains": "Account1@example.com"}) self.assertEqual(response.status_code, 200) self.assertIn("table", response.context_data) self.assertEqual(len(response.context_data["table"].rows), 1) self.assertIn(instance, response.context_data["table"].data) def test_view_with_filter_returns_one_object_inactive_only(self): - instance = factories.AccountFactory.create( - email="account1@example.com", status=models.Account.INACTIVE_STATUS - ) - factories.AccountFactory.create( - email="account2@example.com", status=models.Account.ACTIVE_STATUS - ) + instance = factories.AccountFactory.create(email="account1@example.com", status=models.Account.INACTIVE_STATUS) + factories.AccountFactory.create(email="account2@example.com", status=models.Account.ACTIVE_STATUS) self.client.force_login(self.user) response = self.client.get(self.get_url(), {"email__icontains": "account"}) self.assertEqual(response.status_code, 200) @@ -3677,12 +3207,8 @@ def test_view_with_filter_returns_one_object_inactive_only(self): self.assertIn(instance, response.context_data["table"].data) def test_view_with_filter_returns_one_object_contains(self): - instance = factories.AccountFactory.create( - email="account1@example.com", status=models.Account.INACTIVE_STATUS - ) - factories.AccountFactory.create( - email="account2@example.com", status=models.Account.INACTIVE_STATUS - ) + instance = factories.AccountFactory.create(email="account1@example.com", status=models.Account.INACTIVE_STATUS) + factories.AccountFactory.create(email="account2@example.com", status=models.Account.INACTIVE_STATUS) self.client.force_login(self.user) response = self.client.get(self.get_url(), {"email__icontains": "account1"}) self.assertEqual(response.status_code, 200) @@ -3691,12 +3217,8 @@ def test_view_with_filter_returns_one_object_contains(self): self.assertIn(instance, response.context_data["table"].data) def test_view_with_filter_returns_all_objects(self): - factories.AccountFactory.create( - email="account1@example.com", status=models.Account.INACTIVE_STATUS - ) - factories.AccountFactory.create( - email="account2@example.com", status=models.Account.INACTIVE_STATUS - ) + factories.AccountFactory.create(email="account1@example.com", status=models.Account.INACTIVE_STATUS) + factories.AccountFactory.create(email="account2@example.com", status=models.Account.INACTIVE_STATUS) self.client.force_login(self.user) response = self.client.get(self.get_url(), {"email__icontains": "example"}) self.assertEqual(response.status_code, 200) @@ -3704,12 +3226,8 @@ def test_view_with_filter_returns_all_objects(self): self.assertEqual(len(response.context_data["table"].rows), 2) def test_view_with_service_account(self): - factories.AccountFactory.create( - status=models.Account.INACTIVE_STATUS, is_service_account=True - ) - factories.AccountFactory.create( - status=models.Account.INACTIVE_STATUS, is_service_account=False - ) + factories.AccountFactory.create(status=models.Account.INACTIVE_STATUS, is_service_account=True) + factories.AccountFactory.create(status=models.Account.INACTIVE_STATUS, is_service_account=False) self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertEqual(response.status_code, 200) @@ -3729,17 +3247,13 @@ def test_view_with_active_and_inactive_accounts(self): self.assertNotIn(active_object, response.context_data["table"].data) self.assertIn(inactive_object, response.context_data["table"].data) - @override_settings( - ANVIL_ACCOUNT_ADAPTER="anvil_consortium_manager.tests.test_app.adapters.TestAccountAdapter" - ) + @override_settings(ANVIL_ACCOUNT_ADAPTER="anvil_consortium_manager.tests.test_app.adapters.TestAccountAdapter") def test_adapter(self): """Displays the correct table if specified in the adapter.""" 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"], app_tables.TestAccountTable - ) + self.assertIsInstance(response.context_data["table"], app_tables.TestAccountTable) self.assertIsInstance(response.context_data["filter"], TestAccountListFilter) @@ -3751,14 +3265,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -3770,22 +3280,14 @@ def get_view(self): return views.AccountDelete.as_view() def get_api_remove_from_group_url(self, group_name, account_email): - return ( - self.api_client.sam_entry_point - + "/api/groups/v1/" - + group_name - + "/member/" - + account_email - ) + return self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/member/" + account_email def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." uuid = uuid4() # Need a client for redirects. response = self.client.get(self.get_url(uuid)) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(uuid) - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(uuid)) def test_status_code_with_user_permission(self): """Returns successful response code.""" @@ -3803,13 +3305,9 @@ def test_template_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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) uuid = uuid4() request = self.factory.get(self.get_url(uuid)) @@ -3819,13 +3317,9 @@ def test_access_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url(uuid4())) request.user = user @@ -3834,9 +3328,7 @@ def test_access_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") uuid = uuid4() request = self.factory.get(self.get_url(uuid)) request.user = user_no_perms @@ -3866,9 +3358,7 @@ def test_success_message(self): """Response includes a success message if successful.""" object = factories.AccountFactory.create() self.client.force_login(self.user) - response = self.client.post( - self.get_url(object.uuid), {"submit": ""}, follow=True - ) + response = self.client.post(self.get_url(object.uuid), {"submit": ""}, follow=True) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) self.assertEqual(views.AccountDelete.success_message, str(messages[0])) @@ -3901,21 +3391,15 @@ def test_success_url(self): self.client.force_login(self.user) response = self.client.post(self.get_url(object.uuid), {"submit": ""}) self.assertEqual(response.status_code, 302) - self.assertRedirects( - response, reverse("anvil_consortium_manager:accounts:list") - ) + self.assertRedirects(response, reverse("anvil_consortium_manager:accounts:list")) def test_removes_account_from_one_group(self): """Deleting an account from the app also removes it from one group.""" object = factories.AccountFactory.create() membership = factories.GroupAccountMembershipFactory.create(account=object) group = membership.group - remove_from_group_url = self.get_api_remove_from_group_url( - group.name, object.email - ) - self.anvil_response_mock.add( - responses.DELETE, remove_from_group_url, status=204 - ) + remove_from_group_url = self.get_api_remove_from_group_url(group.name, object.email) + self.anvil_response_mock.add(responses.DELETE, remove_from_group_url, status=204) self.client.force_login(self.user) response = self.client.post(self.get_url(object.uuid), {"submit": ""}) self.assertEqual(response.status_code, 302) @@ -3926,23 +3410,13 @@ def test_removes_account_from_one_group(self): def test_removes_account_from_all_groups(self): """Deleting an account from the app also removes it from all groups that it is in.""" object = factories.AccountFactory.create() - memberships = factories.GroupAccountMembershipFactory.create_batch( - 2, account=object - ) + memberships = factories.GroupAccountMembershipFactory.create_batch(2, account=object) group_1 = memberships[0].group group_2 = memberships[1].group - remove_from_group_url_1 = self.get_api_remove_from_group_url( - group_1.name, object.email - ) - self.anvil_response_mock.add( - responses.DELETE, remove_from_group_url_1, status=204 - ) - remove_from_group_url_2 = self.get_api_remove_from_group_url( - group_2.name, object.email - ) - self.anvil_response_mock.add( - responses.DELETE, remove_from_group_url_2, status=204 - ) + remove_from_group_url_1 = self.get_api_remove_from_group_url(group_1.name, object.email) + self.anvil_response_mock.add(responses.DELETE, remove_from_group_url_1, status=204) + remove_from_group_url_2 = self.get_api_remove_from_group_url(group_2.name, object.email) + self.anvil_response_mock.add(responses.DELETE, remove_from_group_url_2, status=204) self.client.force_login(self.user) response = self.client.post(self.get_url(object.uuid), {"submit": ""}) self.assertEqual(response.status_code, 302) @@ -3953,20 +3427,12 @@ def test_removes_account_from_all_groups(self): def test_api_error_when_removing_account_from_groups(self): """Message when an API error occurred when removing a user from a group.""" object = factories.AccountFactory.create() - memberships = factories.GroupAccountMembershipFactory.create_batch( - 2, account=object - ) + memberships = factories.GroupAccountMembershipFactory.create_batch(2, account=object) group_1 = memberships[0].group group_2 = memberships[1].group - remove_from_group_url_1 = self.get_api_remove_from_group_url( - group_1.name, object.email - ) - self.anvil_response_mock.add( - responses.DELETE, remove_from_group_url_1, status=204 - ) - remove_from_group_url_2 = self.get_api_remove_from_group_url( - group_2.name, object.email - ) + remove_from_group_url_1 = self.get_api_remove_from_group_url(group_1.name, object.email) + self.anvil_response_mock.add(responses.DELETE, remove_from_group_url_1, status=204) + remove_from_group_url_2 = self.get_api_remove_from_group_url(group_2.name, object.email) self.anvil_response_mock.add( responses.DELETE, remove_from_group_url_2, @@ -3975,9 +3441,7 @@ def test_api_error_when_removing_account_from_groups(self): ) # Need a client for messages. self.client.force_login(self.user) - response = self.client.post( - self.get_url(object.uuid), {"submit": ""}, follow=True - ) + response = self.client.post(self.get_url(object.uuid), {"submit": ""}, follow=True) self.assertRedirects(response, object.get_absolute_url()) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) @@ -4002,14 +3466,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -4021,22 +3481,14 @@ def get_view(self): return views.AccountDeactivate.as_view() def get_api_remove_from_group_url(self, group_name, account_email): - return ( - self.api_client.sam_entry_point - + "/api/groups/v1/" - + group_name - + "/member/" - + account_email - ) + return self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/member/" + account_email def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." # Need a client for redirects. uuid = uuid4() response = self.client.get(self.get_url(uuid)) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(uuid) - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(uuid)) def test_status_code_with_user_permission(self): """Returns successful response code.""" @@ -4054,13 +3506,9 @@ def test_template_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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) uuid = uuid4() request = self.factory.get(self.get_url(uuid)) @@ -4070,13 +3518,9 @@ def test_access_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url(uuid4())) request.user = user @@ -4085,9 +3529,7 @@ def test_access_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") uuid = uuid4() request = self.factory.get(self.get_url(uuid)) request.user = user_no_perms @@ -4130,9 +3572,7 @@ def test_success_message(self): """Response includes a success message if successful.""" object = factories.AccountFactory.create() self.client.force_login(self.user) - response = self.client.post( - self.get_url(object.uuid), {"submit": ""}, follow=True - ) + response = self.client.post(self.get_url(object.uuid), {"submit": ""}, follow=True) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) self.assertEqual(views.AccountDeactivate.success_message, str(messages[0])) @@ -4175,12 +3615,8 @@ def test_removes_account_from_one_group(self): object = factories.AccountFactory.create() membership = factories.GroupAccountMembershipFactory.create(account=object) group = membership.group - remove_from_group_url = self.get_api_remove_from_group_url( - group.name, object.email - ) - self.anvil_response_mock.add( - responses.DELETE, remove_from_group_url, status=204 - ) + remove_from_group_url = self.get_api_remove_from_group_url(group.name, object.email) + self.anvil_response_mock.add(responses.DELETE, remove_from_group_url, status=204) self.client.force_login(self.user) response = self.client.post(self.get_url(object.uuid), {"submit": ""}) self.assertEqual(response.status_code, 302) @@ -4192,23 +3628,13 @@ def test_removes_account_from_one_group(self): def test_removes_account_from_all_groups(self): """Deactivating an account from the app also removes it from all groups that it is in.""" object = factories.AccountFactory.create() - memberships = factories.GroupAccountMembershipFactory.create_batch( - 2, account=object - ) + memberships = factories.GroupAccountMembershipFactory.create_batch(2, account=object) group_1 = memberships[0].group group_2 = memberships[1].group - remove_from_group_url_1 = self.get_api_remove_from_group_url( - group_1.name, object.email - ) - self.anvil_response_mock.add( - responses.DELETE, remove_from_group_url_1, status=204 - ) - remove_from_group_url_2 = self.get_api_remove_from_group_url( - group_2.name, object.email - ) - self.anvil_response_mock.add( - responses.DELETE, remove_from_group_url_2, status=204 - ) + remove_from_group_url_1 = self.get_api_remove_from_group_url(group_1.name, object.email) + self.anvil_response_mock.add(responses.DELETE, remove_from_group_url_1, status=204) + remove_from_group_url_2 = self.get_api_remove_from_group_url(group_2.name, object.email) + self.anvil_response_mock.add(responses.DELETE, remove_from_group_url_2, status=204) self.client.force_login(self.user) response = self.client.post(self.get_url(object.uuid), {"submit": ""}) self.assertEqual(response.status_code, 302) @@ -4221,20 +3647,12 @@ def test_removes_account_from_all_groups(self): def test_api_error_when_removing_account_from_groups(self): """Message when an API error occurred when removing a user from a group.""" object = factories.AccountFactory.create() - memberships = factories.GroupAccountMembershipFactory.create_batch( - 2, account=object - ) + memberships = factories.GroupAccountMembershipFactory.create_batch(2, account=object) group_1 = memberships[0].group group_2 = memberships[1].group - remove_from_group_url_1 = self.get_api_remove_from_group_url( - group_1.name, object.email - ) - self.anvil_response_mock.add( - responses.DELETE, remove_from_group_url_1, status=204 - ) - remove_from_group_url_2 = self.get_api_remove_from_group_url( - group_2.name, object.email - ) + remove_from_group_url_1 = self.get_api_remove_from_group_url(group_1.name, object.email) + self.anvil_response_mock.add(responses.DELETE, remove_from_group_url_1, status=204) + remove_from_group_url_2 = self.get_api_remove_from_group_url(group_2.name, object.email) self.anvil_response_mock.add( responses.DELETE, remove_from_group_url_2, @@ -4243,16 +3661,12 @@ def test_api_error_when_removing_account_from_groups(self): ) # Need a client for messages. self.client.force_login(self.user) - response = self.client.post( - self.get_url(object.uuid), {"submit": ""}, follow=True - ) + response = self.client.post(self.get_url(object.uuid), {"submit": ""}, follow=True) self.assertRedirects(response, object.get_absolute_url()) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) self.assertEqual( - views.AccountDeactivate.message_error_removing_from_groups.format( - "test error" - ), + views.AccountDeactivate.message_error_removing_from_groups.format("test error"), str(messages[0]), ) # The Account is not marked as inactive. @@ -4281,9 +3695,7 @@ def test_account_already_inactive_get(self): # A message is shown. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.AccountDeactivate.message_already_inactive, str(messages[0]) - ) + self.assertEqual(views.AccountDeactivate.message_already_inactive, str(messages[0])) def test_account_already_inactive_post(self): """Redirects with a message if account is already deactivated.""" @@ -4293,9 +3705,7 @@ def test_account_already_inactive_post(self): object.save() # No API calls are made. self.client.force_login(self.user) - response = self.client.post( - self.get_url(object.uuid), {"submit": ""}, follow=True - ) + response = self.client.post(self.get_url(object.uuid), {"submit": ""}, follow=True) self.assertRedirects(response, object.get_absolute_url()) # The object is unchanged. object.refresh_from_db() @@ -4305,9 +3715,7 @@ def test_account_already_inactive_post(self): # A message is shown. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.AccountDeactivate.message_already_inactive, str(messages[0]) - ) + self.assertEqual(views.AccountDeactivate.message_already_inactive, str(messages[0])) class AccountReactivateTest(AnVILAPIMockTestMixin, TestCase): @@ -4318,14 +3726,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -4337,22 +3741,14 @@ def get_view(self): return views.AccountReactivate.as_view() def get_api_add_to_group_url(self, group_name, account_email): - return ( - self.api_client.sam_entry_point - + "/api/groups/v1/" - + group_name - + "/member/" - + account_email - ) + return self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/member/" + account_email def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." # Need a client for redirects. uuid = uuid4() response = self.client.get(self.get_url(uuid)) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(uuid) - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(uuid)) def test_status_code_with_user_permission(self): """Returns successful response code.""" @@ -4374,13 +3770,9 @@ def test_template_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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) uuid = uuid4() request = self.factory.get(self.get_url(uuid)) @@ -4390,13 +3782,9 @@ def test_access_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url(uuid4())) request.user = user @@ -4405,9 +3793,7 @@ def test_access_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") uuid = uuid4() request = self.factory.get(self.get_url(uuid)) request.user = user_no_perms @@ -4455,9 +3841,7 @@ def test_success_message(self): object.status = object.INACTIVE_STATUS object.save() self.client.force_login(self.user) - response = self.client.post( - self.get_url(object.uuid), {"submit": ""}, follow=True - ) + response = self.client.post(self.get_url(object.uuid), {"submit": ""}, follow=True) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) self.assertEqual(views.AccountReactivate.success_message, str(messages[0])) @@ -4520,9 +3904,7 @@ def test_adds_account_from_one_group(self): def test_adds_account_to_all_groups(self): """Reactivating an account from the app also adds it from all groups that it is in.""" object = factories.AccountFactory.create() - memberships = factories.GroupAccountMembershipFactory.create_batch( - 2, account=object - ) + memberships = factories.GroupAccountMembershipFactory.create_batch(2, account=object) object.status = object.INACTIVE_STATUS object.save() group_1 = memberships[0].group @@ -4541,9 +3923,7 @@ def test_adds_account_to_all_groups(self): def test_api_error_when_adding_account_to_groups(self): """Message when an API error occurred when adding a user to a group.""" object = factories.AccountFactory.create() - memberships = factories.GroupAccountMembershipFactory.create_batch( - 2, account=object - ) + memberships = factories.GroupAccountMembershipFactory.create_batch(2, account=object) object.status = object.INACTIVE_STATUS object.save() group_1 = memberships[0].group @@ -4559,9 +3939,7 @@ def test_api_error_when_adding_account_to_groups(self): ) # Need a client for messages. self.client.force_login(self.user) - response = self.client.post( - self.get_url(object.uuid), {"submit": ""}, follow=True - ) + response = self.client.post(self.get_url(object.uuid), {"submit": ""}, follow=True) self.assertRedirects(response, object.get_absolute_url()) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) @@ -4591,9 +3969,7 @@ def test_account_already_active_get(self): # A message is shown. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.AccountReactivate.message_already_active, str(messages[0]) - ) + self.assertEqual(views.AccountReactivate.message_already_active, str(messages[0])) def test_account_already_active_post(self): """Redirects with a message if account is already deactivated.""" @@ -4601,9 +3977,7 @@ def test_account_already_active_post(self): factories.GroupAccountMembershipFactory.create_batch(2, account=object) # No API calls are made. self.client.force_login(self.user) - response = self.client.post( - self.get_url(object.uuid), {"submit": ""}, follow=True - ) + response = self.client.post(self.get_url(object.uuid), {"submit": ""}, follow=True) self.assertRedirects(response, object.get_absolute_url()) # The object is unchanged. object.refresh_from_db() @@ -4613,9 +3987,7 @@ def test_account_already_active_post(self): # A message is shown. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.AccountReactivate.message_already_active, str(messages[0]) - ) + self.assertEqual(views.AccountReactivate.message_already_active, str(messages[0])) class AccountAutocompleteTest(TestCase): @@ -4625,9 +3997,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -4642,9 +4012,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.""" @@ -4654,13 +4022,9 @@ def test_status_code_with_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -4669,9 +4033,7 @@ def test_access_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): @@ -4682,10 +4044,7 @@ def test_returns_all_objects(self): groups = factories.AccountFactory.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([group.pk for group in groups])) @@ -4694,10 +4053,7 @@ def test_returns_correct_object_match(self): account = factories.AccountFactory.create(email="test@foo.com") self.client.force_login(self.user) response = self.client.get(self.get_url(), {"q": "test@foo.com"}) - 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], account.pk) @@ -4706,10 +4062,7 @@ def test_returns_correct_object_starting_with_query(self): account = factories.AccountFactory.create(email="test@foo.com") self.client.force_login(self.user) response = self.client.get(self.get_url(), {"q": "tes"}) - 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], account.pk) @@ -4718,10 +4071,7 @@ def test_returns_correct_object_containing_query(self): account = factories.AccountFactory.create(email="test@foo.com") self.client.force_login(self.user) response = self.client.get(self.get_url(), {"q": "foo"}) - 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], account.pk) @@ -4730,46 +4080,31 @@ def test_returns_correct_object_case_insensitive(self): account = factories.AccountFactory.create(email="test@foo.com") self.client.force_login(self.user) response = self.client.get(self.get_url(), {"q": "TEST@FOO.COM"}) - 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], account.pk) def test_does_not_return_inactive_accounts(self): """Queryset does not return accounts that are inactive.""" - factories.AccountFactory.create( - email="test@foo.com", status=models.Account.INACTIVE_STATUS - ) + factories.AccountFactory.create(email="test@foo.com", status=models.Account.INACTIVE_STATUS) self.client.force_login(self.user) response = self.client.get(self.get_url(), {"q": "test@foo.com"}) - 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), 0) - @override_settings( - ANVIL_ACCOUNT_ADAPTER="anvil_consortium_manager.tests.test_app.adapters.TestAccountAdapter" - ) + @override_settings(ANVIL_ACCOUNT_ADAPTER="anvil_consortium_manager.tests.test_app.adapters.TestAccountAdapter") def test_adapter_queryset(self): """Filters queryset correctly if custom get_autocomplete_queryset is set in adapter.""" account_1 = factories.AccountFactory.create(email="test@bar.com") account_2 = factories.AccountFactory.create(email="foo@test.com") self.client.force_login(self.user) response = self.client.get(self.get_url(), {"q": "test"}) - 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.assertIn(account_1.pk, returned_ids) self.assertNotIn(account_2.pk, returned_ids) - @override_settings( - ANVIL_ACCOUNT_ADAPTER="anvil_consortium_manager.tests.test_app.adapters.TestAccountAdapter" - ) + @override_settings(ANVIL_ACCOUNT_ADAPTER="anvil_consortium_manager.tests.test_app.adapters.TestAccountAdapter") def test_adapter_labels(self): """Test view labels.""" account = factories.AccountFactory.create(email="test@bar.com") @@ -4792,9 +4127,7 @@ def setUp(self): # Create a user with only view permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -4820,9 +4153,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.""" @@ -4832,13 +4163,9 @@ def test_status_code_with_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -4847,9 +4174,7 @@ def test_access_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): @@ -4866,9 +4191,7 @@ def test_audit_verified(self): self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertIn("verified_table", response.context_data) - self.assertIsInstance( - response.context_data["verified_table"], audit.VerifiedTable - ) + self.assertIsInstance(response.context_data["verified_table"], audit.VerifiedTable) self.assertEqual(len(response.context_data["verified_table"].rows), 0) def test_audit_verified_one_verified(self): @@ -4954,9 +4277,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -4971,9 +4292,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("foo")) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url("foo") - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url("foo")) def test_status_code_with_user_permission(self): """Returns successful response code.""" @@ -4984,13 +4303,9 @@ def test_status_code_with_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo")) request.user = user @@ -4999,9 +4314,7 @@ def test_access_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("foo")) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -5029,9 +4342,7 @@ def test_workspace_table(self): self.client.force_login(self.user) response = self.client.get(self.get_url(obj.name)) self.assertIn("workspace_table", response.context_data) - self.assertIsInstance( - response.context_data["workspace_table"], tables.WorkspaceGroupSharingTable - ) + self.assertIsInstance(response.context_data["workspace_table"], tables.WorkspaceGroupSharingTable) def test_workspace_table_none(self): """No workspaces are shown if the group does not have access to any workspaces.""" @@ -5122,9 +4433,7 @@ def test_group_table(self): self.client.force_login(self.user) response = self.client.get(self.get_url(obj.name)) self.assertIn("group_table", response.context_data) - self.assertIsInstance( - response.context_data["group_table"], tables.GroupGroupMembershipTable - ) + self.assertIsInstance(response.context_data["group_table"], tables.GroupGroupMembershipTable) def test_group_table_none(self): """No groups are shown if the group has no member groups.""" @@ -5167,9 +4476,7 @@ def test_group_table_show_only_direct_members(self): parent = factories.ManagedGroupFactory.create() child = factories.ManagedGroupFactory.create() grandchild = factories.ManagedGroupFactory.create() - parent_child_membership = factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + parent_child_membership = factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) child_grandchild_membership = factories.GroupGroupMembershipFactory.create( parent_group=child, child_group=grandchild ) @@ -5177,12 +4484,8 @@ def test_group_table_show_only_direct_members(self): response = self.client.get(self.get_url(parent.name)) self.assertIn("group_table", response.context_data) self.assertEqual(len(response.context_data["group_table"].rows), 1) - self.assertIn( - parent_child_membership, response.context_data["group_table"].data - ) - self.assertNotIn( - child_grandchild_membership, response.context_data["group_table"].data - ) + self.assertIn(parent_child_membership, response.context_data["group_table"].data) + self.assertNotIn(child_grandchild_membership, response.context_data["group_table"].data) def test_workspace_auth_domain_table(self): """The auth_domain table exists.""" @@ -5201,9 +4504,7 @@ def test_workspace_auth_domain_table_none(self): self.client.force_login(self.user) response = self.client.get(self.get_url(group.name)) self.assertIn("workspace_authorization_domain_table", response.context_data) - self.assertEqual( - len(response.context_data["workspace_authorization_domain_table"].rows), 0 - ) + self.assertEqual(len(response.context_data["workspace_authorization_domain_table"].rows), 0) def test_workspace_auth_domain_table_one(self): """One workspace is shown in if the group is the auth domain for it.""" @@ -5242,9 +4543,7 @@ def test_workspace_auth_domain_account_for_only_this_group(self): self.client.force_login(self.user) response = self.client.get(self.get_url(group.name)) self.assertIn("workspace_authorization_domain_table", response.context_data) - self.assertEqual( - len(response.context_data["workspace_authorization_domain_table"].rows), 0 - ) + self.assertEqual(len(response.context_data["workspace_authorization_domain_table"].rows), 0) def test_parent_table(self): """The parent table exists.""" @@ -5252,9 +4551,7 @@ def test_parent_table(self): self.client.force_login(self.user) response = self.client.get(self.get_url(obj.name)) self.assertIn("parent_table", response.context_data) - self.assertIsInstance( - response.context_data["parent_table"], tables.GroupGroupMembershipTable - ) + self.assertIsInstance(response.context_data["parent_table"], tables.GroupGroupMembershipTable) def test_parent_table_none(self): """No groups are shown if the group is not a part of any other groups.""" @@ -5290,30 +4587,20 @@ def test_parent_table_shows_only_direct_parents(self): grandparent_parent_membership = factories.GroupGroupMembershipFactory.create( parent_group=grandparent, child_group=parent ) - parent_child_membership = factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + parent_child_membership = factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) self.client.force_login(self.user) response = self.client.get(self.get_url(child.name)) self.assertIn("parent_table", response.context_data) self.assertEqual(len(response.context_data["parent_table"].rows), 1) - self.assertIn( - parent_child_membership, response.context_data["parent_table"].data - ) - self.assertNotIn( - grandparent_parent_membership, response.context_data["parent_table"].data - ) + self.assertIn(parent_child_membership, response.context_data["parent_table"].data) + self.assertNotIn(grandparent_parent_membership, response.context_data["parent_table"].data) def test_edit_permission(self): """Links to reactivate/deactivate/delete pages appear if the user has edit permission.""" edit_user = User.objects.create_user(username="edit", password="test") edit_user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ), - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ), + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME), + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME), ) self.client.force_login(edit_user) obj = factories.ManagedGroupFactory.create() @@ -5332,9 +4619,7 @@ def test_view_permission(self): """Links to reactivate/deactivate/delete pages appear if the user has edit permission.""" view_user = User.objects.create_user(username="view", password="test") view_user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ), + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME), ) self.client.force_login(view_user) obj = factories.ManagedGroupFactory.create() @@ -5353,9 +4638,7 @@ def test_group_visualization(self): factories.ManagedGroupFactory.create() group = factories.ManagedGroupFactory.create() child = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - parent_group=group, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=group, child_group=child) self.client.force_login(self.user) response = self.client.get(self.get_url(group.name)) self.assertIn("graph", response.context_data) @@ -5373,14 +4656,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -5397,10 +4676,8 @@ def get_api_url(self, group_name): 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() - ) + response = self.client.get(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.""" @@ -5410,13 +4687,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user_with_view_perm @@ -5425,13 +4698,9 @@ def test_access_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -5440,9 +4709,7 @@ def test_access_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): @@ -5453,16 +4720,12 @@ def test_has_form_in_context(self): self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertTrue("form" in response.context_data) - self.assertIsInstance( - response.context_data["form"], forms.ManagedGroupCreateForm - ) + self.assertIsInstance(response.context_data["form"], forms.ManagedGroupCreateForm) def test_can_create_an_object(self): """Posting valid data to the form creates an object.""" api_url = self.get_api_url("test-group") - self.anvil_response_mock.add( - responses.POST, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.POST, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post(self.get_url(), {"name": "test-group"}) self.assertEqual(response.status_code, 302) @@ -5477,13 +4740,9 @@ def test_can_create_an_object(self): def test_can_create_an_object_with_note(self): """Posting valid data including note to the form creates an object.""" api_url = self.get_api_url("test-group") - self.anvil_response_mock.add( - responses.POST, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.POST, api_url, status=self.api_success_code) self.client.force_login(self.user) - response = self.client.post( - self.get_url(), {"name": "test-group", "note": "test note"} - ) + response = self.client.post(self.get_url(), {"name": "test-group", "note": "test note"}) self.assertEqual(response.status_code, 302) new_object = models.ManagedGroup.objects.latest("pk") self.assertIsInstance(new_object, models.ManagedGroup) @@ -5492,9 +4751,7 @@ def test_can_create_an_object_with_note(self): def test_success_message(self): """Response includes a success message if successful.""" api_url = self.get_api_url("test-group") - self.anvil_response_mock.add( - responses.POST, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.POST, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post(self.get_url(), {"name": "test-group"}, follow=True) messages = [m.message for m in get_messages(response.wsgi_request)] @@ -5505,9 +4762,7 @@ def test_redirects_to_new_object_detail(self): """After successfully creating an object, view redirects to the object's detail page.""" # This needs to use the client because the RequestFactory doesn't handle redirects. api_url = self.get_api_url("test-group") - self.anvil_response_mock.add( - responses.POST, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.POST, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post(self.get_url(), {"name": "test-group"}) new_object = models.ManagedGroup.objects.latest("pk") @@ -5591,9 +4846,7 @@ def test_api_error_message(self): def test_api_group_already_exists(self): api_url = self.get_api_url("test-group") - self.anvil_response_mock.add( - responses.POST, api_url, status=409, json={"message": "other error"} - ) + self.anvil_response_mock.add(responses.POST, api_url, status=409, json={"message": "other error"}) # Need a client to check messages. self.client.force_login(self.user) response = self.client.post(self.get_url(), {"name": "test-group"}) @@ -5614,14 +4867,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -5636,9 +4885,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("foo")) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url("foo") - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url("foo")) def test_status_code_with_user_permission(self): """Returns successful response code.""" @@ -5649,13 +4896,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo")) request.user = user_with_view_perm @@ -5664,13 +4907,9 @@ def test_access_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo")) request.user = user @@ -5679,9 +4918,7 @@ def test_access_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("foo")) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -5700,9 +4937,7 @@ def test_has_form_in_context(self): self.client.force_login(self.user) response = self.client.get(self.get_url(instance.name)) self.assertTrue("form" in response.context_data) - self.assertIsInstance( - response.context_data["form"], forms.ManagedGroupUpdateForm - ) + self.assertIsInstance(response.context_data["form"], forms.ManagedGroupUpdateForm) def test_can_modify_note(self): """Can set the note when creating a billing project.""" @@ -5739,9 +4974,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -5756,9 +4989,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.""" @@ -5768,13 +4999,9 @@ def test_status_code_with_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -5783,9 +5010,7 @@ def test_access_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): @@ -5881,14 +5106,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -5907,9 +5128,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.""" @@ -5920,13 +5139,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url(1)) request.user = user_with_view_perm @@ -5935,13 +5150,9 @@ def test_access_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo")) request.user = user @@ -5950,9 +5161,7 @@ def test_access_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(1)) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -5969,9 +5178,7 @@ def test_view_deletes_object(self): """Posting submit to the form successfully deletes the object.""" object = factories.ManagedGroupFactory.create(name="test-group") api_url = self.get_api_url(object.name) - self.anvil_response_mock.add( - responses.DELETE, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.DELETE, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post(self.get_url(object.name), {"submit": ""}) self.assertEqual(response.status_code, 302) @@ -5984,13 +5191,9 @@ def test_success_message(self): """Response includes a success message if successful.""" object = factories.ManagedGroupFactory.create(name="test-group") api_url = self.get_api_url(object.name) - self.anvil_response_mock.add( - responses.DELETE, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.DELETE, api_url, status=self.api_success_code) self.client.force_login(self.user) - response = self.client.post( - self.get_url(object.name), {"submit": ""}, follow=True - ) + response = self.client.post(self.get_url(object.name), {"submit": ""}, follow=True) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) self.assertEqual(views.ManagedGroupDelete.success_message, str(messages[0])) @@ -6000,9 +5203,7 @@ def test_only_deletes_specified_pk(self): object = factories.ManagedGroupFactory.create() other_object = factories.ManagedGroupFactory.create() api_url = self.get_api_url(object.name) - self.anvil_response_mock.add( - responses.DELETE, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.DELETE, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post(self.get_url(object.name), {"submit": ""}) self.assertEqual(response.status_code, 302) @@ -6016,16 +5217,12 @@ def test_success_url(self): """Redirects to the expected page.""" object = factories.ManagedGroupFactory.create() api_url = self.get_api_url(object.name) - self.anvil_response_mock.add( - responses.DELETE, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.DELETE, api_url, status=self.api_success_code) # Need to use the client instead of RequestFactory to check redirection url. self.client.force_login(self.user) response = self.client.post(self.get_url(object.name), {"submit": ""}) self.assertEqual(response.status_code, 302) - self.assertRedirects( - response, reverse("anvil_consortium_manager:managed_groups:list") - ) + self.assertRedirects(response, reverse("anvil_consortium_manager:managed_groups:list")) def test_get_redirect_group_is_a_member_of_another_group(self): """Redirect get request when trying to delete a group that is a member of another group. @@ -6033,9 +5230,7 @@ def test_get_redirect_group_is_a_member_of_another_group(self): This is a behavior enforced by AnVIL.""" parent = factories.ManagedGroupFactory.create() child = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) # Need to use a client for messages. self.client.force_login(self.user) response = self.client.get(self.get_url(child.name), follow=True) @@ -6060,9 +5255,7 @@ def test_post_redirect_group_is_a_member_of_another_group(self): This is a behavior enforced by AnVIL.""" parent = factories.ManagedGroupFactory.create() child = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) # Need to use a client for messages. self.client.force_login(self.user) response = self.client.post(self.get_url(child.name), follow=True) @@ -6093,9 +5286,7 @@ def test_get_redirect_group_used_as_auth_domain(self): # Check for messages. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.ManagedGroupDelete.message_is_auth_domain, str(messages[0]) - ) + self.assertEqual(views.ManagedGroupDelete.message_is_auth_domain, str(messages[0])) # Make sure that the object still exists. self.assertEqual(models.ManagedGroup.objects.count(), 1) @@ -6111,9 +5302,7 @@ def test_post_redirect_group_used_as_auth_domain(self): # Check for messages. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.ManagedGroupDelete.message_is_auth_domain, str(messages[0]) - ) + self.assertEqual(views.ManagedGroupDelete.message_is_auth_domain, str(messages[0])) # Make sure that the object still exists. self.assertEqual(models.ManagedGroup.objects.count(), 1) @@ -6123,9 +5312,7 @@ def test_get_redirect_group_has_access_to_workspace(self): This is a behavior enforced by AnVIL.""" group = factories.ManagedGroupFactory.create() workspace = factories.WorkspaceFactory.create() - access = factories.WorkspaceGroupSharingFactory.create( - workspace=workspace, group=group - ) + access = factories.WorkspaceGroupSharingFactory.create(workspace=workspace, group=group) # Need to use a client for messages. self.client.force_login(self.user) response = self.client.get(self.get_url(group.name), follow=True) @@ -6150,9 +5337,7 @@ def test_post_redirect_group_has_access_to_workspace(self): This is a behavior enforced by AnVIL.""" group = factories.ManagedGroupFactory.create() workspace = factories.WorkspaceFactory.create() - access = factories.WorkspaceGroupSharingFactory.create( - workspace=workspace, group=group - ) + access = factories.WorkspaceGroupSharingFactory.create(workspace=workspace, group=group) # Need to use a client for messages. self.client.force_login(self.user) response = self.client.post(self.get_url(group.name), follow=True) @@ -6175,13 +5360,9 @@ def test_can_delete_group_that_has_child_groups(self): """Can delete a group that has other groups as members.""" parent = factories.ManagedGroupFactory.create() child = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) api_url = self.get_api_url(parent.name) - self.anvil_response_mock.add( - responses.DELETE, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.DELETE, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post(self.get_url(parent.name), {"submit": ""}) self.assertEqual(response.status_code, 302) @@ -6203,9 +5384,7 @@ def test_can_delete_group_if_it_has_account_members(self): account = factories.AccountFactory.create() factories.GroupAccountMembershipFactory.create(group=group, account=account) api_url = self.get_api_url(group.name) - self.anvil_response_mock.add( - responses.DELETE, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.DELETE, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post(self.get_url(group.name), {"submit": ""}) self.assertEqual(response.status_code, 302) @@ -6217,9 +5396,7 @@ def test_can_delete_group_if_it_has_account_members(self): models.Account.objects.get(pk=account.pk) # History is added for GroupAccountMemberships. self.assertEqual(models.GroupAccountMembership.history.count(), 2) - self.assertEqual( - models.GroupAccountMembership.history.latest().history_type, "-" - ) + self.assertEqual(models.GroupAccountMembership.history.latest().history_type, "-") def test_api_error(self): """Shows a message if an AnVIL API error occurs.""" @@ -6251,9 +5428,7 @@ def test_get_redirect_group_not_managed_by_app(self): # Check for messages. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.ManagedGroupDelete.message_not_managed_by_app, str(messages[0]) - ) + self.assertEqual(views.ManagedGroupDelete.message_not_managed_by_app, str(messages[0])) # Make sure that the object still exists. self.assertEqual(models.ManagedGroup.objects.count(), 1) @@ -6267,32 +5442,24 @@ def test_post_redirect_group_not_managed_by_app(self): # Check for messages. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.ManagedGroupDelete.message_not_managed_by_app, str(messages[0]) - ) + self.assertEqual(views.ManagedGroupDelete.message_not_managed_by_app, str(messages[0])) # Make sure that the object still exists. self.assertEqual(models.ManagedGroup.objects.count(), 1) @skip("AnVIL API issue - covered by model fields") def test_api_not_admin_of_group(self): - self.fail( - "AnVIL API returns 204 instead of 403 when trying to delete a group you are not an admin of." - ) + self.fail("AnVIL API returns 204 instead of 403 when trying to delete a group you are not an admin of.") @skip("AnVIL API issue - covered by model fields") def test_api_group_does_not_exist(self): - self.fail( - "AnVIL API returns 204 instead of 404 when trying to delete a group that doesn't exist." - ) + self.fail("AnVIL API returns 204 instead of 404 when trying to delete a group that doesn't exist.") def test_post_does_not_delete_when_protected_fk_to_another_model(self): """Group is not deleted when there is another model referencing the group with a protected foreing key.""" object = factories.ManagedGroupFactory.create(name="test-group") app_models.ProtectedManagedGroup.objects.create(group=object) self.client.force_login(self.user) - response = self.client.post( - self.get_url(object.name), {"submit": ""}, follow=True - ) + response = self.client.post(self.get_url(object.name), {"submit": ""}, follow=True) self.assertRedirects(response, object.get_absolute_url()) # A message is added. messages = list(response.context["messages"]) @@ -6313,16 +5480,12 @@ 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): """Get the url for the view being tested.""" - return reverse( - "anvil_consortium_manager:managed_groups:autocomplete", args=args - ) + return reverse("anvil_consortium_manager:managed_groups:autocomplete", args=args) def get_view(self): """Return the view being tested.""" @@ -6332,9 +5495,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.""" @@ -6344,13 +5505,9 @@ def test_status_code_with_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -6359,9 +5516,7 @@ def test_access_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): @@ -6372,10 +5527,7 @@ def test_returns_all_objects(self): groups = factories.ManagedGroupFactory.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([group.pk for group in groups])) @@ -6384,10 +5536,7 @@ def test_returns_correct_object_match(self): group = factories.ManagedGroupFactory.create(name="test-group") self.client.force_login(self.user) response = self.client.get(self.get_url(), {"q": "test-group"}) - 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], group.pk) @@ -6396,10 +5545,7 @@ def test_returns_correct_object_starting_with_query(self): group = factories.ManagedGroupFactory.create(name="test-group") self.client.force_login(self.user) response = self.client.get(self.get_url(), {"q": "test"}) - 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], group.pk) @@ -6408,10 +5554,7 @@ def test_returns_correct_object_containing_query(self): group = factories.ManagedGroupFactory.create(name="test-group") self.client.force_login(self.user) response = self.client.get(self.get_url(), {"q": "grou"}) - 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], group.pk) @@ -6420,24 +5563,16 @@ def test_returns_correct_object_case_insensitive(self): group = factories.ManagedGroupFactory.create(name="TEST-GROUP") self.client.force_login(self.user) response = self.client.get(self.get_url(), {"q": "test"}) - 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], group.pk) def test_returns_groups_not_managed_by_app_by_default(self): """Queryset does return groups that are not managed by the app by default.""" - object = factories.ManagedGroupFactory.create( - name="test-group", is_managed_by_app=False - ) + object = factories.ManagedGroupFactory.create(name="test-group", is_managed_by_app=False) 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), 1) self.assertEqual(returned_ids[0], object.pk) @@ -6462,9 +5597,7 @@ def setUp(self): # Create a user with only view permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -6486,21 +5619,15 @@ def get_api_group_json(self, group_name, role): def get_api_url_members(self, group_name): """Return the API url being called by the method.""" - return ( - self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/member" - ) + return self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/member" def get_api_url_admins(self, group_name): """Return the API url being called by the method.""" - return ( - self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/admin" - ) + return self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/admin" def get_api_json_response_admins(self, emails=[]): """Return json data about groups in the API format.""" - return [ - anvil_api.AnVILAPIClient().auth_session.credentials.service_account_email - ] + emails + return [anvil_api.AnVILAPIClient().auth_session.credentials.service_account_email] + emails def get_api_json_response_members(self, emails=[]): """Return json data about groups in the API format.""" @@ -6514,9 +5641,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.""" @@ -6533,13 +5658,9 @@ def test_status_code_with_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -6548,9 +5669,7 @@ def test_access_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): @@ -6581,9 +5700,7 @@ def test_audit_verified(self): self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertIn("verified_table", response.context_data) - self.assertIsInstance( - response.context_data["verified_table"], audit.VerifiedTable - ) + self.assertIsInstance(response.context_data["verified_table"], audit.VerifiedTable) self.assertEqual(len(response.context_data["verified_table"].rows), 0) def test_audit_verified_one_record(self): @@ -6659,9 +5776,7 @@ def test_audit_not_in_app(self): self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertIn("not_in_app_table", response.context_data) - self.assertIsInstance( - response.context_data["not_in_app_table"], audit.NotInAppTable - ) + self.assertIsInstance(response.context_data["not_in_app_table"], audit.NotInAppTable) self.assertEqual(len(response.context_data["not_in_app_table"].rows), 0) def test_audit_not_in_app_one_record(self): @@ -6735,35 +5850,25 @@ 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.group = factories.ManagedGroupFactory.create() def get_url(self, *args): """Get the url for the view being tested.""" - return reverse( - "anvil_consortium_manager:managed_groups:audit_membership", args=args - ) + return reverse("anvil_consortium_manager:managed_groups:audit_membership", args=args) def get_api_url_members(self, group_name): """Return the API url being called by the method.""" - return ( - self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/member" - ) + return self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/member" def get_api_url_admins(self, group_name): """Return the API url being called by the method.""" - return ( - self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/admin" - ) + return self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/admin" def get_api_json_response_admins(self, emails=[]): """Return json data about groups in the API format.""" - return [ - anvil_api.AnVILAPIClient().auth_session.credentials.service_account_email - ] + emails + return [anvil_api.AnVILAPIClient().auth_session.credentials.service_account_email] + emails def get_api_json_response_members(self, emails=[]): """Return json data about groups in the API format.""" @@ -6777,9 +5882,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("foo")) - self.assertRedirects( - response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url("foo") - ) + self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url("foo")) def test_status_code_with_user_permission(self): """Returns successful response code.""" @@ -6803,13 +5906,9 @@ def test_status_code_with_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo")) request.user = user @@ -6818,9 +5917,7 @@ def test_access_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("foo")) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -6865,9 +5962,7 @@ def test_audit_verified(self): self.client.force_login(self.user) response = self.client.get(self.get_url(self.group.name)) self.assertIn("verified_table", response.context_data) - self.assertIsInstance( - response.context_data["verified_table"], audit.VerifiedTable - ) + self.assertIsInstance(response.context_data["verified_table"], audit.VerifiedTable) self.assertEqual(len(response.context_data["verified_table"].rows), 0) def test_audit_verified_one_record(self): @@ -6956,9 +6051,7 @@ def test_audit_not_in_app(self): self.client.force_login(self.user) response = self.client.get(self.get_url(self.group.name)) self.assertIn("not_in_app_table", response.context_data) - self.assertIsInstance( - response.context_data["not_in_app_table"], audit.NotInAppTable - ) + self.assertIsInstance(response.context_data["not_in_app_table"], audit.NotInAppTable) self.assertEqual(len(response.context_data["not_in_app_table"].rows), 0) def test_audit_not_in_app_one_record(self): @@ -7054,24 +6147,18 @@ 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): """Get the url for the view being tested.""" - return reverse( - "anvil_consortium_manager:managed_groups:visualization", args=args - ) + return reverse("anvil_consortium_manager:managed_groups:visualization", args=args) 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.""" @@ -7081,13 +6168,9 @@ def test_status_code_with_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -7126,12 +6209,8 @@ def test_group_visualization(self): parent_1 = factories.ManagedGroupFactory.create() parent_2 = factories.ManagedGroupFactory.create() child = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent, child_group=parent_1 - ) - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent, child_group=parent_2 - ) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent, child_group=parent_1) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent, child_group=parent_2) factories.GroupGroupMembershipFactory.create( parent_group=parent_1, child_group=child, @@ -7149,19 +6228,13 @@ def setUp(self): # Create a user with view permission. self.view_user = User.objects.create_user(username="test_view", password="view") self.view_user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) # Create a user with edit permission. self.edit_user = User.objects.create_user(username="test_edit", password="test") self.edit_user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ), - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ), + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME), + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME), ) def tearDown(self): @@ -7193,13 +6266,9 @@ def test_status_code_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -7293,9 +6362,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def tearDown(self): @@ -7317,9 +6384,7 @@ def get_url(self, *args): def test_view_redirect_not_logged_in(self): "View redirects to login view when user is not logged in." # Need a client for redirects. - url = reverse( - "anvil_consortium_manager:workspaces:detail", args=["foo1", "foo2"] - ) + url = reverse("anvil_consortium_manager:workspaces:detail", args=["foo1", "foo2"]) response = self.client.get(url) self.assertRedirects(response, resolve_url(settings.LOGIN_URL) + "?next=" + url) @@ -7332,13 +6397,9 @@ def test_status_code_with_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo", "bar")) request.user = user @@ -7347,9 +6408,7 @@ def test_access_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("foo", "bar")) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -7403,9 +6462,7 @@ def test_group_sharing_table_one(self): def test_group_sharing_table_two(self): """Two groups are shown if the workspace has been shared with two groups.""" workspace = factories.DefaultWorkspaceDataFactory.create() - factories.WorkspaceGroupSharingFactory.create_batch( - 2, workspace=workspace.workspace - ) + factories.WorkspaceGroupSharingFactory.create_batch(2, workspace=workspace.workspace) self.client.force_login(self.user) response = self.client.get(workspace.get_absolute_url()) self.assertIn("group_sharing_table", response.context_data) @@ -7413,9 +6470,7 @@ def test_group_sharing_table_two(self): def test_shows_workspace_group_sharing_for_only_that_workspace(self): """Only shows groups that this workspace has been shared with.""" - workspace = factories.DefaultWorkspaceDataFactory.create( - workspace__name="workspace-1" - ) + workspace = factories.DefaultWorkspaceDataFactory.create(workspace__name="workspace-1") other_workspace = factories.WorkspaceFactory.create(name="workspace-2") factories.WorkspaceGroupSharingFactory.create(workspace=other_workspace) self.client.force_login(self.user) @@ -7440,9 +6495,7 @@ def test_auth_domain_table_none(self): self.client.force_login(self.user) response = self.client.get(workspace.get_absolute_url()) self.assertIn("authorization_domain_table", response.context_data) - self.assertEqual( - len(response.context_data["authorization_domain_table"].rows), 0 - ) + self.assertEqual(len(response.context_data["authorization_domain_table"].rows), 0) def test_auth_domain_table_one(self): """One group is shown if the workspace has one auth domain.""" @@ -7473,29 +6526,21 @@ def test_auth_domain_table_two(self): def test_shows_auth_domains_for_only_that_workspace(self): """Only shows auth domains for this workspace.""" - workspace = factories.DefaultWorkspaceDataFactory.create( - workspace__name="workspace-1" - ) + workspace = factories.DefaultWorkspaceDataFactory.create(workspace__name="workspace-1") other_workspace = factories.WorkspaceFactory.create(name="workspace-2") group = factories.ManagedGroupFactory.create() other_workspace.authorization_domains.add(group) self.client.force_login(self.user) response = self.client.get(workspace.get_absolute_url()) self.assertIn("authorization_domain_table", response.context_data) - self.assertEqual( - len(response.context_data["authorization_domain_table"].rows), 0 - ) + self.assertEqual(len(response.context_data["authorization_domain_table"].rows), 0) def test_edit_permission(self): """Links to reactivate/deactivate/delete pages appear if the user has edit permission.""" edit_user = User.objects.create_user(username="edit", password="test") edit_user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ), - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ), + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME), + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME), ) self.client.force_login(edit_user) obj = factories.DefaultWorkspaceDataFactory.create() @@ -7548,9 +6593,7 @@ def test_view_permission(self): """Links to reactivate/deactivate/delete pages appear if the user has edit permission.""" view_user = User.objects.create_user(username="view", password="test") view_user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ), + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME), ) self.client.force_login(view_user) obj = factories.DefaultWorkspaceDataFactory.create() @@ -7638,18 +6681,14 @@ def test_context_workspace_type_display_name_custom_adapter(self): def test_is_locked_true(self): """An indicator of whether a workspace is locked appears on the page.""" - workspace = factories.DefaultWorkspaceDataFactory.create( - workspace__is_locked=True - ) + workspace = factories.DefaultWorkspaceDataFactory.create(workspace__is_locked=True) self.client.force_login(self.user) response = self.client.get(workspace.get_absolute_url()) self.assertContains(response, "Locked") def test_is_locked_false(self): """An indicator of whether a workspace is locked appears on the page.""" - workspace = factories.DefaultWorkspaceDataFactory.create( - workspace__is_locked=False - ) + workspace = factories.DefaultWorkspaceDataFactory.create(workspace__is_locked=False) self.client.force_login(self.user) response = self.client.get(workspace.get_absolute_url()) self.assertNotContains(response, "Locked") @@ -7658,12 +6697,8 @@ def test_edit_permission_is_locked(self): """Links appear correctly when the user has edit permission but the workspace is locked.""" edit_user = User.objects.create_user(username="edit", password="test") edit_user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ), - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ), + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME), + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME), ) self.client.force_login(edit_user) obj = factories.DefaultWorkspaceDataFactory.create(workspace__is_locked=True) @@ -7717,12 +6752,8 @@ def test_clone_links_with_two_registered_workspace_adapters(self): workspace_adapter_registry.register(TestWorkspaceAdapter) edit_user = User.objects.create_user(username="edit", password="test") edit_user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ), - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ), + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME), + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME), ) self.client.force_login(edit_user) obj = factories.DefaultWorkspaceDataFactory.create() @@ -7765,14 +6796,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) self.workspace_type = DefaultWorkspaceAdapter.type self.api_url = self.api_client.rawls_entry_point + "/api/workspaces" @@ -7799,9 +6826,7 @@ def test_view_redirect_not_logged_in(self): response = self.client.get(self.get_url(self.workspace_type)) self.assertRedirects( response, - resolve_url(settings.LOGIN_URL) - + "?next=" - + self.get_url(self.workspace_type), + resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(self.workspace_type), ) def test_status_code_with_user_permission(self): @@ -7812,13 +6837,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url(self.workspace_type)) request.user = user_with_view_perm @@ -7827,13 +6848,9 @@ def test_access_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url(self.workspace_type)) request.user = user @@ -7842,9 +6859,7 @@ def test_access_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(self.workspace_type)) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -7887,9 +6902,7 @@ def test_has_formset_in_context(self): def test_can_create_an_object(self): """Posting valid data to the form creates an object.""" - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") json_data = { "namespace": "test-billing-project", "name": "test-workspace", @@ -7927,9 +6940,7 @@ def test_can_create_an_object(self): def test_can_create_an_object_with_note(self): """Posting valid data to the form creates an object.""" - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") json_data = { "namespace": "test-billing-project", "name": "test-workspace", @@ -7962,9 +6973,7 @@ def test_can_create_an_object_with_note(self): def test_creates_default_workspace_data(self): """Posting valid data to the form creates the default workspace data object.""" - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") json_data = { "namespace": "test-billing-project", "name": "test-workspace", @@ -7993,9 +7002,7 @@ def test_creates_default_workspace_data(self): new_workspace = models.Workspace.objects.latest("pk") # Also creates a workspace data object. self.assertEqual(models.DefaultWorkspaceData.objects.count(), 1) - self.assertIsInstance( - new_workspace.defaultworkspacedata, models.DefaultWorkspaceData - ) + self.assertIsInstance(new_workspace.defaultworkspacedata, models.DefaultWorkspaceData) def test_success_message(self): """Response includes a success message if successful.""" @@ -8088,9 +7095,7 @@ def test_cannot_create_duplicate_object(self): def test_can_create_workspace_with_same_billing_project_different_name(self): """Can create a workspace with a different name in the same billing project.""" billing_project = factories.BillingProjectFactory.create() - factories.WorkspaceFactory.create( - billing_project=billing_project, name="test-name-1" - ) + factories.WorkspaceFactory.create(billing_project=billing_project, name="test-name-1") json_data = { "namespace": billing_project.name, "name": "test-name-2", @@ -8118,18 +7123,14 @@ def test_can_create_workspace_with_same_billing_project_different_name(self): self.assertEqual(response.status_code, 302) self.assertEqual(models.Workspace.objects.count(), 2) # Make sure you can get the new object. - models.Workspace.objects.get( - billing_project=billing_project, name="test-name-2" - ) + models.Workspace.objects.get(billing_project=billing_project, name="test-name-2") def test_can_create_workspace_with_same_name_different_billing_project(self): """Can create a workspace with the same name in a different billing project.""" billing_project_1 = factories.BillingProjectFactory.create(name="project-1") billing_project_2 = factories.BillingProjectFactory.create(name="project-2") workspace_name = "test-name" - factories.WorkspaceFactory.create( - billing_project=billing_project_1, name=workspace_name - ) + factories.WorkspaceFactory.create(billing_project=billing_project_1, name=workspace_name) json_data = { "namespace": billing_project_2.name, "name": "test-name", @@ -8157,9 +7158,7 @@ def test_can_create_workspace_with_same_name_different_billing_project(self): self.assertEqual(response.status_code, 302) self.assertEqual(models.Workspace.objects.count(), 2) # Make sure you can get the new object. - models.Workspace.objects.get( - billing_project=billing_project_2, name=workspace_name - ) + models.Workspace.objects.get(billing_project=billing_project_2, name=workspace_name) def test_invalid_input_name(self): """Posting invalid data to name field does not create an object.""" @@ -8275,9 +7274,7 @@ def test_api_error_message(self): def test_can_create_a_workspace_with_one_authorization_domain(self): """Can create a workspace with one authorization domain.""" - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") auth_domain = factories.ManagedGroupFactory.create() json_data = { "namespace": "test-billing-project", @@ -8315,15 +7312,11 @@ def test_can_create_a_workspace_with_one_authorization_domain(self): self.assertEqual(new_object.history.latest().history_type, "+") # History is added for the authorization domain. self.assertEqual(models.WorkspaceAuthorizationDomain.history.count(), 1) - self.assertEqual( - models.WorkspaceAuthorizationDomain.history.latest().history_type, "+" - ) + self.assertEqual(models.WorkspaceAuthorizationDomain.history.latest().history_type, "+") def test_create_workspace_with_two_auth_domains(self): """Can create a workspace with two authorization domains.""" - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") auth_domain_1 = factories.ManagedGroupFactory.create(name="auth1") auth_domain_2 = factories.ManagedGroupFactory.create(name="auth2") json_data = { @@ -8364,9 +7357,7 @@ def test_create_workspace_with_two_auth_domains(self): def test_invalid_auth_domain(self): """Does not create a workspace when an invalid authorization domain is specified.""" - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") self.client.force_login(self.user) response = self.client.post( self.get_url(self.workspace_type), @@ -8392,9 +7383,7 @@ def test_invalid_auth_domain(self): # No API calls made. def test_one_valid_one_invalid_auth_domain(self): - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") auth_domain = factories.ManagedGroupFactory.create() self.client.force_login(self.user) response = self.client.post( @@ -8421,9 +7410,7 @@ def test_one_valid_one_invalid_auth_domain(self): def test_auth_domain_does_not_exist_on_anvil(self): """No workspace is displayed if the auth domain group doesn't exist on AnVIL.""" - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") auth_domain = factories.ManagedGroupFactory.create() json_data = { "namespace": "test-billing-project", @@ -8468,9 +7455,7 @@ def test_auth_domain_does_not_exist_on_anvil(self): def test_not_admin_of_auth_domain_on_anvil(self): """No workspace is displayed if we are not the admins of the auth domain on AnVIL.""" - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") auth_domain = factories.ManagedGroupFactory.create() json_data = { "namespace": "test-billing-project", @@ -8537,9 +7522,7 @@ def test_adapter_creates_workspace_data(self): workspace_adapter_registry.unregister(DefaultWorkspaceAdapter) workspace_adapter_registry.register(TestWorkspaceAdapter) self.workspace_type = "test" - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") json_data = { "namespace": "test-billing-project", "name": "test-workspace", @@ -8629,9 +7612,7 @@ def test_adapter_custom_form_class(self): self.workspace_type = "test" self.client.force_login(self.user) response = self.client.get(self.get_url(self.workspace_type)) - self.assertIsInstance( - response.context_data["form"], app_forms.TestWorkspaceForm - ) + self.assertIsInstance(response.context_data["form"], app_forms.TestWorkspaceForm) def test_adapter_does_not_create_object_if_workspace_form_invalid(self): # Overriding settings doesn't work, because appconfig.ready has already run and @@ -8677,22 +7658,16 @@ 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) self.workspace_type = DefaultWorkspaceAdapter().get_type() self.workspace_list_url = self.api_client.rawls_entry_point + "/api/workspaces" # Object to hold API response for ACL call. self.api_json_response_acl = {"acl": {}} - self.add_api_json_response_acl( - self.service_account_email, "OWNER", can_compute=True, can_share=True - ) + self.add_api_json_response_acl(self.service_account_email, "OWNER", can_compute=True, can_share=True) def tearDown(self): """Clean up after tests.""" @@ -8707,13 +7682,7 @@ def get_url(self, *args): return reverse("anvil_consortium_manager:workspaces:import", args=args) def get_api_url(self, billing_project_name, workspace_name): - 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, @@ -8728,9 +7697,7 @@ def get_api_json_response( "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": is_locked, @@ -8748,9 +7715,7 @@ def get_api_url_acl(self, billing_project_name, workspace_name): + "/acl" ) - def add_api_json_response_acl( - self, email, access, can_compute=False, can_share=False - ): + def add_api_json_response_acl(self, email, access, can_compute=False, can_share=False): """Add a record to the API response for the workspace ACL call.""" self.api_json_response_acl["acl"][email] = { "accessLevel": access, @@ -8769,9 +7734,7 @@ def test_view_redirect_not_logged_in(self): response = self.client.get(self.get_url(self.workspace_type)) self.assertRedirects( response, - resolve_url(settings.LOGIN_URL) - + "?next=" - + self.get_url(self.workspace_type), + resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(self.workspace_type), ) def test_status_code_with_user_permission(self): @@ -8780,9 +7743,7 @@ def test_status_code_with_user_permission(self): responses.GET, self.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=[], @@ -8793,13 +7754,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url(self.workspace_type)) request.user = user_with_view_perm @@ -8808,13 +7765,9 @@ def test_access_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url(self.workspace_type)) request.user = user @@ -8823,9 +7776,7 @@ def test_access_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(self.workspace_type)) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -8853,9 +7804,7 @@ def test_has_form_in_context(self): responses.GET, self.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)], @@ -8873,9 +7822,7 @@ def test_has_formset_in_context(self): responses.GET, self.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)], @@ -8894,9 +7841,7 @@ def test_form_choices_no_available_workspaces(self): responses.GET, self.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=[], @@ -8911,9 +7856,7 @@ def test_form_choices_no_available_workspaces(self): # A message is shown. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.WorkspaceImport.message_no_available_workspaces, str(messages[0]) - ) + self.assertEqual(views.WorkspaceImport.message_no_available_workspaces, str(messages[0])) def test_form_choices_one_available_workspace(self): """Choices are populated correctly with one available workspace.""" @@ -8921,9 +7864,7 @@ def test_form_choices_one_available_workspace(self): responses.GET, self.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("bp-1", "ws-1")], @@ -8944,9 +7885,7 @@ def test_form_choices_two_available_workspaces(self): responses.GET, self.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=[ @@ -8971,9 +7910,7 @@ def test_form_choices_alphabetical_order(self): responses.GET, self.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=[ @@ -8995,16 +7932,12 @@ def test_form_choices_alphabetical_order(self): def test_form_does_not_show_already_imported_workspaces(self): """The form does not show workspaces that have already been imported in the choices.""" billing_project = factories.BillingProjectFactory.create(name="bp") - factories.WorkspaceFactory.create( - billing_project=billing_project, name="ws-imported" - ) + factories.WorkspaceFactory.create(billing_project=billing_project, name="ws-imported") self.anvil_response_mock.add( responses.GET, self.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=[ @@ -9022,9 +7955,7 @@ def test_form_does_not_show_already_imported_workspaces(self): # A message is shown. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.WorkspaceImport.message_no_available_workspaces, str(messages[0]) - ) + self.assertEqual(views.WorkspaceImport.message_no_available_workspaces, str(messages[0])) def test_form_does_not_show_workspaces_not_owner(self): """The form does not show workspaces where we aren't owners in the choices.""" @@ -9032,9 +7963,7 @@ def test_form_does_not_show_workspaces_not_owner(self): responses.GET, self.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=[ @@ -9061,19 +7990,13 @@ def test_can_import_workspace_and_billing_project_as_user(self): responses.GET, self.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)], ) # Billing project API call. - billing_project_url = ( - self.api_client.rawls_entry_point - + "/api/billing/v2/" - + billing_project_name - ) + billing_project_url = self.api_client.rawls_entry_point + "/api/billing/v2/" + billing_project_name self.anvil_response_mock.add(responses.GET, billing_project_url, status=200) url = self.get_api_url(billing_project_name, workspace_name) self.anvil_response_mock.add( @@ -9125,18 +8048,14 @@ def test_can_import_workspace_and_billing_project_as_user(self): def test_can_import_workspace_with_note(self): """Sets note when specified when importing a workspace.""" billing_project_name = "billing-project" - billing_project = factories.BillingProjectFactory.create( - name=billing_project_name - ) + billing_project = factories.BillingProjectFactory.create(name=billing_project_name) workspace_name = "workspace" # Available workspaces API call. self.anvil_response_mock.add( responses.GET, self.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)], @@ -9181,18 +8100,14 @@ def test_can_import_workspace_with_note(self): def test_can_import_locked_workspace(self): """Sets note when specified when importing a workspace.""" billing_project_name = "billing-project" - billing_project = factories.BillingProjectFactory.create( - name=billing_project_name - ) + billing_project = factories.BillingProjectFactory.create(name=billing_project_name) workspace_name = "workspace" # Available workspaces API call. self.anvil_response_mock.add( responses.GET, self.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)], @@ -9202,9 +8117,7 @@ def test_can_import_locked_workspace(self): responses.GET, url, status=self.api_success_code, - json=self.get_api_json_response( - billing_project_name, workspace_name, is_locked=True - ), + json=self.get_api_json_response(billing_project_name, workspace_name, is_locked=True), ) # Response for ACL query. self.anvil_response_mock.add( @@ -9245,9 +8158,7 @@ def test_creates_default_workspace_data_without_custom_adapter(self): responses.GET, self.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)], @@ -9282,9 +8193,7 @@ def test_creates_default_workspace_data_without_custom_adapter(self): new_workspace = models.Workspace.objects.latest("pk") # Also creates a workspace data object. self.assertEqual(models.DefaultWorkspaceData.objects.count(), 1) - self.assertIsInstance( - new_workspace.defaultworkspacedata, models.DefaultWorkspaceData - ) + self.assertIsInstance(new_workspace.defaultworkspacedata, models.DefaultWorkspaceData) def test_success_message(self): """Can import a workspace from AnVIL when the billing project does not exist in Django and we are users.""" @@ -9295,9 +8204,7 @@ def test_success_message(self): responses.GET, self.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)], @@ -9342,22 +8249,14 @@ def test_can_import_workspace_and_billing_project_as_not_user(self): responses.GET, self.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)], ) # Billing project API call. - billing_project_url = ( - self.api_client.rawls_entry_point - + "/api/billing/v2/" - + billing_project_name - ) - self.anvil_response_mock.add( - responses.GET, billing_project_url, status=404, json={"message": "other"} - ) + billing_project_url = self.api_client.rawls_entry_point + "/api/billing/v2/" + billing_project_name + self.anvil_response_mock.add(responses.GET, billing_project_url, status=404, json={"message": "other"}) url = self.get_api_url(billing_project_name, workspace_name) self.anvil_response_mock.add( responses.GET, @@ -9410,9 +8309,7 @@ def test_can_import_workspace_with_existing_billing_project(self): responses.GET, self.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)], @@ -9470,9 +8367,7 @@ def test_can_import_workspace_with_auth_domain_in_app(self): responses.GET, self.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, # Assume that this is the only workspace we can see on AnVIL. @@ -9514,9 +8409,7 @@ def test_can_import_workspace_with_auth_domain_in_app(self): self.assertEqual(new_workspace.history.latest().history_type, "+") # History is added for the authorization domain. self.assertEqual(models.WorkspaceAuthorizationDomain.history.count(), 1) - self.assertEqual( - models.WorkspaceAuthorizationDomain.history.latest().history_type, "+" - ) + self.assertEqual(models.WorkspaceAuthorizationDomain.history.latest().history_type, "+") def test_can_import_workspace_with_auth_domain_not_in_app(self): """Can import a workspace with an auth domain that is not already in the app.""" @@ -9528,9 +8421,7 @@ def test_can_import_workspace_with_auth_domain_not_in_app(self): responses.GET, self.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=[ @@ -9606,9 +8497,7 @@ def test_can_import_workspace_with_auth_domain_not_in_app(self): self.assertEqual(auth_domain.history.latest().history_type, "+") # History is added for the authorization domain. self.assertEqual(models.WorkspaceAuthorizationDomain.history.count(), 1) - self.assertEqual( - models.WorkspaceAuthorizationDomain.history.latest().history_type, "+" - ) + self.assertEqual(models.WorkspaceAuthorizationDomain.history.latest().history_type, "+") def test_redirects_to_new_object_detail(self): """After successfully creating an object, view redirects to the object's detail page.""" @@ -9620,9 +8509,7 @@ def test_redirects_to_new_object_detail(self): responses.GET, self.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)], @@ -9664,16 +8551,10 @@ def test_workspace_already_imported(self): responses.GET, self.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( - workspace.billing_project.name, workspace.name - ) - ], + json=[self.get_api_json_response(workspace.billing_project.name, workspace.name)], ) # Messages need the client. self.client.force_login(self.user) @@ -9706,9 +8587,7 @@ def test_invalid_workspace_name(self): responses.GET, self.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("foo", "bar")], @@ -9743,9 +8622,7 @@ def test_post_blank_data(self): responses.GET, self.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("foo", "bar")], @@ -9776,9 +8653,7 @@ def test_other_anvil_api_error(self): responses.GET, self.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)], @@ -9819,9 +8694,7 @@ def test_anvil_api_error_workspace_list_get(self): responses.GET, self.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=500, json={"message": "an error"}, @@ -9833,9 +8706,7 @@ def test_anvil_api_error_workspace_list_get(self): # Check messages. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.WorkspaceImport.message_error_fetching_workspaces, str(messages[0]) - ) + self.assertEqual(views.WorkspaceImport.message_error_fetching_workspaces, str(messages[0])) # Did not create any objects. self.assertEqual(models.BillingProject.objects.count(), 0) self.assertEqual(models.Workspace.objects.count(), 0) @@ -9846,9 +8717,7 @@ def test_anvil_api_error_workspace_list_post(self): responses.GET, self.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=500, json={"message": "an error"}, @@ -9872,9 +8741,7 @@ def test_anvil_api_error_workspace_list_post(self): # Check messages. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.WorkspaceImport.message_error_fetching_workspaces, str(messages[0]) - ) + self.assertEqual(views.WorkspaceImport.message_error_fetching_workspaces, str(messages[0])) # Did not create any objects. self.assertEqual(models.BillingProject.objects.count(), 0) self.assertEqual(models.Workspace.objects.count(), 0) @@ -9893,9 +8760,7 @@ def test_adapter_includes_workspace_data_formset(self): responses.GET, self.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)], @@ -9923,9 +8788,7 @@ def test_adapter_creates_workspace_data(self): responses.GET, self.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)], @@ -9985,9 +8848,7 @@ def test_adapter_does_not_create_objects_if_workspace_data_form_invalid(self): responses.GET, self.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)], @@ -10044,9 +8905,7 @@ def test_imports_group_sharing(self): responses.GET, self.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)], @@ -10060,9 +8919,7 @@ def test_imports_group_sharing(self): ) # Response for ACL query. group = factories.ManagedGroupFactory.create() - self.add_api_json_response_acl( - group.email, "READER", can_compute=False, can_share=False - ) + self.add_api_json_response_acl(group.email, "READER", can_compute=False, can_share=False) self.anvil_response_mock.add( responses.GET, self.get_api_url_acl(billing_project.name, workspace_name), @@ -10102,9 +8959,7 @@ def test_api_error_acl_call(self): responses.GET, self.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)], @@ -10162,22 +9017,15 @@ 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) self.workspace_to_clone = factories.WorkspaceFactory.create() - self.api_url = ( - self.api_client.rawls_entry_point - + "/api/workspaces/{}/{}/clone".format( - self.workspace_to_clone.billing_project.name, - self.workspace_to_clone.name, - ) + self.api_url = self.api_client.rawls_entry_point + "/api/workspaces/{}/{}/clone".format( + self.workspace_to_clone.billing_project.name, + self.workspace_to_clone.name, ) self.workspace_type = DefaultWorkspaceAdapter.type @@ -10231,13 +9079,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) request = self.factory.get( self.get_url( @@ -10257,13 +9101,9 @@ def test_access_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo", "bar", self.workspace_type)) request.user = user @@ -10272,9 +9112,7 @@ def test_access_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( self.workspace_to_clone.billing_project.name, @@ -10371,9 +9209,7 @@ def test_has_formset_in_context(self): def test_can_create_an_object(self): """Posting valid data to the form creates an object.""" - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") json_data = { "namespace": "test-billing-project", "name": "test-workspace", @@ -10418,9 +9254,7 @@ def test_can_create_object_with_auth_domains(self): """Posting valid data to the form creates an object.""" auth_domain = factories.ManagedGroupFactory.create() self.workspace_to_clone.authorization_domains.add(auth_domain) - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") json_data = { "namespace": "test-billing-project", "name": "test-workspace", @@ -10467,9 +9301,7 @@ def test_can_add_an_auth_domains(self): auth_domain = factories.ManagedGroupFactory.create() self.workspace_to_clone.authorization_domains.add(auth_domain) new_auth_domain = factories.ManagedGroupFactory.create() - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") json_data = { "namespace": "test-billing-project", "name": "test-workspace", @@ -10514,9 +9346,7 @@ def test_can_add_an_auth_domains(self): def test_creates_default_workspace_data(self): """Posting valid data to the form creates the default workspace data object.""" - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") json_data = { "namespace": "test-billing-project", "name": "test-workspace", @@ -10550,9 +9380,7 @@ def test_creates_default_workspace_data(self): new_workspace = models.Workspace.objects.latest("pk") # Also creates a workspace data object. self.assertEqual(models.DefaultWorkspaceData.objects.count(), 1) - self.assertIsInstance( - new_workspace.defaultworkspacedata, models.DefaultWorkspaceData - ) + self.assertIsInstance(new_workspace.defaultworkspacedata, models.DefaultWorkspaceData) def test_success_message(self): """Response includes a success message if successful.""" @@ -10658,9 +9486,7 @@ def test_cannot_create_duplicate_object(self): def test_can_create_workspace_with_same_billing_project_different_name(self): """Can create a workspace with a different name in the same billing project.""" billing_project = factories.BillingProjectFactory.create() - factories.WorkspaceFactory.create( - billing_project=billing_project, name="test-name-1" - ) + factories.WorkspaceFactory.create(billing_project=billing_project, name="test-name-1") json_data = { "namespace": billing_project.name, "name": "test-name-2", @@ -10693,18 +9519,14 @@ def test_can_create_workspace_with_same_billing_project_different_name(self): self.assertEqual(response.status_code, 302) self.assertEqual(models.Workspace.objects.count(), 3) # Make sure you can get the new object. - models.Workspace.objects.get( - billing_project=billing_project, name="test-name-2" - ) + models.Workspace.objects.get(billing_project=billing_project, name="test-name-2") def test_can_create_workspace_with_same_name_different_billing_project(self): """Can create a workspace with the same name in a different billing project.""" billing_project_1 = factories.BillingProjectFactory.create(name="project-1") billing_project_2 = factories.BillingProjectFactory.create(name="project-2") workspace_name = "test-name" - factories.WorkspaceFactory.create( - billing_project=billing_project_1, name=workspace_name - ) + factories.WorkspaceFactory.create(billing_project=billing_project_1, name=workspace_name) json_data = { "namespace": billing_project_2.name, "name": "test-name", @@ -10737,9 +9559,7 @@ def test_can_create_workspace_with_same_name_different_billing_project(self): self.assertEqual(response.status_code, 302) self.assertEqual(models.Workspace.objects.count(), 3) # Make sure you can get the new object. - models.Workspace.objects.get( - billing_project=billing_project_2, name=workspace_name - ) + models.Workspace.objects.get(billing_project=billing_project_2, name=workspace_name) def test_invalid_input_name(self): """Posting invalid data to name field does not create an object.""" @@ -10886,9 +9706,7 @@ def test_api_error_message(self): def test_invalid_auth_domain(self): """Does not create a workspace when an invalid authorization domain is specified.""" - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") self.client.force_login(self.user) response = self.client.post( self.get_url( @@ -10918,9 +9736,7 @@ def test_invalid_auth_domain(self): self.assertIn(self.workspace_to_clone, models.Workspace.objects.all()) def test_one_valid_one_invalid_auth_domain(self): - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") auth_domain = factories.ManagedGroupFactory.create() self.client.force_login(self.user) response = self.client.post( @@ -10952,9 +9768,7 @@ def test_one_valid_one_invalid_auth_domain(self): def test_auth_domain_does_not_exist_on_anvil(self): """No workspace is displayed if the auth domain group doesn't exist on AnVIL.""" - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") auth_domain = factories.ManagedGroupFactory.create() json_data = { "namespace": "test-billing-project", @@ -11005,9 +9819,7 @@ def test_auth_domain_does_not_exist_on_anvil(self): def test_not_admin_of_auth_domain_on_anvil(self): """No workspace is displayed if we are not the admins of the auth domain on AnVIL.""" - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") auth_domain = factories.ManagedGroupFactory.create() json_data = { "namespace": "test-billing-project", @@ -11058,9 +9870,7 @@ def test_not_admin_of_auth_domain_on_anvil(self): def test_not_user_of_billing_project(self): """Posting a billing project where we are not users does not create an object.""" - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project", has_app_as_user=False - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project", has_app_as_user=False) self.client.force_login(self.user) response = self.client.post( self.get_url( @@ -11118,9 +9928,7 @@ def test_adapter_creates_workspace_data(self): workspace_adapter_registry.unregister(DefaultWorkspaceAdapter) workspace_adapter_registry.register(TestWorkspaceAdapter) self.workspace_type = "test" - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") json_data = { "namespace": "test-billing-project", "name": "test-workspace", @@ -11261,14 +10069,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) self.workspace_data = factories.DefaultWorkspaceDataFactory.create() self.workspace = self.workspace_data.workspace @@ -11301,20 +10105,14 @@ 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.workspace.billing_project, self.workspace.name) - ) + response = self.client.get(self.get_url(self.workspace.billing_project, self.workspace.name)) self.assertEqual(response.status_code, 200) 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo", "bar")) request.user = user_with_view_perm @@ -11323,13 +10121,9 @@ def test_access_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo", "bar")) request.user = user @@ -11338,9 +10132,7 @@ def test_access_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("foo", "bar")) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -11356,30 +10148,22 @@ def test_object_does_not_exist(self): def test_context_workspace_data(self): """The view adds the workspace_data object to the context.""" self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.workspace.billing_project.name, self.workspace.name) - ) + response = self.client.get(self.get_url(self.workspace.billing_project.name, self.workspace.name)) response.context_data self.assertIn("workspace_data_object", response.context_data) - self.assertEqual( - response.context_data["workspace_data_object"], self.workspace_data - ) + self.assertEqual(response.context_data["workspace_data_object"], self.workspace_data) def test_has_form_in_context(self): """Response includes a form.""" self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.workspace.billing_project.name, self.workspace.name) - ) + response = self.client.get(self.get_url(self.workspace.billing_project.name, self.workspace.name)) self.assertIn("form", response.context_data) self.assertIsInstance(response.context_data["form"], forms.WorkspaceForm) def test_form_fields(self): """Response includes a form.""" self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.workspace.billing_project.name, self.workspace.name) - ) + response = self.client.get(self.get_url(self.workspace.billing_project.name, self.workspace.name)) form = response.context_data.get("form") self.assertEqual(len(form.fields), 1) self.assertIn("note", form.fields) @@ -11387,9 +10171,7 @@ def test_form_fields(self): def test_has_formset_in_context(self): """Response includes a formset for the workspace_data model.""" self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.workspace.billing_project.name, self.workspace.name) - ) + response = self.client.get(self.get_url(self.workspace.billing_project.name, self.workspace.name)) self.assertTrue("workspace_data_formset" in response.context_data) formset = response.context_data["workspace_data_formset"] self.assertIsInstance(formset, BaseInlineFormSet) @@ -11464,12 +10246,8 @@ def test_can_update_workspace_data(self): """Can update workspace data when updating the workspace.""" # Note that we need to use the test adapter for this. workspace_adapter_registry.register(TestWorkspaceAdapter) - workspace = factories.WorkspaceFactory( - workspace_type=TestWorkspaceAdapter().get_type() - ) - workspace_data = app_models.TestWorkspaceData.objects.create( - workspace=workspace, study_name="original name" - ) + workspace = factories.WorkspaceFactory(workspace_type=TestWorkspaceAdapter().get_type()) + workspace_data = app_models.TestWorkspaceData.objects.create(workspace=workspace, study_name="original name") # Need a client for messages. self.client.force_login(self.user) response = self.client.post( @@ -11492,17 +10270,11 @@ def test_can_update_workspace_data(self): def test_custom_adapter_workspace_data(self): # Note that we need to use the test adapter for this. workspace_adapter_registry.register(TestWorkspaceAdapter) - workspace = factories.WorkspaceFactory( - workspace_type=TestWorkspaceAdapter().get_type() - ) - app_models.TestWorkspaceData.objects.create( - workspace=workspace, study_name="original name" - ) + workspace = factories.WorkspaceFactory(workspace_type=TestWorkspaceAdapter().get_type()) + app_models.TestWorkspaceData.objects.create(workspace=workspace, study_name="original name") # Need a client for messages. self.client.force_login(self.user) - response = self.client.get( - self.get_url(workspace.billing_project.name, workspace.name) - ) + response = self.client.get(self.get_url(workspace.billing_project.name, workspace.name)) self.assertTrue("workspace_data_formset" in response.context_data) formset = response.context_data["workspace_data_formset"] self.assertIsInstance(formset, BaseInlineFormSet) @@ -11517,9 +10289,7 @@ def test_no_updates_if_invalid_workspace_data_form(self): workspace_type=TestWorkspaceAdapter().get_type(), note="original note", ) - workspace_data = app_models.TestWorkspaceData.objects.create( - workspace=workspace, study_name="original name" - ) + workspace_data = app_models.TestWorkspaceData.objects.create(workspace=workspace, study_name="original name") # Need a client for messages. self.client.force_login(self.user) response = self.client.post( @@ -11546,17 +10316,11 @@ def test_custom_adapter_workspace_form(self): """Workspace form is subclass of the custom adapter form.""" # Note that we need to use the test adapter for this. workspace_adapter_registry.register(TestWorkspaceAdapter) - workspace = factories.WorkspaceFactory( - workspace_type=TestWorkspaceAdapter().get_type() - ) - app_models.TestWorkspaceData.objects.create( - workspace=workspace, study_name="original name" - ) + workspace = factories.WorkspaceFactory(workspace_type=TestWorkspaceAdapter().get_type()) + app_models.TestWorkspaceData.objects.create(workspace=workspace, study_name="original name") # Need a client for messages. self.client.force_login(self.user) - response = self.client.get( - self.get_url(workspace.billing_project.name, workspace.name) - ) + response = self.client.get(self.get_url(workspace.billing_project.name, workspace.name)) self.assertTrue("form" in response.context_data) form = response.context_data["form"] self.assertIsInstance(form, TestWorkspaceAdapter().get_workspace_form_class()) @@ -11571,9 +10335,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.workspace_type = DefaultWorkspaceAdapter().get_type() @@ -11610,13 +10372,9 @@ def test_status_code_with_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -11625,9 +10383,7 @@ def test_access_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): @@ -11671,12 +10427,8 @@ def test_view_with_two_objects(self): def test_only_shows_workspaces_of_any_type(self): """The table includes all workspaces regardless of type.""" workspace_adapter_registry.register(TestWorkspaceAdapter) - test_workspace = factories.WorkspaceFactory( - workspace_type=TestWorkspaceAdapter().get_type() - ) - default_workspace = factories.WorkspaceFactory( - workspace_type=DefaultWorkspaceAdapter().get_type() - ) + test_workspace = factories.WorkspaceFactory(workspace_type=TestWorkspaceAdapter().get_type()) + default_workspace = factories.WorkspaceFactory(workspace_type=DefaultWorkspaceAdapter().get_type()) self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertEqual(response.status_code, 200) @@ -11691,9 +10443,7 @@ def test_context_workspace_type_display_name(self): response = self.client.get(self.get_url()) self.assertEqual(response.status_code, 200) self.assertIn("workspace_type_display_name", response.context_data) - self.assertEqual( - response.context_data["workspace_type_display_name"], "All workspace" - ) + self.assertEqual(response.context_data["workspace_type_display_name"], "All workspace") def test_view_with_filter_return_no_object(self): factories.WorkspaceFactory.create(name="workspace1") @@ -11751,9 +10501,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.workspace_type = DefaultWorkspaceAdapter().get_type() @@ -11779,9 +10527,7 @@ def test_view_redirect_not_logged_in(self): response = self.client.get(self.get_url(self.workspace_type)) self.assertRedirects( response, - resolve_url(settings.LOGIN_URL) - + "?next=" - + self.get_url(self.workspace_type), + resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(self.workspace_type), ) def test_status_code_with_user_permission(self): @@ -11792,13 +10538,9 @@ def test_status_code_with_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url(self.workspace_type)) request.user = user @@ -11807,9 +10549,7 @@ def test_access_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(self.workspace_type)) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -11868,9 +10608,7 @@ def test_adapter(self): self.client.force_login(self.user) response = self.client.get(self.get_url(self.workspace_type)) self.assertIn("table", response.context_data) - self.assertIsInstance( - response.context_data["table"], app_tables.TestWorkspaceDataTable - ) + self.assertIsInstance(response.context_data["table"], app_tables.TestWorkspaceDataTable) def test_only_shows_workspaces_with_correct_type(self): """Only workspaces with the same workspace_type are shown in the table.""" @@ -11887,9 +10625,7 @@ def test_view_with_filter_return_no_object(self): factories.WorkspaceFactory.create(name="workspace1") factories.WorkspaceFactory.create(name="workspace2") self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.workspace_type), {"name__icontains": "abc"} - ) + response = self.client.get(self.get_url(self.workspace_type), {"name__icontains": "abc"}) self.assertEqual(response.status_code, 200) self.assertIn("table", response.context_data) self.assertEqual(len(response.context_data["table"].rows), 0) @@ -11898,9 +10634,7 @@ def test_view_with_filter_returns_one_object_exact(self): instance = factories.WorkspaceFactory.create(name="workspace1") factories.WorkspaceFactory.create(name="workspace2") self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.workspace_type), {"name__icontains": "workspace1"} - ) + response = self.client.get(self.get_url(self.workspace_type), {"name__icontains": "workspace1"}) self.assertEqual(response.status_code, 200) self.assertIn("table", response.context_data) self.assertEqual(len(response.context_data["table"].rows), 1) @@ -11910,9 +10644,7 @@ def test_view_with_filter_returns_one_object_case_insensitive(self): instance = factories.WorkspaceFactory.create(name="workspace1") factories.WorkspaceFactory.create(name="workspace2") self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.workspace_type), {"name__icontains": "Workspace1"} - ) + response = self.client.get(self.get_url(self.workspace_type), {"name__icontains": "Workspace1"}) self.assertEqual(response.status_code, 200) self.assertIn("table", response.context_data) self.assertEqual(len(response.context_data["table"].rows), 1) @@ -11922,9 +10654,7 @@ def test_view_with_filter_returns_one_object_case_contains(self): instance = factories.WorkspaceFactory.create(name="workspace1") factories.WorkspaceFactory.create(name="workspace2") self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.workspace_type), {"name__icontains": "orkspace1"} - ) + response = self.client.get(self.get_url(self.workspace_type), {"name__icontains": "orkspace1"}) self.assertEqual(response.status_code, 200) self.assertIn("table", response.context_data) self.assertEqual(len(response.context_data["table"].rows), 1) @@ -11932,13 +10662,9 @@ def test_view_with_filter_returns_one_object_case_contains(self): def test_view_with_filter_workspace_type(self): instance = factories.WorkspaceFactory.create(name="workspace1") - factories.WorkspaceFactory.create( - name="workspace2", workspace_type=TestWorkspaceAdapter().get_type() - ) + factories.WorkspaceFactory.create(name="workspace2", workspace_type=TestWorkspaceAdapter().get_type()) self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.workspace_type), {"name__icontains": "workspace"} - ) + response = self.client.get(self.get_url(self.workspace_type), {"name__icontains": "workspace"}) self.assertEqual(response.status_code, 200) self.assertIn("table", response.context_data) self.assertEqual(len(response.context_data["table"].rows), 1) @@ -11948,9 +10674,7 @@ def test_view_with_filter_returns_mutiple_objects(self): factories.WorkspaceFactory.create(name="workspace1") factories.WorkspaceFactory.create(name="wOrkspace1") self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.workspace_type), {"name__icontains": "Workspace"} - ) + response = self.client.get(self.get_url(self.workspace_type), {"name__icontains": "Workspace"}) self.assertEqual(response.status_code, 200) self.assertIn("table", response.context_data) self.assertEqual(len(response.context_data["table"].rows), 2) @@ -11968,14 +10692,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) def tearDown(self): @@ -11991,13 +10711,7 @@ def get_url(self, *args): return reverse("anvil_consortium_manager:workspaces:delete", args=args) def get_api_url(self, billing_project_name, workspace_name): - 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_view(self): """Return the view being tested.""" @@ -12019,13 +10733,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo1", "foo2")) request.user = user_with_view_perm @@ -12034,13 +10744,9 @@ def test_access_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo", "bar")) request.user = user @@ -12049,9 +10755,7 @@ def test_access_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("foo1", "foo2")) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -12066,20 +10770,12 @@ def test_view_with_invalid_pk(self): def test_view_deletes_object(self): """Posting submit to the form successfully deletes the object.""" - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) - object = factories.WorkspaceFactory.create( - billing_project=billing_project, name="test-workspace" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") + object = factories.WorkspaceFactory.create(billing_project=billing_project, name="test-workspace") api_url = self.get_api_url(object.billing_project.name, object.name) - self.anvil_response_mock.add( - responses.DELETE, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.DELETE, api_url, status=self.api_success_code) self.client.force_login(self.user) - response = self.client.post( - self.get_url(object.billing_project.name, object.name), {"submit": ""} - ) + response = self.client.post(self.get_url(object.billing_project.name, object.name), {"submit": ""}) self.assertEqual(response.status_code, 302) self.assertEqual(models.Workspace.objects.count(), 0) # History is added. @@ -12088,16 +10784,10 @@ def test_view_deletes_object(self): def test_success_message(self): """Response includes a success message if successful.""" - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) - object = factories.WorkspaceFactory.create( - billing_project=billing_project, name="test-workspace" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") + object = factories.WorkspaceFactory.create(billing_project=billing_project, name="test-workspace") api_url = self.get_api_url(object.billing_project.name, object.name) - self.anvil_response_mock.add( - responses.DELETE, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.DELETE, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(object.billing_project.name, object.name), @@ -12113,13 +10803,9 @@ def test_only_deletes_specified_pk(self): object = factories.WorkspaceFactory.create() other_object = factories.WorkspaceFactory.create() api_url = self.get_api_url(object.billing_project.name, object.name) - self.anvil_response_mock.add( - responses.DELETE, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.DELETE, api_url, status=self.api_success_code) self.client.force_login(self.user) - response = self.client.post( - self.get_url(object.billing_project.name, object.name), {"submit": ""} - ) + response = self.client.post(self.get_url(object.billing_project.name, object.name), {"submit": ""}) self.assertEqual(response.status_code, 302) self.assertEqual(models.Workspace.objects.count(), 1) self.assertQuerySetEqual( @@ -12129,25 +10815,15 @@ def test_only_deletes_specified_pk(self): def test_can_delete_workspace_with_auth_domain(self): """A workspace can be deleted if it has an auth domain, and the auth domain group is not deleted.""" - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) - object = factories.WorkspaceFactory.create( - billing_project=billing_project, name="test-workspace" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") + object = factories.WorkspaceFactory.create(billing_project=billing_project, name="test-workspace") auth_domain = factories.ManagedGroupFactory.create(name="test-group") - wad = models.WorkspaceAuthorizationDomain.objects.create( - workspace=object, group=auth_domain - ) + wad = models.WorkspaceAuthorizationDomain.objects.create(workspace=object, group=auth_domain) # object.authorization_domains.add(auth_domain) api_url = self.get_api_url(object.billing_project.name, object.name) - self.anvil_response_mock.add( - responses.DELETE, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.DELETE, api_url, status=self.api_success_code) self.client.force_login(self.user) - response = self.client.post( - self.get_url(object.billing_project.name, object.name), {"submit": ""} - ) + response = self.client.post(self.get_url(object.billing_project.name, object.name), {"submit": ""}) self.assertEqual(response.status_code, 302) self.assertEqual(models.Workspace.objects.count(), 0) self.assertEqual(models.WorkspaceAuthorizationDomain.objects.count(), 0) @@ -12163,22 +10839,14 @@ def test_can_delete_workspace_with_auth_domain(self): def test_can_delete_workspace_that_has_been_shared_with_group(self): """A workspace can be deleted if it has been shared with a group, and the group is not deleted.""" - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) - object = factories.WorkspaceFactory.create( - billing_project=billing_project, name="test-workspace" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") + object = factories.WorkspaceFactory.create(billing_project=billing_project, name="test-workspace") group = factories.ManagedGroupFactory.create(name="test-group") factories.WorkspaceGroupSharingFactory.create(workspace=object, group=group) api_url = self.get_api_url(object.billing_project.name, object.name) - self.anvil_response_mock.add( - responses.DELETE, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.DELETE, api_url, status=self.api_success_code) self.client.force_login(self.user) - response = self.client.post( - self.get_url(object.billing_project.name, object.name), {"submit": ""} - ) + response = self.client.post(self.get_url(object.billing_project.name, object.name), {"submit": ""}) self.assertEqual(response.status_code, 302) self.assertEqual(models.Workspace.objects.count(), 0) self.assertEqual(models.WorkspaceGroupSharing.objects.count(), 0) @@ -12190,22 +10858,16 @@ def test_can_delete_workspace_that_has_been_shared_with_group(self): self.assertEqual(object.history.latest().history_type, "-") # History is added for WorkspaceGroupSharing. self.assertEqual(models.WorkspaceGroupSharing.history.count(), 2) - self.assertEqual( - models.WorkspaceGroupSharing.history.latest().history_type, "-" - ) + self.assertEqual(models.WorkspaceGroupSharing.history.latest().history_type, "-") def test_success_url(self): """Redirects to the expected page.""" object = factories.WorkspaceFactory.create() # Need to use the client instead of RequestFactory to check redirection url. api_url = self.get_api_url(object.billing_project.name, object.name) - self.anvil_response_mock.add( - responses.DELETE, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.DELETE, api_url, status=self.api_success_code) self.client.force_login(self.user) - response = self.client.post( - self.get_url(object.billing_project.name, object.name), {"submit": ""} - ) + response = self.client.post(self.get_url(object.billing_project.name, object.name), {"submit": ""}) self.assertEqual(response.status_code, 302) self.assertRedirects( response, @@ -12219,18 +10881,12 @@ def test_adapter_success_url(self): """Redirects to the expected page.""" # Register a new adapter. workspace_adapter_registry.register(TestWorkspaceAdapter) - object = factories.WorkspaceFactory.create( - workspace_type=TestWorkspaceAdapter().get_type() - ) + object = factories.WorkspaceFactory.create(workspace_type=TestWorkspaceAdapter().get_type()) # Need to use the client instead of RequestFactory to check redirection url. api_url = self.get_api_url(object.billing_project.name, object.name) - self.anvil_response_mock.add( - responses.DELETE, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.DELETE, api_url, status=self.api_success_code) self.client.force_login(self.user) - response = self.client.post( - self.get_url(object.billing_project.name, object.name), {"submit": ""} - ) + response = self.client.post(self.get_url(object.billing_project.name, object.name), {"submit": ""}) self.assertEqual(response.status_code, 302) self.assertRedirects( response, @@ -12252,9 +10908,7 @@ def test_api_error(self): json={"message": "workspace delete test error"}, ) self.client.force_login(self.user) - response = self.client.post( - self.get_url(object.billing_project.name, object.name), {"submit": ""} - ) + response = self.client.post(self.get_url(object.billing_project.name, object.name), {"submit": ""}) self.assertEqual(response.status_code, 200) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) @@ -12312,9 +10966,7 @@ def test_post_does_not_delete_when_workspace_data_has_protected_fk_to_another_mo def test_get_is_locked(self): """View redirects with a get request if the workspace is locked.""" - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") object = factories.DefaultWorkspaceDataFactory.create( workspace__billing_project=billing_project, workspace__name="test-workspace", @@ -12333,15 +10985,11 @@ def test_get_is_locked(self): # With a message. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.WorkspaceDelete.message_workspace_locked, str(messages[0]) - ) + self.assertEqual(views.WorkspaceDelete.message_workspace_locked, str(messages[0])) def test_post_is_locked(self): """View redirects with a post request if the workspace is locked.""" - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") object = factories.DefaultWorkspaceDataFactory.create( workspace__billing_project=billing_project, workspace__name="test-workspace", @@ -12361,9 +11009,7 @@ def test_post_is_locked(self): # With a message. messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.WorkspaceDelete.message_workspace_locked, str(messages[0]) - ) + self.assertEqual(views.WorkspaceDelete.message_workspace_locked, str(messages[0])) class WorkspaceAutocompleteTest(TestCase): @@ -12373,9 +11019,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -12390,9 +11034,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.""" @@ -12402,13 +11044,9 @@ def test_status_code_with_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -12417,9 +11055,7 @@ def test_access_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): @@ -12430,10 +11066,7 @@ def test_returns_all_objects(self): groups = factories.WorkspaceFactory.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([group.pk for group in groups])) @@ -12442,10 +11075,7 @@ def test_returns_correct_object_match(self): workspace = factories.WorkspaceFactory.create(name="test-workspace") self.client.force_login(self.user) response = self.client.get(self.get_url(), {"q": "test-workspace"}) - 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], workspace.pk) @@ -12454,10 +11084,7 @@ def test_returns_correct_object_starting_with_query(self): workspace = factories.WorkspaceFactory.create(name="test-workspace") self.client.force_login(self.user) response = self.client.get(self.get_url(), {"q": "test"}) - 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], workspace.pk) @@ -12466,10 +11093,7 @@ def test_returns_correct_object_containing_query(self): workspace = factories.WorkspaceFactory.create(name="test-workspace") self.client.force_login(self.user) response = self.client.get(self.get_url(), {"q": "work"}) - 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], workspace.pk) @@ -12478,10 +11102,7 @@ def test_returns_correct_object_case_insensitive(self): workspace = factories.WorkspaceFactory.create(name="test-workspace") self.client.force_login(self.user) response = self.client.get(self.get_url(), {"q": "TEST-WORKSPACE"}) - 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], workspace.pk) @@ -12495,9 +11116,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.default_workspace_type = DefaultWorkspaceAdapter().get_type() workspace_adapter_registry.register(TestWorkspaceAdapter) @@ -12507,9 +11126,7 @@ def tearDown(self): def get_url(self, *args): """Get the url for the view being tested.""" - return reverse( - "anvil_consortium_manager:workspaces:autocomplete_by_type", args=args - ) + return reverse("anvil_consortium_manager:workspaces:autocomplete_by_type", args=args) def get_view(self): """Return the view being tested.""" @@ -12521,9 +11138,7 @@ def test_view_redirect_not_logged_in(self): response = self.client.get(self.get_url(self.default_workspace_type)) self.assertRedirects( response, - resolve_url(settings.LOGIN_URL) - + "?next=" - + self.get_url(self.default_workspace_type), + resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(self.default_workspace_type), ) def test_status_code_with_user_permission(self): @@ -12534,13 +11149,9 @@ def test_status_code_with_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url(self.default_workspace_type)) request.user = user @@ -12549,9 +11160,7 @@ def test_access_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(self.default_workspace_type)) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -12569,76 +11178,43 @@ def test_returns_all_objects(self): workspaces = factories.DefaultWorkspaceDataFactory.create_batch(10) self.client.force_login(self.user) response = self.client.get(self.get_url(self.default_workspace_type)) - 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([workspace.pk for workspace in workspaces]) - ) + self.assertEqual(sorted(returned_ids), sorted([workspace.pk for workspace in workspaces])) def test_returns_correct_object_match(self): """Queryset returns the correct objects when query matches the name.""" - workspace = factories.DefaultWorkspaceDataFactory.create( - workspace__name="test-workspace" - ) + workspace = factories.DefaultWorkspaceDataFactory.create(workspace__name="test-workspace") self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.default_workspace_type), {"q": "test-workspace"} - ) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + response = self.client.get(self.get_url(self.default_workspace_type), {"q": "test-workspace"}) + 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], workspace.pk) def test_returns_correct_object_starting_with_query(self): """Queryset returns the correct objects when query matches the beginning of the name.""" - workspace = factories.DefaultWorkspaceDataFactory.create( - workspace__name="test-workspace" - ) + workspace = factories.DefaultWorkspaceDataFactory.create(workspace__name="test-workspace") self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.default_workspace_type), {"q": "test"} - ) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + response = self.client.get(self.get_url(self.default_workspace_type), {"q": "test"}) + 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], workspace.pk) def test_returns_correct_object_containing_query(self): """Queryset returns the correct objects when the name contains the query.""" - workspace = factories.DefaultWorkspaceDataFactory.create( - workspace__name="test-workspace" - ) + workspace = factories.DefaultWorkspaceDataFactory.create(workspace__name="test-workspace") self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.default_workspace_type), {"q": "work"} - ) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + response = self.client.get(self.get_url(self.default_workspace_type), {"q": "work"}) + 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], workspace.pk) def test_returns_correct_object_case_insensitive(self): """Queryset returns the correct objects when query matches the beginning of the name.""" - workspace = factories.DefaultWorkspaceDataFactory.create( - workspace__name="test-workspace" - ) + workspace = factories.DefaultWorkspaceDataFactory.create(workspace__name="test-workspace") self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.default_workspace_type), {"q": "TEST-WORKSPACE"} - ) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + response = self.client.get(self.get_url(self.default_workspace_type), {"q": "TEST-WORKSPACE"}) + 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], workspace.pk) @@ -12648,19 +11224,11 @@ def test_only_specified_workspace_type(self): other_workspace = TestWorkspaceDataFactory.create() self.client.force_login(self.user) response = self.client.get(self.get_url(workspace.workspace.workspace_type)) - 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], workspace.pk) - response = self.client.get( - self.get_url(other_workspace.workspace.workspace_type) - ) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + response = self.client.get(self.get_url(other_workspace.workspace.workspace_type)) + 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], other_workspace.pk) @@ -12670,13 +11238,8 @@ def test_custom_autocomplete_method(self): # Workspace that should not match the custom autocomplete filtering. TestWorkspaceDataFactory.create(workspace__name="TEST-WORKSPACE") self.client.force_login(self.user) - response = self.client.get( - self.get_url(workspace_1.workspace.workspace_type), {"q": "TEST"} - ) - returned_ids = [ - int(x["id"]) - for x in json.loads(response.content.decode("utf-8"))["results"] - ] + response = self.client.get(self.get_url(workspace_1.workspace.workspace_type), {"q": "TEST"}) + 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], workspace_1.pk) @@ -12688,16 +11251,9 @@ def test_custom_autocomplete_with_forwarded_value(self): self.client.force_login(self.user) response = self.client.get( self.get_url(workspace.workspace.workspace_type), - { - "forward": json.dumps( - {"billing_project": workspace.workspace.billing_project.pk} - ) - }, + {"forward": json.dumps({"billing_project": workspace.workspace.billing_project.pk})}, ) - 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], workspace.pk) @@ -12712,9 +11268,7 @@ def setUp(self): # Create a user with only view permission. self.user = User.objects.create_user(username="test", password="test") self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -12724,9 +11278,7 @@ def get_url(self, *args): def get_api_url(self): return self.api_client.rawls_entry_point + "/api/workspaces" - def get_api_workspace_json( - self, billing_project_name, workspace_name, access, auth_domains=[] - ): + def get_api_workspace_json(self, billing_project_name, workspace_name, access, auth_domains=[]): """Return the json dictionary for a single workspace on AnVIL.""" return { "accessLevel": access, @@ -12769,9 +11321,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.""" @@ -12788,13 +11338,9 @@ def test_status_code_with_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -12803,9 +11349,7 @@ def test_access_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): @@ -12836,9 +11380,7 @@ def test_audit_verified(self): self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertIn("verified_table", response.context_data) - self.assertIsInstance( - response.context_data["verified_table"], audit.VerifiedTable - ) + self.assertIsInstance(response.context_data["verified_table"], audit.VerifiedTable) self.assertEqual(len(response.context_data["verified_table"].rows), 0) def test_audit_verified_one_record(self): @@ -12849,16 +11391,10 @@ def test_audit_verified_one_record(self): responses.GET, api_url, status=200, - json=[ - self.get_api_workspace_json( - workspace.billing_project.name, workspace.name, "OWNER" - ) - ], + json=[self.get_api_workspace_json(workspace.billing_project.name, workspace.name, "OWNER")], ) # Response to check workspace access. - workspace_acl_url = self.get_api_workspace_acl_url( - workspace.billing_project.name, workspace.name - ) + workspace_acl_url = self.get_api_workspace_acl_url(workspace.billing_project.name, workspace.name) self.anvil_response_mock.add( responses.GET, workspace_acl_url, @@ -12894,11 +11430,7 @@ def test_audit_errors_one_record(self): api_url, status=200, # Error - we are not an owner. - json=[ - self.get_api_workspace_json( - workspace.billing_project.name, workspace.name, "READER" - ) - ], + json=[self.get_api_workspace_json(workspace.billing_project.name, workspace.name, "READER")], ) self.client.force_login(self.user) response = self.client.get(self.get_url()) @@ -12917,9 +11449,7 @@ def test_audit_not_in_app(self): self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertIn("not_in_app_table", response.context_data) - self.assertIsInstance( - response.context_data["not_in_app_table"], audit.NotInAppTable - ) + self.assertIsInstance(response.context_data["not_in_app_table"], audit.NotInAppTable) self.assertEqual(len(response.context_data["not_in_app_table"].rows), 0) def test_audit_not_in_app_one_record(self): @@ -12959,11 +11489,7 @@ def test_audit_ok_is_not_ok(self): api_url, status=200, # Error - we are not admin. - json=[ - self.get_api_workspace_json( - workspace.billing_project.name, workspace.name, "READER" - ) - ], + json=[self.get_api_workspace_json(workspace.billing_project.name, workspace.name, "READER")], ) self.client.force_login(self.user) response = self.client.get(self.get_url()) @@ -12981,16 +11507,12 @@ 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) # Set this variable here because it will include the service account. # Tests can update it with the update_api_response method. self.api_response = {"acl": {}} - self.update_api_response( - self.service_account_email, "OWNER", can_compute=True, can_share=True - ) + self.update_api_response(self.service_account_email, "OWNER", can_compute=True, can_share=True) # Create a workspace for use in tests. self.workspace = factories.WorkspaceFactory.create() self.api_url = ( @@ -13042,20 +11564,14 @@ def test_status_code_with_user_permission(self): json=self.api_response, ) self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.workspace.billing_project.name, self.workspace.name) - ) + response = self.client.get(self.get_url(self.workspace.billing_project.name, self.workspace.name)) self.assertEqual(response.status_code, 200) def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo", "bar")) request.user = user @@ -13064,9 +11580,7 @@ def test_access_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("foo", "bar")) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -13081,9 +11595,7 @@ def test_template(self): json=self.api_response, ) self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.workspace.billing_project.name, self.workspace.name) - ) + response = self.client.get(self.get_url(self.workspace.billing_project.name, self.workspace.name)) self.assertEqual(response.status_code, 200) def test_audit_verified(self): @@ -13095,14 +11607,10 @@ def test_audit_verified(self): status=200, json=self.api_response, ) - self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.workspace.billing_project.name, self.workspace.name) - ) - self.assertIn("verified_table", response.context_data) - self.assertIsInstance( - response.context_data["verified_table"], audit.VerifiedTable - ) + self.client.force_login(self.user) + response = self.client.get(self.get_url(self.workspace.billing_project.name, self.workspace.name)) + self.assertIn("verified_table", response.context_data) + self.assertIsInstance(response.context_data["verified_table"], audit.VerifiedTable) self.assertEqual(len(response.context_data["verified_table"].rows), 0) def test_audit_verified_one_record(self): @@ -13117,9 +11625,7 @@ def test_audit_verified_one_record(self): json=self.api_response, ) self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.workspace.billing_project.name, self.workspace.name) - ) + response = self.client.get(self.get_url(self.workspace.billing_project.name, self.workspace.name)) self.assertIn("verified_table", response.context_data) self.assertEqual(len(response.context_data["verified_table"].rows), 1) @@ -13133,9 +11639,7 @@ def test_audit_errors(self): json=self.api_response, ) self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.workspace.billing_project.name, self.workspace.name) - ) + response = self.client.get(self.get_url(self.workspace.billing_project.name, self.workspace.name)) self.assertIn("error_table", response.context_data) self.assertIsInstance(response.context_data["error_table"], audit.ErrorTable) self.assertEqual(len(response.context_data["error_table"].rows), 0) @@ -13153,9 +11657,7 @@ def test_audit_errors_one_record(self): json=self.api_response, ) self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.workspace.billing_project.name, self.workspace.name) - ) + response = self.client.get(self.get_url(self.workspace.billing_project.name, self.workspace.name)) self.assertIn("error_table", response.context_data) self.assertEqual(len(response.context_data["error_table"].rows), 1) @@ -13170,13 +11672,9 @@ def test_audit_not_in_app(self): # json=self.get_api_group_members_json_response(), ) self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.workspace.billing_project.name, self.workspace.name) - ) + response = self.client.get(self.get_url(self.workspace.billing_project.name, self.workspace.name)) self.assertIn("not_in_app_table", response.context_data) - self.assertIsInstance( - response.context_data["not_in_app_table"], audit.NotInAppTable - ) + self.assertIsInstance(response.context_data["not_in_app_table"], audit.NotInAppTable) self.assertEqual(len(response.context_data["not_in_app_table"].rows), 0) def test_audit_not_in_app_one_record(self): @@ -13189,9 +11687,7 @@ def test_audit_not_in_app_one_record(self): json=self.api_response, ) self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.workspace.billing_project.name, self.workspace.name) - ) + response = self.client.get(self.get_url(self.workspace.billing_project.name, self.workspace.name)) self.assertIn("not_in_app_table", response.context_data) self.assertEqual(len(response.context_data["not_in_app_table"].rows), 1) @@ -13206,9 +11702,7 @@ def test_audit_ok_is_ok(self): # json=self.get_api_group_members_json_response(), ) self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.workspace.billing_project.name, self.workspace.name) - ) + response = self.client.get(self.get_url(self.workspace.billing_project.name, self.workspace.name)) self.assertIn("audit_ok", response.context_data) self.assertEqual(response.context_data["audit_ok"], True) @@ -13224,18 +11718,14 @@ def test_audit_ok_is_not_ok(self): # json=self.get_api_group_members_json_response(members=["foo@bar.com"]), ) self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.workspace.billing_project.name, self.workspace.name) - ) + response = self.client.get(self.get_url(self.workspace.billing_project.name, self.workspace.name)) self.assertIn("audit_ok", response.context_data) self.assertEqual(response.context_data["audit_ok"], False) def test_workspace_does_not_exist_in_app(self): """Raises a 404 error with an invalid workspace slug.""" billing_project = factories.BillingProjectFactory.create() - request = self.factory.get( - self.get_url(billing_project.name, self.workspace.name) - ) + request = self.factory.get(self.get_url(billing_project.name, self.workspace.name)) request.user = self.user with self.assertRaises(Http404): self.get_view()( @@ -13249,9 +11739,7 @@ def test_billing_project_does_not_exist_in_app(self): request = self.factory.get(self.get_url("foo", self.workspace.name)) request.user = self.user with self.assertRaises(Http404): - self.get_view()( - request, billing_project_slug="foo", workspace_slug=self.workspace.name - ) + self.get_view()(request, billing_project_slug="foo", workspace_slug=self.workspace.name) class GroupGroupMembershipDetailTest(TestCase): @@ -13261,16 +11749,12 @@ 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): """Get the url for the view being tested.""" - return reverse( - "anvil_consortium_manager:managed_groups:member_groups:detail", args=args - ) + return reverse("anvil_consortium_manager:managed_groups:member_groups:detail", args=args) def get_view(self): """Return the view being tested.""" @@ -13282,29 +11766,21 @@ def test_view_redirect_not_logged_in(self): response = self.client.get(self.get_url("parent", "child")) self.assertRedirects( response, - resolve_url(settings.LOGIN_URL) - + "?next=" - + self.get_url("parent", "child"), + resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url("parent", "child"), ) def test_status_code_with_user_permission(self): """Returns successful response code.""" obj = factories.GroupGroupMembershipFactory.create() self.client.force_login(self.user) - response = self.client.get( - self.get_url(obj.parent_group.name, obj.child_group.name) - ) + response = self.client.get(self.get_url(obj.parent_group.name, obj.child_group.name)) self.assertEqual(response.status_code, 200) def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo", "bar")) request.user = user @@ -13313,15 +11789,11 @@ def test_access_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("parent", "child")) request.user = user_no_perms with self.assertRaises(PermissionDenied): - self.get_view()( - request, parent_group_slug="parent", child_group_slug="child" - ) + self.get_view()(request, parent_group_slug="parent", child_group_slug="child") def test_view_status_code_with_invalid_pk(self): """Raises a 404 error with an invalid object pk.""" @@ -13329,20 +11801,14 @@ def test_view_status_code_with_invalid_pk(self): request = self.factory.get(self.get_url("parent", "child")) request.user = self.user with self.assertRaises(Http404): - self.get_view()( - request, parent_group_slug="parent", child_group_slug="child" - ) + self.get_view()(request, parent_group_slug="parent", child_group_slug="child") def test_edit_permission(self): """Links to delete url appears if the user has edit permission.""" edit_user = User.objects.create_user(username="edit", password="test") edit_user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ), - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ), + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME), + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME), ) self.client.force_login(edit_user) obj = factories.GroupGroupMembershipFactory.create() @@ -13364,9 +11830,7 @@ def test_view_permission(self): """Links to delete url appears if the user has edit permission.""" view_user = User.objects.create_user(username="view", password="test") view_user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ), + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME), ) self.client.force_login(view_user) obj = factories.GroupGroupMembershipFactory.create() @@ -13411,14 +11875,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -13430,24 +11890,14 @@ def get_view(self): return views.GroupGroupMembershipCreate.as_view() def get_api_url(self, group_name, role, email): - url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/" - + group_name - + "/" - + role - + "/" - + email - ) + url = self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/" + role + "/" + email return url 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.""" @@ -13457,13 +11907,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user_with_view_perm @@ -13472,13 +11918,9 @@ def test_access_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -13487,9 +11929,7 @@ def test_access_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): @@ -13500,18 +11940,14 @@ def test_has_form_in_context(self): self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertTrue("form" in response.context_data) - self.assertIsInstance( - response.context_data["form"], forms.GroupGroupMembershipForm - ) + self.assertIsInstance(response.context_data["form"], forms.GroupGroupMembershipForm) def test_can_create_an_object_member(self): """Posting valid data to the form creates an object.""" parent_group = factories.ManagedGroupFactory.create(name="group-1") child_group = factories.ManagedGroupFactory.create(name="group-2") api_url = self.get_api_url(parent_group.name, "member", child_group.email) - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(), @@ -13534,9 +11970,7 @@ def test_success_message(self): parent_group = factories.ManagedGroupFactory.create(name="group-1") child_group = factories.ManagedGroupFactory.create(name="group-2") api_url = self.get_api_url(parent_group.name, "member", child_group.email) - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(), @@ -13549,18 +11983,14 @@ def test_success_message(self): ) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.GroupGroupMembershipCreate.success_message, str(messages[0]) - ) + self.assertEqual(views.GroupGroupMembershipCreate.success_message, str(messages[0])) def test_can_create_an_object_admin(self): """Posting valid data to the form creates an object.""" parent_group = factories.ManagedGroupFactory.create(name="group-1") child_group = factories.ManagedGroupFactory.create(name="group-2") api_url = self.get_api_url(parent_group.name, "admin", child_group.email) - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(), @@ -13581,9 +12011,7 @@ def test_redirects_to_list(self): parent_group = factories.ManagedGroupFactory.create(name="group-1") child_group = factories.ManagedGroupFactory.create(name="group-2") api_url = self.get_api_url(parent_group.name, "member", child_group.email) - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(), @@ -13593,15 +12021,11 @@ def test_redirects_to_list(self): "role": models.GroupGroupMembership.MEMBER, }, ) - self.assertRedirects( - response, reverse("anvil_consortium_manager:group_group_membership:list") - ) + self.assertRedirects(response, reverse("anvil_consortium_manager:group_group_membership:list")) def test_cannot_create_duplicate_object_with_same_role(self): """Cannot create a second GroupGroupMembership object for the same parent and child with the same role.""" - obj = factories.GroupGroupMembershipFactory.create( - role=models.GroupGroupMembership.MEMBER - ) + obj = factories.GroupGroupMembershipFactory.create(role=models.GroupGroupMembership.MEMBER) self.client.force_login(self.user) response = self.client.post( self.get_url(), @@ -13622,9 +12046,7 @@ def test_cannot_create_duplicate_object_with_same_role(self): def test_cannot_create_duplicate_object_with_different_role(self): """Cannot create a second GroupGroupMembership object for the same parent and child with a different role.""" - obj = factories.GroupGroupMembershipFactory.create( - role=models.GroupGroupMembership.MEMBER - ) + obj = factories.GroupGroupMembershipFactory.create(role=models.GroupGroupMembership.MEMBER) self.client.force_login(self.user) response = self.client.post( self.get_url(), @@ -13651,13 +12073,9 @@ def test_can_add_two_groups_to_one_parent(self): group_1 = factories.ManagedGroupFactory.create(name="test-group-1") group_2 = factories.ManagedGroupFactory.create(name="test-group-2") parent = factories.ManagedGroupFactory.create(name="parent-group") - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=group_1 - ) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=group_1) api_url = self.get_api_url(parent.name, "member", group_2.email) - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(), @@ -13674,13 +12092,9 @@ def test_can_add_a_child_group_to_two_parents(self): group_1 = factories.ManagedGroupFactory.create(name="test-group-1") group_2 = factories.ManagedGroupFactory.create(name="test-group-2") child = factories.ManagedGroupFactory.create(name="child_1-group") - factories.GroupGroupMembershipFactory.create( - parent_group=group_1, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=group_1, child_group=child) api_url = self.get_api_url(group_2.name, "member", child.email) - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(), @@ -13853,12 +12267,8 @@ def test_cant_add_circular_relationship(self): grandparent = factories.ManagedGroupFactory.create() parent = factories.ManagedGroupFactory.create() child = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent, child_group=parent - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent, child_group=parent) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) self.client.force_login(self.user) response = self.client.post( self.get_url(), @@ -13876,9 +12286,7 @@ def test_cant_add_circular_relationship(self): def test_cannot_add_child_group_if_parent_not_managed_by_app(self): """Cannot add a child group to a parent group if the parent group is not managed by the app.""" - parent_group = factories.ManagedGroupFactory.create( - name="group-1", is_managed_by_app=False - ) + parent_group = factories.ManagedGroupFactory.create(name="group-1", is_managed_by_app=False) child_group = factories.ManagedGroupFactory.create(name="group-2") self.client.force_login(self.user) response = self.client.post( @@ -14057,23 +12465,17 @@ 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) self.parent_group = factories.ManagedGroupFactory.create() self.child_group = factories.ManagedGroupFactory.create() def get_url(self, *args): """Get the url for the view being tested.""" - return reverse( - "anvil_consortium_manager:managed_groups:member_groups:new", args=args - ) + return reverse("anvil_consortium_manager:managed_groups:member_groups:new", args=args) def get_view(self): """Return the view being tested.""" @@ -14097,9 +12499,7 @@ def test_view_redirect_not_logged_in(self): response = self.client.get(self.get_url(self.parent_group.name)) self.assertRedirects( response, - resolve_url(settings.LOGIN_URL) - + "?next=" - + self.get_url(self.parent_group.name), + resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(self.parent_group.name), ) def test_status_code_with_user_permission(self): @@ -14110,13 +12510,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url(self.parent_group.name)) request.user = user_with_view_perm @@ -14125,13 +12521,9 @@ def test_access_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo")) request.user = user @@ -14140,9 +12532,7 @@ def test_access_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(self.parent_group.name)) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -14153,25 +12543,19 @@ def test_has_form_in_context(self): self.client.force_login(self.user) response = self.client.get(self.get_url(self.parent_group.name)) self.assertTrue("form" in response.context_data) - self.assertIsInstance( - response.context_data["form"], forms.GroupGroupMembershipForm - ) + self.assertIsInstance(response.context_data["form"], forms.GroupGroupMembershipForm) def test_form_hidden_input(self): """The proper inputs are hidden in the form.""" self.client.force_login(self.user) response = self.client.get(self.get_url(self.parent_group.name)) self.assertTrue("form" in response.context_data) - self.assertIsInstance( - response.context_data["form"].fields["parent_group"].widget, HiddenInput - ) + self.assertIsInstance(response.context_data["form"].fields["parent_group"].widget, HiddenInput) def test_can_create_an_object_member(self): """Posting valid data to the form creates an object.""" api_url = self.get_api_url("member") - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(self.parent_group.name), @@ -14194,9 +12578,7 @@ def test_can_create_an_object_member(self): def test_success_message(self): """Response includes a success message if successful.""" api_url = self.get_api_url("member") - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(self.parent_group.name), @@ -14209,16 +12591,12 @@ def test_success_message(self): ) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.GroupGroupMembershipCreateByParent.success_message, str(messages[0]) - ) + self.assertEqual(views.GroupGroupMembershipCreateByParent.success_message, str(messages[0])) def test_can_create_an_object_admin(self): """Posting valid data to the form creates an object.""" api_url = self.get_api_url("admin") - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(self.parent_group.name), @@ -14236,9 +12614,7 @@ def test_can_create_an_object_admin(self): def test_redirects_to_detail(self): """After successfully creating an object, view redirects to the object's detail page.""" api_url = self.get_api_url("member") - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(self.parent_group.name), @@ -14255,9 +12631,7 @@ def test_redirects_to_detail(self): def test_cannot_create_duplicate_object(self): """Cannot create a second GroupGroupMembership object for the same parent and child with the same role.""" - obj = factories.GroupGroupMembershipFactory.create( - role=models.GroupGroupMembership.MEMBER - ) + obj = factories.GroupGroupMembershipFactory.create(role=models.GroupGroupMembership.MEMBER) self.client.force_login(self.user) response = self.client.post( self.get_url(obj.parent_group.name), @@ -14416,12 +12790,8 @@ def test_cant_add_circular_relationship(self): grandparent = factories.ManagedGroupFactory.create() parent = factories.ManagedGroupFactory.create() child = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent, child_group=parent - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent, child_group=parent) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) self.client.force_login(self.user) response = self.client.post( self.get_url(child.name), @@ -14603,23 +12973,17 @@ 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) self.parent_group = factories.ManagedGroupFactory.create() self.child_group = factories.ManagedGroupFactory.create() def get_url(self, *args): """Get the url for the view being tested.""" - return reverse( - "anvil_consortium_manager:managed_groups:add_to_group", args=args - ) + return reverse("anvil_consortium_manager:managed_groups:add_to_group", args=args) def get_view(self): """Return the view being tested.""" @@ -14643,9 +13007,7 @@ def test_view_redirect_not_logged_in(self): response = self.client.get(self.get_url(self.child_group.name)) self.assertRedirects( response, - resolve_url(settings.LOGIN_URL) - + "?next=" - + self.get_url(self.child_group.name), + resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(self.child_group.name), ) def test_status_code_with_user_permission(self): @@ -14656,13 +13018,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url(self.child_group.name)) request.user = user_with_view_perm @@ -14671,13 +13029,9 @@ def test_access_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo")) request.user = user @@ -14686,9 +13040,7 @@ def test_access_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(self.child_group.name)) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -14699,25 +13051,19 @@ def test_has_form_in_context(self): self.client.force_login(self.user) response = self.client.get(self.get_url(self.child_group.name)) self.assertTrue("form" in response.context_data) - self.assertIsInstance( - response.context_data["form"], forms.GroupGroupMembershipForm - ) + self.assertIsInstance(response.context_data["form"], forms.GroupGroupMembershipForm) def test_form_hidden_input(self): """The proper inputs are hidden in the form.""" self.client.force_login(self.user) response = self.client.get(self.get_url(self.child_group.name)) self.assertTrue("form" in response.context_data) - self.assertIsInstance( - response.context_data["form"].fields["child_group"].widget, HiddenInput - ) + self.assertIsInstance(response.context_data["form"].fields["child_group"].widget, HiddenInput) def test_can_create_an_object_member(self): """Posting valid data to the form creates an object.""" api_url = self.get_api_url("member") - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(self.child_group.name), @@ -14740,9 +13086,7 @@ def test_can_create_an_object_member(self): def test_success_message(self): """Response includes a success message if successful.""" api_url = self.get_api_url("member") - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(self.child_group.name), @@ -14755,16 +13099,12 @@ def test_success_message(self): ) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.GroupGroupMembershipCreateByParent.success_message, str(messages[0]) - ) + self.assertEqual(views.GroupGroupMembershipCreateByParent.success_message, str(messages[0])) def test_can_create_an_object_admin(self): """Posting valid data to the form creates an object.""" api_url = self.get_api_url("admin") - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(self.child_group.name), @@ -14782,9 +13122,7 @@ def test_can_create_an_object_admin(self): def test_redirects_to_detail(self): """After successfully creating an object, view redirects to the object's detail page.""" api_url = self.get_api_url("member") - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(self.child_group.name), @@ -14801,9 +13139,7 @@ def test_redirects_to_detail(self): def test_cannot_create_duplicate_object(self): """Cannot create a second GroupGroupMembership object for the same parent and child with the same role.""" - obj = factories.GroupGroupMembershipFactory.create( - role=models.GroupGroupMembership.MEMBER - ) + obj = factories.GroupGroupMembershipFactory.create(role=models.GroupGroupMembership.MEMBER) self.client.force_login(self.user) response = self.client.post( self.get_url(obj.child_group.name), @@ -14962,12 +13298,8 @@ def test_cant_add_circular_relationship(self): grandparent = factories.ManagedGroupFactory.create() parent = factories.ManagedGroupFactory.create() child = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent, child_group=parent - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent, child_group=parent) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) self.client.force_login(self.user) response = self.client.post( self.get_url(grandparent.name), @@ -15110,14 +13442,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) self.parent_group = factories.ManagedGroupFactory.create() self.child_group = factories.ManagedGroupFactory.create() @@ -15148,37 +13476,25 @@ def get_api_url(self, role): 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.parent_group.name, self.child_group.name) - ) + response = self.client.get(self.get_url(self.parent_group.name, self.child_group.name)) self.assertRedirects( response, - resolve_url(settings.LOGIN_URL) - + "?next=" - + self.get_url(self.parent_group.name, self.child_group.name), + resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(self.parent_group.name, self.child_group.name), ) 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.parent_group.name, self.child_group.name) - ) + response = self.client.get(self.get_url(self.parent_group.name, self.child_group.name)) self.assertEqual(response.status_code, 200) 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) - ) - request = self.factory.get( - self.get_url(self.parent_group.name, self.child_group.name) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) + request = self.factory.get(self.get_url(self.parent_group.name, self.child_group.name)) request.user = user_with_view_perm with self.assertRaises(PermissionDenied): self.get_view()( @@ -15189,13 +13505,9 @@ def test_access_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo", "bar")) request.user = user @@ -15204,12 +13516,8 @@ def test_access_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" - ) - request = self.factory.get( - self.get_url(self.parent_group.name, self.child_group.name) - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") + request = self.factory.get(self.get_url(self.parent_group.name, self.child_group.name)) request.user = user_no_perms with self.assertRaises(PermissionDenied): self.get_view()( @@ -15221,34 +13529,22 @@ def test_access_without_user_permission(self): def test_has_form_in_context(self): """Response includes a form.""" self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.parent_group.name, self.child_group.name) - ) + response = self.client.get(self.get_url(self.parent_group.name, self.child_group.name)) self.assertTrue("form" in response.context_data) - self.assertIsInstance( - response.context_data["form"], forms.GroupGroupMembershipForm - ) + self.assertIsInstance(response.context_data["form"], forms.GroupGroupMembershipForm) def test_form_hidden_input(self): """The proper inputs are hidden in the form.""" self.client.force_login(self.user) - response = self.client.get( - self.get_url(self.parent_group.name, self.child_group.name) - ) + response = self.client.get(self.get_url(self.parent_group.name, self.child_group.name)) self.assertTrue("form" in response.context_data) - self.assertIsInstance( - response.context_data["form"].fields["child_group"].widget, HiddenInput - ) - self.assertIsInstance( - response.context_data["form"].fields["parent_group"].widget, HiddenInput - ) + self.assertIsInstance(response.context_data["form"].fields["child_group"].widget, HiddenInput) + self.assertIsInstance(response.context_data["form"].fields["parent_group"].widget, HiddenInput) def test_can_create_an_object_member(self): """Posting valid data to the form creates an object.""" api_url = self.get_api_url("member") - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) self.client.force_login(self.user) response = self.client.post( @@ -15272,9 +13568,7 @@ def test_can_create_an_object_member(self): def test_success_message(self): """Response includes a success message if successful.""" api_url = self.get_api_url("member") - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(self.parent_group.name, self.child_group.name), @@ -15295,9 +13589,7 @@ def test_success_message(self): def test_can_create_an_object_admin(self): """Posting valid data to the form creates an object.""" api_url = self.get_api_url("admin") - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(self.parent_group.name, self.child_group.name), @@ -15315,9 +13607,7 @@ def test_can_create_an_object_admin(self): def test_redirects_to_detail(self): """After successfully creating an object, view redirects to the object's detail page.""" api_url = self.get_api_url("member") - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(self.parent_group.name, self.child_group.name), @@ -15334,13 +13624,9 @@ def test_redirects_to_detail(self): def test_get_duplicate_object_redirect_cannot_create_duplicate_object(self): """Cannot create a second GroupGroupMembership object for the same parent and child with the same role.""" - obj = factories.GroupGroupMembershipFactory.create( - role=models.GroupGroupMembership.MEMBER - ) + obj = factories.GroupGroupMembershipFactory.create(role=models.GroupGroupMembership.MEMBER) self.client.force_login(self.user) - response = self.client.get( - self.get_url(obj.parent_group.name, obj.child_group.name), follow=True - ) + response = self.client.get(self.get_url(obj.parent_group.name, obj.child_group.name), follow=True) self.assertRedirects(response, obj.get_absolute_url()) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) @@ -15351,9 +13637,7 @@ def test_get_duplicate_object_redirect_cannot_create_duplicate_object(self): def test_post_duplicate_object_redirect_cannot_create_duplicate_object(self): """Cannot create a second GroupGroupMembership object for the same parent and child with the same role.""" - obj = factories.GroupGroupMembershipFactory.create( - role=models.GroupGroupMembership.MEMBER - ) + obj = factories.GroupGroupMembershipFactory.create(role=models.GroupGroupMembership.MEMBER) self.client.force_login(self.user) response = self.client.post( self.get_url(obj.parent_group.name, obj.child_group.name), @@ -15377,9 +13661,7 @@ def test_get_parent_group_not_found(self): request = self.factory.get(self.get_url("foo", self.child_group.name)) request.user = self.user with self.assertRaises(Http404): - self.get_view()( - request, parent_group_slug="foo", child_group_slug=self.child_group.name - ) + self.get_view()(request, parent_group_slug="foo", child_group_slug=self.child_group.name) self.assertEqual(models.GroupGroupMembership.objects.count(), 0) def test_post_parent_group_not_found(self): @@ -15394,9 +13676,7 @@ def test_post_parent_group_not_found(self): ) request.user = self.user with self.assertRaises(Http404): - self.get_view()( - request, parent_group_slug="foo", child_group_slug=self.child_group.name - ) + self.get_view()(request, parent_group_slug="foo", child_group_slug=self.child_group.name) self.assertEqual(models.GroupGroupMembership.objects.count(), 0) def test_get_child_group_not_found(self): @@ -15451,9 +13731,7 @@ def test_invalid_input_role(self): def test_post_blank_data(self): """Posting blank data does not create an object.""" self.client.force_login(self.user) - response = self.client.post( - self.get_url(self.parent_group.name, self.child_group.name), {} - ) + response = self.client.post(self.get_url(self.parent_group.name, self.child_group.name), {}) self.assertEqual(response.status_code, 200) form = response.context_data["form"] self.assertFalse(form.is_valid()) @@ -15556,12 +13834,8 @@ def test_cant_add_circular_relationship(self): grandparent = factories.ManagedGroupFactory.create() parent = factories.ManagedGroupFactory.create() child = factories.ManagedGroupFactory.create() - factories.GroupGroupMembershipFactory.create( - parent_group=grandparent, child_group=parent - ) - factories.GroupGroupMembershipFactory.create( - parent_group=parent, child_group=child - ) + factories.GroupGroupMembershipFactory.create(parent_group=grandparent, child_group=parent) + factories.GroupGroupMembershipFactory.create(parent_group=parent, child_group=child) self.client.force_login(self.user) response = self.client.post( self.get_url(child.name, grandparent.name), @@ -15740,16 +14014,12 @@ 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): """Get the url for the view being tested.""" - return reverse( - "anvil_consortium_manager:group_group_membership:list", args=args - ) + return reverse("anvil_consortium_manager:group_group_membership:list", args=args) def get_view(self): """Return the view being tested.""" @@ -15759,9 +14029,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.""" @@ -15771,13 +14039,9 @@ def test_status_code_with_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -15786,9 +14050,7 @@ def test_access_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): @@ -15798,9 +14060,7 @@ def test_view_has_correct_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.GroupGroupMembershipTable - ) + self.assertIsInstance(response.context_data["table"], tables.GroupGroupMembershipTable) def test_view_with_no_objects(self): self.client.force_login(self.user) @@ -15837,36 +14097,22 @@ 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) def get_url(self, *args): """Get the url for the view being tested.""" - return reverse( - "anvil_consortium_manager:managed_groups:member_groups:delete", args=args - ) + return reverse("anvil_consortium_manager:managed_groups:member_groups:delete", args=args) def get_view(self): """Return the view being tested.""" return views.GroupGroupMembershipDelete.as_view() def get_api_url(self, group_name, role, email): - url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/" - + group_name - + "/" - + role - + "/" - + email - ) + url = self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/" + role + "/" + email return url def test_view_redirect_not_logged_in(self): @@ -15875,46 +14121,32 @@ def test_view_redirect_not_logged_in(self): response = self.client.get(self.get_url("parent", "child")) self.assertRedirects( response, - resolve_url(settings.LOGIN_URL) - + "?next=" - + self.get_url("parent", "child"), + resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url("parent", "child"), ) def test_status_code_with_user_permission(self): """Returns successful response code.""" obj = factories.GroupGroupMembershipFactory.create() self.client.force_login(self.user) - response = self.client.get( - self.get_url(obj.parent_group.name, obj.child_group.name) - ) + response = self.client.get(self.get_url(obj.parent_group.name, obj.child_group.name)) self.assertEqual(response.status_code, 200) 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("parent", "child")) request.user = user_with_view_perm with self.assertRaises(PermissionDenied): - self.get_view()( - request, parent_group_slug="parent", child_group_slug="child" - ) + self.get_view()(request, parent_group_slug="parent", child_group_slug="child") def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo", "bar")) request.user = user @@ -15923,40 +14155,26 @@ def test_access_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("parent", "child")) request.user = user_no_perms with self.assertRaises(PermissionDenied): - self.get_view()( - request, parent_group_slug="parent", child_group_slug="child" - ) + self.get_view()(request, parent_group_slug="parent", child_group_slug="child") def test_view_with_invalid_pk(self): """Returns a 404 when the object doesn't exist.""" request = self.factory.get(self.get_url("parent", "child")) request.user = self.user with self.assertRaises(Http404): - self.get_view()( - request, parent_group_slug="parent", child_group_slug="child" - ) + self.get_view()(request, parent_group_slug="parent", child_group_slug="child") def test_view_deletes_object(self): """Posting submit to the form successfully deletes the object.""" - obj = factories.GroupGroupMembershipFactory.create( - role=models.GroupGroupMembership.MEMBER - ) - api_url = self.get_api_url( - obj.parent_group.name, obj.role.lower(), obj.child_group.email - ) - self.anvil_response_mock.add( - responses.DELETE, api_url, status=self.api_success_code - ) + obj = factories.GroupGroupMembershipFactory.create(role=models.GroupGroupMembership.MEMBER) + api_url = self.get_api_url(obj.parent_group.name, obj.role.lower(), obj.child_group.email) + self.anvil_response_mock.add(responses.DELETE, api_url, status=self.api_success_code) self.client.force_login(self.user) - response = self.client.post( - self.get_url(obj.parent_group.name, obj.child_group.name), {"submit": ""} - ) + response = self.client.post(self.get_url(obj.parent_group.name, obj.child_group.name), {"submit": ""}) self.assertEqual(response.status_code, 302) self.assertEqual(models.GroupGroupMembership.objects.count(), 0) # History is added. @@ -15965,15 +14183,9 @@ def test_view_deletes_object(self): def test_success_message(self): """Response includes a success message if successful.""" - obj = factories.GroupGroupMembershipFactory.create( - role=models.GroupGroupMembership.MEMBER - ) - api_url = self.get_api_url( - obj.parent_group.name, obj.role.lower(), obj.child_group.email - ) - self.anvil_response_mock.add( - responses.DELETE, api_url, status=self.api_success_code - ) + obj = factories.GroupGroupMembershipFactory.create(role=models.GroupGroupMembership.MEMBER) + api_url = self.get_api_url(obj.parent_group.name, obj.role.lower(), obj.child_group.email) + self.anvil_response_mock.add(responses.DELETE, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(obj.parent_group.name, obj.child_group.name), @@ -15982,24 +14194,16 @@ def test_success_message(self): ) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.GroupGroupMembershipDelete.success_message, str(messages[0]) - ) + self.assertEqual(views.GroupGroupMembershipDelete.success_message, str(messages[0])) def test_only_deletes_specified_pk(self): """View only deletes the specified pk.""" obj = factories.GroupGroupMembershipFactory.create() other_object = factories.GroupGroupMembershipFactory.create() - api_url = self.get_api_url( - obj.parent_group.name, obj.role.lower(), obj.child_group.email - ) - self.anvil_response_mock.add( - responses.DELETE, api_url, status=self.api_success_code - ) + api_url = self.get_api_url(obj.parent_group.name, obj.role.lower(), obj.child_group.email) + self.anvil_response_mock.add(responses.DELETE, api_url, status=self.api_success_code) self.client.force_login(self.user) - response = self.client.post( - self.get_url(obj.parent_group.name, obj.child_group.name), {"submit": ""} - ) + response = self.client.post(self.get_url(obj.parent_group.name, obj.child_group.name), {"submit": ""}) self.assertEqual(response.status_code, 302) self.assertEqual(models.GroupGroupMembership.objects.count(), 1) self.assertQuerySetEqual( @@ -16011,17 +14215,11 @@ def test_success_url(self): """Redirects to the expected page.""" obj = factories.GroupGroupMembershipFactory.create() parent_group = obj.parent_group - api_url = self.get_api_url( - obj.parent_group.name, obj.role.lower(), obj.child_group.email - ) - self.anvil_response_mock.add( - responses.DELETE, api_url, status=self.api_success_code - ) + api_url = self.get_api_url(obj.parent_group.name, obj.role.lower(), obj.child_group.email) + self.anvil_response_mock.add(responses.DELETE, api_url, status=self.api_success_code) # Need to use the client instead of RequestFactory to check redirection url. self.client.force_login(self.user) - response = self.client.post( - self.get_url(obj.parent_group.name, obj.child_group.name), {"submit": ""} - ) + response = self.client.post(self.get_url(obj.parent_group.name, obj.child_group.name), {"submit": ""}) self.assertEqual(response.status_code, 302) self.assertRedirects(response, parent_group.get_absolute_url()) @@ -16029,9 +14227,7 @@ def test_api_error(self): """Shows a message if an AnVIL API error occurs.""" # Need a client to check messages. obj = factories.GroupGroupMembershipFactory.create() - api_url = self.get_api_url( - obj.parent_group.name, obj.role.lower(), obj.child_group.email - ) + api_url = self.get_api_url(obj.parent_group.name, obj.role.lower(), obj.child_group.email) self.anvil_response_mock.add( responses.DELETE, api_url, @@ -16039,9 +14235,7 @@ def test_api_error(self): json={"message": "group group membership delete test error"}, ) self.client.force_login(self.user) - response = self.client.post( - self.get_url(obj.parent_group.name, obj.child_group.name), {"submit": ""} - ) + response = self.client.post(self.get_url(obj.parent_group.name, obj.child_group.name), {"submit": ""}) self.assertEqual(response.status_code, 200) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) @@ -16056,14 +14250,10 @@ def test_get_redirect_parent_group_not_managed_by_app(self): """Redirect get when trying to delete GroupGroupMembership when a parent group is not managed by the app.""" parent_group = factories.ManagedGroupFactory.create(is_managed_by_app=False) child_group = factories.ManagedGroupFactory.create() - obj = factories.GroupGroupMembershipFactory.create( - parent_group=parent_group, child_group=child_group - ) + obj = factories.GroupGroupMembershipFactory.create(parent_group=parent_group, child_group=child_group) # Need to use a client for messages. self.client.force_login(self.user) - response = self.client.get( - self.get_url(obj.parent_group.name, obj.child_group.name), follow=True - ) + response = self.client.get(self.get_url(obj.parent_group.name, obj.child_group.name), follow=True) self.assertRedirects(response, obj.get_absolute_url()) # Check for messages. messages = [m.message for m in get_messages(response.wsgi_request)] @@ -16079,14 +14269,10 @@ def test_post_redirect_parent_group_not_managed_by_app(self): """Redirect post when trying to delete GroupGroupMembership when a parent group is not managed by the app.""" parent_group = factories.ManagedGroupFactory.create(is_managed_by_app=False) child_group = factories.ManagedGroupFactory.create() - obj = factories.GroupGroupMembershipFactory.create( - parent_group=parent_group, child_group=child_group - ) + obj = factories.GroupGroupMembershipFactory.create(parent_group=parent_group, child_group=child_group) # Need to use a client for messages. self.client.force_login(self.user) - response = self.client.post( - self.get_url(obj.parent_group.name, obj.child_group.name), follow=True - ) + response = self.client.post(self.get_url(obj.parent_group.name, obj.child_group.name), follow=True) self.assertRedirects(response, obj.get_absolute_url()) # Check for messages. messages = [m.message for m in get_messages(response.wsgi_request)] @@ -16100,9 +14286,7 @@ def test_post_redirect_parent_group_not_managed_by_app(self): def test_api_error_400(self): obj = factories.GroupGroupMembershipFactory.create() - api_url = self.get_api_url( - obj.parent_group.name, obj.role.lower(), obj.child_group.email - ) + api_url = self.get_api_url(obj.parent_group.name, obj.role.lower(), obj.child_group.email) self.anvil_response_mock.add( responses.DELETE, api_url, @@ -16110,9 +14294,7 @@ def test_api_error_400(self): json={"message": "group group membership delete test error"}, ) self.client.force_login(self.user) - response = self.client.post( - self.get_url(obj.parent_group.name, obj.child_group.name), {"submit": ""} - ) + response = self.client.post(self.get_url(obj.parent_group.name, obj.child_group.name), {"submit": ""}) self.assertEqual(response.status_code, 200) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) @@ -16125,9 +14307,7 @@ def test_api_error_400(self): def test_api_error_403(self): obj = factories.GroupGroupMembershipFactory.create() - api_url = self.get_api_url( - obj.parent_group.name, obj.role.lower(), obj.child_group.email - ) + api_url = self.get_api_url(obj.parent_group.name, obj.role.lower(), obj.child_group.email) self.anvil_response_mock.add( responses.DELETE, api_url, @@ -16135,9 +14315,7 @@ def test_api_error_403(self): json={"message": "group group membership delete test error"}, ) self.client.force_login(self.user) - response = self.client.post( - self.get_url(obj.parent_group.name, obj.child_group.name), {"submit": ""} - ) + response = self.client.post(self.get_url(obj.parent_group.name, obj.child_group.name), {"submit": ""}) self.assertEqual(response.status_code, 200) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) @@ -16150,9 +14328,7 @@ def test_api_error_403(self): def test_api_error_404(self): obj = factories.GroupGroupMembershipFactory.create() - api_url = self.get_api_url( - obj.parent_group.name, obj.role.lower(), obj.child_group.email - ) + api_url = self.get_api_url(obj.parent_group.name, obj.role.lower(), obj.child_group.email) self.anvil_response_mock.add( responses.DELETE, api_url, @@ -16160,9 +14336,7 @@ def test_api_error_404(self): json={"message": "group group membership delete test error"}, ) self.client.force_login(self.user) - response = self.client.post( - self.get_url(obj.parent_group.name, obj.child_group.name), {"submit": ""} - ) + response = self.client.post(self.get_url(obj.parent_group.name, obj.child_group.name), {"submit": ""}) self.assertEqual(response.status_code, 200) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) @@ -16175,9 +14349,7 @@ def test_api_error_404(self): def test_api_error_500(self): obj = factories.GroupGroupMembershipFactory.create() - api_url = self.get_api_url( - obj.parent_group.name, obj.role.lower(), obj.child_group.email - ) + api_url = self.get_api_url(obj.parent_group.name, obj.role.lower(), obj.child_group.email) self.anvil_response_mock.add( responses.DELETE, api_url, @@ -16185,9 +14357,7 @@ def test_api_error_500(self): json={"message": "group group membership delete test error"}, ) self.client.force_login(self.user) - response = self.client.post( - self.get_url(obj.parent_group.name, obj.child_group.name), {"submit": ""} - ) + response = self.client.post(self.get_url(obj.parent_group.name, obj.child_group.name), {"submit": ""}) self.assertEqual(response.status_code, 200) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) @@ -16206,16 +14376,12 @@ 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): """Get the url for the view being tested.""" - return reverse( - "anvil_consortium_manager:managed_groups:member_accounts:detail", args=args - ) + return reverse("anvil_consortium_manager:managed_groups:member_accounts:detail", args=args) def get_view(self): """Return the view being tested.""" @@ -16240,13 +14406,9 @@ def test_status_code_with_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo", uuid4())) request.user = user @@ -16255,9 +14417,7 @@ def test_access_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") uuid = uuid4() request = self.factory.get(self.get_url("foo1", uuid)) request.user = user_no_perms @@ -16276,12 +14436,8 @@ def test_edit_permission(self): """Links to delete url appears if the user has edit permission.""" edit_user = User.objects.create_user(username="edit", password="test") edit_user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ), - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ), + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME), + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME), ) self.client.force_login(edit_user) obj = factories.GroupAccountMembershipFactory.create() @@ -16303,9 +14459,7 @@ def test_view_permission(self): """Links to delete url appears if the user has edit permission.""" view_user = User.objects.create_user(username="view", password="test") view_user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ), + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME), ) self.client.force_login(view_user) obj = factories.GroupAccountMembershipFactory.create() @@ -16328,13 +14482,9 @@ def test_detail_page_links(self): self.client.force_login(self.user) obj = factories.GroupAccountMembershipFactory.create() response = self.client.get(obj.get_absolute_url()) - html = """{text}""".format( - url=obj.group.get_absolute_url(), text=str(obj.group) - ) + html = """{text}""".format(url=obj.group.get_absolute_url(), text=str(obj.group)) self.assertContains(response, html) - html = """{text}""".format( - url=obj.account.get_absolute_url(), text=str(obj.account) - ) + html = """{text}""".format(url=obj.account.get_absolute_url(), text=str(obj.account)) self.assertContains(response, html) @@ -16350,45 +14500,29 @@ 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) def get_url(self, *args): """Get the url for the view being tested.""" - return reverse( - "anvil_consortium_manager:group_account_membership:new", args=args - ) + return reverse("anvil_consortium_manager:group_account_membership:new", args=args) def get_view(self): """Return the view being tested.""" return views.GroupAccountMembershipCreate.as_view() def get_api_url(self, group_name, role, email): - url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/" - + group_name - + "/" - + role - + "/" - + email - ) + url = self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/" + role + "/" + email return url 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.""" @@ -16398,13 +14532,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user_with_view_perm @@ -16413,13 +14543,9 @@ def test_access_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -16428,9 +14554,7 @@ def test_access_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): @@ -16441,18 +14565,14 @@ def test_has_form_in_context(self): self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertTrue("form" in response.context_data) - self.assertIsInstance( - response.context_data["form"], forms.GroupAccountMembershipForm - ) + self.assertIsInstance(response.context_data["form"], forms.GroupAccountMembershipForm) def test_can_create_an_object_member(self): """Posting valid data to the form creates an object.""" group = factories.ManagedGroupFactory.create(name="test-group") account = factories.AccountFactory.create(email="email@example.com") api_url = self.get_api_url(group.name, "member", account.email) - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(), @@ -16475,9 +14595,7 @@ def test_success_message(self): group = factories.ManagedGroupFactory.create(name="test-group") account = factories.AccountFactory.create(email="email@example.com") api_url = self.get_api_url(group.name, "member", account.email) - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(), @@ -16490,18 +14608,14 @@ def test_success_message(self): ) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.GroupAccountMembershipCreate.success_message, str(messages[0]) - ) + self.assertEqual(views.GroupAccountMembershipCreate.success_message, str(messages[0])) def test_can_create_an_object_admin(self): """Posting valid data to the form creates an object.""" group = factories.ManagedGroupFactory.create(name="test-group") account = factories.AccountFactory.create(email="email@example.com") api_url = self.get_api_url(group.name, "admin", account.email) - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(), @@ -16522,9 +14636,7 @@ def test_redirects_to_list(self): group = factories.ManagedGroupFactory.create() account = factories.AccountFactory.create() api_url = self.get_api_url(group.name, "member", account.email) - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(), @@ -16534,9 +14646,7 @@ def test_redirects_to_list(self): "role": models.GroupAccountMembership.MEMBER, }, ) - self.assertRedirects( - response, reverse("anvil_consortium_manager:group_account_membership:list") - ) + self.assertRedirects(response, reverse("anvil_consortium_manager:group_account_membership:list")) def test_cannot_create_duplicate_object_with_same_role(self): """Cannot create a second GroupAccountMembership object for the same account and group with the same role.""" @@ -16594,9 +14704,7 @@ def test_can_add_two_groups_for_one_account(self): account = factories.AccountFactory.create() factories.GroupAccountMembershipFactory.create(group=group_1, account=account) api_url = self.get_api_url(group_2.name, "member", account.email) - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(), @@ -16615,9 +14723,7 @@ def test_can_add_two_accounts_to_one_group(self): account_2 = factories.AccountFactory.create(email="test_2@example.com") factories.GroupAccountMembershipFactory.create(group=group, account=account_1) api_url = self.get_api_url(group.name, "member", account_2.email) - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(), @@ -16734,9 +14840,7 @@ def test_post_blank_data_role(self): account = factories.AccountFactory.create() group = factories.ManagedGroupFactory.create() self.client.force_login(self.user) - response = self.client.post( - self.get_url(), {"group": group.pk, "account": account.pk} - ) + response = self.client.post(self.get_url(), {"group": group.pk, "account": account.pk}) self.assertEqual(response.status_code, 200) form = response.context_data["form"] self.assertFalse(form.is_valid()) @@ -16821,9 +14925,7 @@ def test_cannot_add_inactive_account_to_group(self): def test_queryset_shows_active_users_only(self): """Form queryset only shows active accounts.""" active_account = factories.AccountFactory.create() - inactive_account = factories.AccountFactory.create( - status=models.Account.INACTIVE_STATUS - ) + inactive_account = factories.AccountFactory.create(status=models.Account.INACTIVE_STATUS) self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertTrue("form" in response.context_data) @@ -16960,23 +15062,17 @@ 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) self.account = factories.AccountFactory.create() self.group = factories.ManagedGroupFactory.create() def get_url(self, *args): """Get the url for the view being tested.""" - return reverse( - "anvil_consortium_manager:managed_groups:member_accounts:new", args=args - ) + return reverse("anvil_consortium_manager:managed_groups:member_accounts:new", args=args) def get_view(self): """Return the view being tested.""" @@ -17011,13 +15107,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url(self.group.name)) request.user = user_with_view_perm @@ -17026,13 +15118,9 @@ def test_access_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo")) request.user = user @@ -17041,9 +15129,7 @@ def test_access_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(self.group.name)) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -17054,9 +15140,7 @@ def test_has_form_in_context(self): self.client.force_login(self.user) response = self.client.get(self.get_url(self.group.name)) self.assertTrue("form" in response.context_data) - self.assertIsInstance( - response.context_data["form"], forms.GroupAccountMembershipForm - ) + self.assertIsInstance(response.context_data["form"], forms.GroupAccountMembershipForm) def test_context_group(self): """Context contains the group.""" @@ -17070,16 +15154,12 @@ def test_form_hidden_input(self): self.client.force_login(self.user) response = self.client.get(self.get_url(self.group.name)) self.assertTrue("form" in response.context_data) - self.assertIsInstance( - response.context_data["form"].fields["group"].widget, HiddenInput - ) + self.assertIsInstance(response.context_data["form"].fields["group"].widget, HiddenInput) def test_can_create_an_object_member(self): """Posting valid data to the form creates an object.""" api_url = self.get_api_url("member") - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(self.group.name), @@ -17099,9 +15179,7 @@ def test_can_create_an_object_member(self): def test_success_message(self): """Response includes a success message if successful.""" api_url = self.get_api_url("member") - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(self.group.name), @@ -17114,16 +15192,12 @@ def test_success_message(self): ) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.GroupAccountMembershipCreate.success_message, str(messages[0]) - ) + self.assertEqual(views.GroupAccountMembershipCreate.success_message, str(messages[0])) def test_can_create_an_object_admin(self): """Posting valid data to the form creates an object.""" api_url = self.get_api_url("admin") - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(self.group.name), @@ -17144,9 +15218,7 @@ def test_success_redirect(self): """After successfully creating an object, view redirects to the model's list view.""" # This needs to use the client because the RequestFactory doesn't handle redirects. api_url = self.get_api_url("member") - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(self.group.name), @@ -17491,14 +15563,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) self.account = factories.AccountFactory.create() self.group = factories.ManagedGroupFactory.create() @@ -17529,9 +15597,7 @@ def test_view_redirect_not_logged_in(self): response = self.client.get(self.get_url(self.account.uuid)) self.assertRedirects( response, - resolve_url(settings.LOGIN_URL) - + "?next=" - + self.get_url(self.account.uuid), + resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(self.account.uuid), ) def test_status_code_with_user_permission(self): @@ -17543,13 +15609,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url(self.account.uuid)) request.user = user_with_view_perm @@ -17558,13 +15620,9 @@ def test_access_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url(uuid4())) request.user = user @@ -17573,9 +15631,7 @@ def test_access_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(self.account.uuid)) request.user = user_no_perms with self.assertRaises(PermissionDenied): @@ -17586,9 +15642,7 @@ def test_has_form_in_context(self): self.client.force_login(self.user) response = self.client.get(self.get_url(self.account.uuid)) self.assertTrue("form" in response.context_data) - self.assertIsInstance( - response.context_data["form"], forms.GroupAccountMembershipForm - ) + self.assertIsInstance(response.context_data["form"], forms.GroupAccountMembershipForm) def test_context_account(self): """Context contains the account.""" @@ -17602,16 +15656,12 @@ def test_form_hidden_input(self): self.client.force_login(self.user) response = self.client.get(self.get_url(self.account.uuid)) self.assertTrue("form" in response.context_data) - self.assertIsInstance( - response.context_data["form"].fields["account"].widget, HiddenInput - ) + self.assertIsInstance(response.context_data["form"].fields["account"].widget, HiddenInput) def test_can_create_an_object_member(self): """Posting valid data to the form creates an object.""" api_url = self.get_api_url("member") - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(self.account.uuid), @@ -17631,9 +15681,7 @@ def test_can_create_an_object_member(self): def test_success_message(self): """Response includes a success message if successful.""" api_url = self.get_api_url("member") - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(self.account.uuid), @@ -17646,16 +15694,12 @@ def test_success_message(self): ) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.GroupAccountMembershipCreate.success_message, str(messages[0]) - ) + self.assertEqual(views.GroupAccountMembershipCreate.success_message, str(messages[0])) def test_can_create_an_object_admin(self): """Posting valid data to the form creates an object.""" api_url = self.get_api_url("admin") - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(self.account.uuid), @@ -17676,9 +15720,7 @@ def test_success_redirect(self): """After successfully creating an object, view redirects to the model's list view.""" # This needs to use the client because the RequestFactory doesn't handle redirects. api_url = self.get_api_url("member") - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(self.account.uuid), @@ -18006,14 +16048,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) self.account = factories.AccountFactory.create() self.group = factories.ManagedGroupFactory.create() @@ -18047,9 +16085,7 @@ def test_view_redirect_not_logged_in(self): response = self.client.get(self.get_url(self.group.name, self.account.uuid)) self.assertRedirects( response, - resolve_url(settings.LOGIN_URL) - + "?next=" - + self.get_url(self.group.name, self.account.uuid), + resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url(self.group.name, self.account.uuid), ) def test_status_code_with_user_permission(self): @@ -18060,30 +16096,20 @@ 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url(self.group.name, self.account.uuid)) request.user = user_with_view_perm with self.assertRaises(PermissionDenied): - self.get_view()( - request, group_slug=self.group.name, account_uuid=self.account.uuid - ) + self.get_view()(request, group_slug=self.group.name, account_uuid=self.account.uuid) def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo", uuid4())) request.user = user @@ -18092,24 +16118,18 @@ def test_access_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(self.group.name, self.account.uuid)) request.user = user_no_perms with self.assertRaises(PermissionDenied): - self.get_view()( - request, group_slug=self.group.name, account_slug=self.account.uuid - ) + self.get_view()(request, group_slug=self.group.name, account_slug=self.account.uuid) def test_has_form_in_context(self): """Response includes a form.""" self.client.force_login(self.user) response = self.client.get(self.get_url(self.group.name, self.account.uuid)) self.assertTrue("form" in response.context_data) - self.assertIsInstance( - response.context_data["form"], forms.GroupAccountMembershipForm - ) + self.assertIsInstance(response.context_data["form"], forms.GroupAccountMembershipForm) def test_context_group(self): """Context contains the group.""" @@ -18130,19 +16150,13 @@ def test_form_hidden_input(self): self.client.force_login(self.user) response = self.client.get(self.get_url(self.group.name, self.account.uuid)) self.assertTrue("form" in response.context_data) - self.assertIsInstance( - response.context_data["form"].fields["account"].widget, HiddenInput - ) - self.assertIsInstance( - response.context_data["form"].fields["group"].widget, HiddenInput - ) + self.assertIsInstance(response.context_data["form"].fields["account"].widget, HiddenInput) + self.assertIsInstance(response.context_data["form"].fields["group"].widget, HiddenInput) def test_can_create_an_object_member(self): """Posting valid data to the form creates an object.""" api_url = self.get_api_url("member") - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(self.group.name, self.account.uuid), @@ -18162,9 +16176,7 @@ def test_can_create_an_object_member(self): def test_success_message(self): """Response includes a success message if successful.""" api_url = self.get_api_url("member") - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(self.group.name, self.account.uuid), @@ -18177,16 +16189,12 @@ def test_success_message(self): ) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.GroupAccountMembershipCreate.success_message, str(messages[0]) - ) + self.assertEqual(views.GroupAccountMembershipCreate.success_message, str(messages[0])) def test_can_create_an_object_admin(self): """Posting valid data to the form creates an object.""" api_url = self.get_api_url("admin") - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(self.group.name, self.account.uuid), @@ -18207,9 +16215,7 @@ def test_success_redirect(self): """After successfully creating an object, view redirects to the model's list view.""" # This needs to use the client because the RequestFactory doesn't handle redirects. api_url = self.get_api_url("member") - self.anvil_response_mock.add( - responses.PUT, api_url, status=self.api_success_code - ) + self.anvil_response_mock.add(responses.PUT, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(self.group.name, self.account.uuid), @@ -18354,9 +16360,7 @@ def test_invalid_input_role(self): def test_post_blank_data(self): """Posting blank data does not create an object.""" self.client.force_login(self.user) - response = self.client.post( - self.get_url(self.group.name, self.account.uuid), {} - ) + response = self.client.post(self.get_url(self.group.name, self.account.uuid), {}) self.assertEqual(response.status_code, 200) form = response.context_data["form"] self.assertFalse(form.is_valid()) @@ -18571,16 +16575,12 @@ 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): """Get the url for the view being tested.""" - return reverse( - "anvil_consortium_manager:group_account_membership:list", args=args - ) + return reverse("anvil_consortium_manager:group_account_membership:list", args=args) def get_view(self): """Return the view being tested.""" @@ -18590,9 +16590,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.""" @@ -18602,13 +16600,9 @@ def test_status_code_with_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -18617,9 +16611,7 @@ def test_access_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): @@ -18629,9 +16621,7 @@ def test_view_has_correct_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.GroupAccountMembershipTable - ) + self.assertIsInstance(response.context_data["table"], tables.GroupAccountMembershipTable) def test_view_with_no_objects(self): self.client.force_login(self.user) @@ -18664,16 +16654,12 @@ 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): """Get the url for the view being tested.""" - return reverse( - "anvil_consortium_manager:group_account_membership:list_active", args=args - ) + return reverse("anvil_consortium_manager:group_account_membership:list_active", args=args) def get_view(self): """Return the view being tested.""" @@ -18683,9 +16669,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.""" @@ -18695,9 +16679,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): @@ -18707,9 +16689,7 @@ def test_view_has_correct_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.GroupAccountMembershipTable - ) + self.assertIsInstance(response.context_data["table"], tables.GroupAccountMembershipTable) def test_view_with_no_objects(self): self.client.force_login(self.user) @@ -18736,9 +16716,7 @@ def test_view_with_two_objects(self): def test_does_not_show_inactive_accounts(self): """Inactive accounts are not shown.""" - factories.GroupAccountMembershipFactory.create_batch( - 2, account__status=models.Account.INACTIVE_STATUS - ) + factories.GroupAccountMembershipFactory.create_batch(2, account__status=models.Account.INACTIVE_STATUS) self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertEqual(response.status_code, 200) @@ -18753,16 +16731,12 @@ 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): """Get the url for the view being tested.""" - return reverse( - "anvil_consortium_manager:group_account_membership:list_inactive", args=args - ) + return reverse("anvil_consortium_manager:group_account_membership:list_inactive", args=args) def get_view(self): """Return the view being tested.""" @@ -18772,9 +16746,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.""" @@ -18784,13 +16756,9 @@ def test_status_code_with_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -18799,9 +16767,7 @@ def test_access_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): @@ -18811,9 +16777,7 @@ def test_view_has_correct_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.GroupAccountMembershipTable - ) + self.assertIsInstance(response.context_data["table"], tables.GroupAccountMembershipTable) def test_view_with_no_objects(self): self.client.force_login(self.user) @@ -18866,36 +16830,22 @@ 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) def get_url(self, *args): """Get the url for the view being tested.""" - return reverse( - "anvil_consortium_manager:managed_groups:member_accounts:delete", args=args - ) + return reverse("anvil_consortium_manager:managed_groups:member_accounts:delete", args=args) def get_view(self): """Return the view being tested.""" return views.GroupAccountMembershipDelete.as_view() def get_api_url(self, group_name, role, email): - url = ( - self.api_client.sam_entry_point - + "/api/groups/v1/" - + group_name - + "/" - + role - + "/" - + email - ) + url = self.api_client.sam_entry_point + "/api/groups/v1/" + group_name + "/" + role + "/" + email return url def test_view_redirect_not_logged_in(self): @@ -18917,13 +16867,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) uuid = uuid4() request = self.factory.get(self.get_url("foo", uuid)) @@ -18933,13 +16879,9 @@ def test_access_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo", uuid4())) request.user = user @@ -18948,9 +16890,7 @@ def test_access_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") uuid = uuid4() request = self.factory.get(self.get_url("foo", uuid)) request.user = user_no_perms @@ -18968,16 +16908,10 @@ def test_view_with_invalid_pk(self): def test_view_deletes_object(self): """Posting submit to the form successfully deletes the object.""" object = factories.GroupAccountMembershipFactory.create() - api_url = self.get_api_url( - object.group.name, object.role.lower(), object.account.email - ) - self.anvil_response_mock.add( - responses.DELETE, api_url, status=self.api_success_code - ) + api_url = self.get_api_url(object.group.name, object.role.lower(), object.account.email) + self.anvil_response_mock.add(responses.DELETE, api_url, status=self.api_success_code) self.client.force_login(self.user) - response = self.client.post( - self.get_url(object.group.name, object.account.uuid), {"submit": ""} - ) + response = self.client.post(self.get_url(object.group.name, object.account.uuid), {"submit": ""}) self.assertEqual(response.status_code, 302) self.assertEqual(models.GroupAccountMembership.objects.count(), 0) # History is added. @@ -18987,12 +16921,8 @@ def test_view_deletes_object(self): def test_success_message(self): """Response includes a success message if successful.""" object = factories.GroupAccountMembershipFactory.create() - api_url = self.get_api_url( - object.group.name, object.role.lower(), object.account.email - ) - self.anvil_response_mock.add( - responses.DELETE, api_url, status=self.api_success_code - ) + api_url = self.get_api_url(object.group.name, object.role.lower(), object.account.email) + self.anvil_response_mock.add(responses.DELETE, api_url, status=self.api_success_code) self.client.force_login(self.user) response = self.client.post( self.get_url(object.group.name, object.account.uuid), @@ -19001,24 +16931,16 @@ def test_success_message(self): ) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.GroupAccountMembershipDelete.success_message, str(messages[0]) - ) + self.assertEqual(views.GroupAccountMembershipDelete.success_message, str(messages[0])) def test_only_deletes_specified_pk(self): """View only deletes the specified pk.""" object = factories.GroupAccountMembershipFactory.create() other_object = factories.GroupAccountMembershipFactory.create() - api_url = self.get_api_url( - object.group.name, object.role.lower(), object.account.email - ) - self.anvil_response_mock.add( - responses.DELETE, api_url, status=self.api_success_code - ) + api_url = self.get_api_url(object.group.name, object.role.lower(), object.account.email) + self.anvil_response_mock.add(responses.DELETE, api_url, status=self.api_success_code) self.client.force_login(self.user) - response = self.client.post( - self.get_url(object.group.name, object.account.uuid), {"submit": ""} - ) + response = self.client.post(self.get_url(object.group.name, object.account.uuid), {"submit": ""}) self.assertEqual(response.status_code, 302) self.assertEqual(models.GroupAccountMembership.objects.count(), 1) self.assertQuerySetEqual( @@ -19030,16 +16952,10 @@ def test_success_url(self): """Redirects to the expected page.""" object = factories.GroupAccountMembershipFactory.create() group = object.group - api_url = self.get_api_url( - object.group.name, object.role.lower(), object.account.email - ) - self.anvil_response_mock.add( - responses.DELETE, api_url, status=self.api_success_code - ) + api_url = self.get_api_url(object.group.name, object.role.lower(), object.account.email) + self.anvil_response_mock.add(responses.DELETE, api_url, status=self.api_success_code) self.client.force_login(self.user) - response = self.client.post( - self.get_url(object.group.name, object.account.uuid), {"submit": ""} - ) + response = self.client.post(self.get_url(object.group.name, object.account.uuid), {"submit": ""}) self.assertEqual(response.status_code, 302) self.assertRedirects(response, group.get_absolute_url()) @@ -19047,14 +16963,10 @@ def test_get_redirect_group_not_managed_by_app(self): """Redirect get when trying to delete GroupAccountMembership when the group is not managed by the app.""" group = factories.ManagedGroupFactory.create(is_managed_by_app=False) account = factories.AccountFactory.create() - membership = factories.GroupAccountMembershipFactory.create( - group=group, account=account - ) + membership = factories.GroupAccountMembershipFactory.create(group=group, account=account) # Need to use a client for messages. self.client.force_login(self.user) - response = self.client.get( - self.get_url(membership.group.name, membership.account.uuid), follow=True - ) + response = self.client.get(self.get_url(membership.group.name, membership.account.uuid), follow=True) self.assertRedirects(response, membership.get_absolute_url()) # Check for messages. messages = [m.message for m in get_messages(response.wsgi_request)] @@ -19070,14 +16982,10 @@ def test_post_redirect_group_not_managed_by_app(self): """Redirect post when trying to delete GroupAccountMembership when the group is not managed by the app.""" group = factories.ManagedGroupFactory.create(is_managed_by_app=False) account = factories.AccountFactory.create() - membership = factories.GroupAccountMembershipFactory.create( - group=group, account=account - ) + membership = factories.GroupAccountMembershipFactory.create(group=group, account=account) # Need to use a client for messages. self.client.force_login(self.user) - response = self.client.post( - self.get_url(membership.group.name, membership.account.uuid), follow=True - ) + response = self.client.post(self.get_url(membership.group.name, membership.account.uuid), follow=True) self.assertRedirects(response, membership.get_absolute_url()) # Check for messages. messages = [m.message for m in get_messages(response.wsgi_request)] @@ -19093,9 +17001,7 @@ def test_api_error_500(self): """Shows a message if an AnVIL API error occurs.""" # Need a client to check messages. object = factories.GroupAccountMembershipFactory.create() - api_url = self.get_api_url( - object.group.name, object.role.lower(), object.account.email - ) + api_url = self.get_api_url(object.group.name, object.role.lower(), object.account.email) self.anvil_response_mock.add( responses.DELETE, api_url, @@ -19103,9 +17009,7 @@ def test_api_error_500(self): json={"message": "group account membership delete test error"}, ) self.client.force_login(self.user) - response = self.client.post( - self.get_url(object.group.name, object.account.uuid), {"submit": ""} - ) + response = self.client.post(self.get_url(object.group.name, object.account.uuid), {"submit": ""}) self.assertEqual(response.status_code, 200) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) @@ -19120,9 +17024,7 @@ def test_api_error_400(self): """Shows a message if an AnVIL API error occurs.""" # Need a client to check messages. object = factories.GroupAccountMembershipFactory.create() - api_url = self.get_api_url( - object.group.name, object.role.lower(), object.account.email - ) + api_url = self.get_api_url(object.group.name, object.role.lower(), object.account.email) self.anvil_response_mock.add( responses.DELETE, api_url, @@ -19130,9 +17032,7 @@ def test_api_error_400(self): json={"message": "group account membership delete test error"}, ) self.client.force_login(self.user) - response = self.client.post( - self.get_url(object.group.name, object.account.uuid), {"submit": ""} - ) + response = self.client.post(self.get_url(object.group.name, object.account.uuid), {"submit": ""}) self.assertEqual(response.status_code, 200) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) @@ -19147,9 +17047,7 @@ def test_api_error_403(self): """Shows a message if an AnVIL API error occurs.""" # Need a client to check messages. object = factories.GroupAccountMembershipFactory.create() - api_url = self.get_api_url( - object.group.name, object.role.lower(), object.account.email - ) + api_url = self.get_api_url(object.group.name, object.role.lower(), object.account.email) self.anvil_response_mock.add( responses.DELETE, api_url, @@ -19157,9 +17055,7 @@ def test_api_error_403(self): json={"message": "group account membership delete test error"}, ) self.client.force_login(self.user) - response = self.client.post( - self.get_url(object.group.name, object.account.uuid), {"submit": ""} - ) + response = self.client.post(self.get_url(object.group.name, object.account.uuid), {"submit": ""}) self.assertEqual(response.status_code, 200) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) @@ -19174,9 +17070,7 @@ def test_api_error_404(self): """Shows a message if an AnVIL API error occurs.""" # Need a client to check messages. object = factories.GroupAccountMembershipFactory.create() - api_url = self.get_api_url( - object.group.name, object.role.lower(), object.account.email - ) + api_url = self.get_api_url(object.group.name, object.role.lower(), object.account.email) self.anvil_response_mock.add( responses.DELETE, api_url, @@ -19184,9 +17078,7 @@ def test_api_error_404(self): json={"message": "group account membership delete test error"}, ) self.client.force_login(self.user) - response = self.client.post( - self.get_url(object.group.name, object.account.uuid), {"submit": ""} - ) + response = self.client.post(self.get_url(object.group.name, object.account.uuid), {"submit": ""}) self.assertEqual(response.status_code, 200) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) @@ -19205,9 +17097,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -19221,14 +17111,10 @@ 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("billing_project", "workspace", "group") - ) + response = self.client.get(self.get_url("billing_project", "workspace", "group")) self.assertRedirects( response, - resolve_url(settings.LOGIN_URL) - + "?next=" - + self.get_url("billing_project", "workspace", "group"), + resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url("billing_project", "workspace", "group"), ) def test_status_code_with_user_permission(self): @@ -19240,13 +17126,9 @@ def test_status_code_with_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo", "bar", "tmp")) request.user = user @@ -19255,12 +17137,8 @@ def test_access_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" - ) - request = self.factory.get( - self.get_url("billing_project", "workspace", "group") - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") + request = self.factory.get(self.get_url("billing_project", "workspace", "group")) request.user = user_no_perms with self.assertRaises(PermissionDenied): self.get_view()( @@ -19273,9 +17151,7 @@ def test_access_without_user_permission(self): def test_view_status_code_with_invalid_pk(self): """Raises a 404 error with an invalid object pk.""" factories.WorkspaceGroupSharingFactory.create() - request = self.factory.get( - self.get_url("billing_project", "workspace", "group") - ) + request = self.factory.get(self.get_url("billing_project", "workspace", "group")) request.user = self.user with self.assertRaises(Http404): self.get_view()( @@ -19289,12 +17165,8 @@ def test_edit_permission(self): """Links to delete url appears if the user has edit permission.""" edit_user = User.objects.create_user(username="edit", password="test") edit_user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ), - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ), + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME), + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME), ) self.client.force_login(edit_user) obj = factories.WorkspaceGroupSharingFactory.create() @@ -19317,9 +17189,7 @@ def test_view_permission(self): """Links to delete url appears if the user has edit permission.""" view_user = User.objects.create_user(username="view", password="test") view_user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ), + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME), ) self.client.force_login(view_user) obj = factories.WorkspaceGroupSharingFactory.create() @@ -19351,21 +17221,15 @@ 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) def get_url(self, *args): """Get the url for the view being tested.""" - return reverse( - "anvil_consortium_manager:workspace_group_sharing:new", args=args - ) + return reverse("anvil_consortium_manager:workspace_group_sharing:new", args=args) def get_view(self): """Return the view being tested.""" @@ -19382,9 +17246,7 @@ def get_api_url(self, billing_project_name, workspace_name): ) return url - def get_api_json_response( - self, invites_sent=[], users_not_found=[], users_updated=[] - ): + def get_api_json_response(self, invites_sent=[], users_not_found=[], users_updated=[]): return { "invitesSent": invites_sent, "usersNotFound": users_not_found, @@ -19395,9 +17257,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.""" @@ -19407,13 +17267,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user_with_view_perm @@ -19422,13 +17278,9 @@ def test_access_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -19437,9 +17289,7 @@ def test_access_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): @@ -19450,19 +17300,13 @@ def test_has_form_in_context(self): self.client.force_login(self.user) response = self.client.get(self.get_url()) self.assertTrue("form" in response.context_data) - self.assertIsInstance( - response.context_data["form"], forms.WorkspaceGroupSharingForm - ) + self.assertIsInstance(response.context_data["form"], forms.WorkspaceGroupSharingForm) def test_can_create_an_object_reader(self): """Posting valid data to the form creates an object.""" group = factories.ManagedGroupFactory.create(name="test-group") - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) - workspace = factories.WorkspaceFactory.create( - name="test-workspace", billing_project=billing_project - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") + workspace = factories.WorkspaceFactory.create(name="test-workspace", billing_project=billing_project) json_data = [ { "email": "test-group@firecloud.org", @@ -19500,12 +17344,8 @@ def test_can_create_an_object_reader(self): def test_can_create_a_writer_with_can_compute(self): """Posting valid data to the form creates an object.""" group = factories.ManagedGroupFactory.create(name="test-group") - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) - workspace = factories.WorkspaceFactory.create( - name="test-workspace", billing_project=billing_project - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") + workspace = factories.WorkspaceFactory.create(name="test-workspace", billing_project=billing_project) json_data = [ { "email": "test-group@firecloud.org", @@ -19541,12 +17381,8 @@ def test_can_create_a_writer_with_can_compute(self): def test_success_message(self): """Response includes a success message if successful.""" group = factories.ManagedGroupFactory.create(name="test-group") - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) - workspace = factories.WorkspaceFactory.create( - name="test-workspace", billing_project=billing_project - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") + workspace = factories.WorkspaceFactory.create(name="test-workspace", billing_project=billing_project) json_data = [ { "email": "test-group@firecloud.org", @@ -19576,9 +17412,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.WorkspaceGroupSharingCreate.success_message, str(messages[0]) - ) + self.assertEqual(views.WorkspaceGroupSharingCreate.success_message, str(messages[0])) def test_can_create_an_object_writer(self): """Posting valid data to the form creates an object.""" @@ -19682,9 +17516,7 @@ def test_redirects_to_list(self): "can_compute": False, }, ) - self.assertRedirects( - response, reverse("anvil_consortium_manager:workspace_group_sharing:list") - ) + self.assertRedirects(response, reverse("anvil_consortium_manager:workspace_group_sharing:list")) def test_cannot_create_duplicate_object_with_same_access(self): """Cannot create a second object for the same workspace and group with the same access level.""" @@ -19746,9 +17578,7 @@ def test_can_have_two_workspaces_for_one_group(self): group_1 = factories.ManagedGroupFactory.create(name="test-group-1") group_2 = factories.ManagedGroupFactory.create(name="test-group-2") workspace = factories.WorkspaceFactory.create() - factories.WorkspaceGroupSharingFactory.create( - group=group_1, workspace=workspace - ) + factories.WorkspaceGroupSharingFactory.create(group=group_1, workspace=workspace) json_data = [ { "email": group_2.email, @@ -19782,9 +17612,7 @@ def test_can_have_two_groups_for_one_workspace(self): group = factories.ManagedGroupFactory.create() workspace_1 = factories.WorkspaceFactory.create(name="test-workspace-1") workspace_2 = factories.WorkspaceFactory.create(name="test-workspace-2") - factories.WorkspaceGroupSharingFactory.create( - group=group, workspace=workspace_1 - ) + factories.WorkspaceGroupSharingFactory.create(group=group, workspace=workspace_1) json_data = [ { "email": group.email, @@ -20103,14 +17931,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) self.workspace = factories.WorkspaceFactory.create() self.group = factories.ManagedGroupFactory.create() @@ -20134,9 +17958,7 @@ def get_api_url(self, billing_project_name, workspace_name): ) return url - def get_api_json_response( - self, invites_sent=[], users_not_found=[], users_updated=[] - ): + def get_api_json_response(self, invites_sent=[], users_not_found=[], users_updated=[]): return { "invitesSent": invites_sent, "usersNotFound": users_not_found, @@ -20175,13 +17997,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) request = self.factory.get( self.get_url( @@ -20199,13 +18017,9 @@ def test_access_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo", "bar")) request.user = user @@ -20214,9 +18028,7 @@ def test_access_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( self.workspace.billing_project.name, @@ -20241,9 +18053,7 @@ def test_has_form_in_context(self): ) ) self.assertTrue("form" in response.context_data) - self.assertIsInstance( - response.context_data["form"], forms.WorkspaceGroupSharingForm - ) + self.assertIsInstance(response.context_data["form"], forms.WorkspaceGroupSharingForm) def test_context_workspace(self): """Context contains the workspace.""" @@ -20267,22 +18077,14 @@ def test_form_hidden_input(self): ) ) self.assertTrue("form" in response.context_data) - self.assertIsInstance( - response.context_data["form"], forms.WorkspaceGroupSharingForm - ) - self.assertIsInstance( - response.context_data["form"].fields["workspace"].widget, HiddenInput - ) + self.assertIsInstance(response.context_data["form"], forms.WorkspaceGroupSharingForm) + self.assertIsInstance(response.context_data["form"].fields["workspace"].widget, HiddenInput) def test_can_create_an_object_reader(self): """Posting valid data to the form creates an object.""" group = factories.ManagedGroupFactory.create(name="test-group") - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) - workspace = factories.WorkspaceFactory.create( - name="test-workspace", billing_project=billing_project - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") + workspace = factories.WorkspaceFactory.create(name="test-workspace", billing_project=billing_project) json_data = [ { "email": "test-group@firecloud.org", @@ -20323,12 +18125,8 @@ def test_can_create_an_object_reader(self): def test_can_create_a_writer_with_can_compute(self): """Posting valid data to the form creates an object.""" group = factories.ManagedGroupFactory.create(name="test-group") - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) - workspace = factories.WorkspaceFactory.create( - name="test-workspace", billing_project=billing_project - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") + workspace = factories.WorkspaceFactory.create(name="test-workspace", billing_project=billing_project) json_data = [ { "email": "test-group@firecloud.org", @@ -20370,12 +18168,8 @@ def test_can_create_a_writer_with_can_compute(self): def test_success_message(self): """Response includes a success message if successful.""" group = factories.ManagedGroupFactory.create(name="test-group") - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) - workspace = factories.WorkspaceFactory.create( - name="test-workspace", billing_project=billing_project - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") + workspace = factories.WorkspaceFactory.create(name="test-workspace", billing_project=billing_project) json_data = [ { "email": "test-group@firecloud.org", @@ -20641,9 +18435,7 @@ def test_get_workspace_not_found(self): """Raises 404 if workspace in URL does not exist when posting data.""" # Create a workspace with the same name but different billing project. factories.WorkspaceFactory.create(name="foo") - request = self.factory.get( - self.get_url(self.workspace.billing_project.name, "foo") - ) + request = self.factory.get(self.get_url(self.workspace.billing_project.name, "foo")) request.user = self.user with self.assertRaises(Http404): self.get_view()( @@ -20873,14 +18665,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) self.workspace = factories.WorkspaceFactory.create() self.group = factories.ManagedGroupFactory.create() @@ -20904,9 +18692,7 @@ def get_api_url(self, billing_project_name, workspace_name): ) return url - def get_api_json_response( - self, invites_sent=[], users_not_found=[], users_updated=[] - ): + def get_api_json_response(self, invites_sent=[], users_not_found=[], users_updated=[]): return { "invitesSent": invites_sent, "usersNotFound": users_not_found, @@ -20942,13 +18728,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) request = self.factory.get( self.get_url( @@ -20964,13 +18746,9 @@ def test_access_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo")) request.user = user @@ -20979,9 +18757,7 @@ def test_access_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( self.group.name, @@ -21003,9 +18779,7 @@ def test_has_form_in_context(self): ) ) self.assertTrue("form" in response.context_data) - self.assertIsInstance( - response.context_data["form"], forms.WorkspaceGroupSharingForm - ) + self.assertIsInstance(response.context_data["form"], forms.WorkspaceGroupSharingForm) def test_context_group(self): """Context contains the group.""" @@ -21027,22 +18801,14 @@ def test_form_hidden_input(self): ) ) self.assertTrue("form" in response.context_data) - self.assertIsInstance( - response.context_data["form"], forms.WorkspaceGroupSharingForm - ) - self.assertIsInstance( - response.context_data["form"].fields["group"].widget, HiddenInput - ) + self.assertIsInstance(response.context_data["form"], forms.WorkspaceGroupSharingForm) + self.assertIsInstance(response.context_data["form"].fields["group"].widget, HiddenInput) def test_can_create_an_object_reader(self): """Posting valid data to the form creates an object.""" group = factories.ManagedGroupFactory.create(name="test-group") - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) - workspace = factories.WorkspaceFactory.create( - name="test-workspace", billing_project=billing_project - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") + workspace = factories.WorkspaceFactory.create(name="test-workspace", billing_project=billing_project) json_data = [ { "email": "test-group@firecloud.org", @@ -21084,12 +18850,8 @@ def test_can_create_an_object_reader(self): def test_can_create_a_writer_with_can_compute(self): """Posting valid data to the form creates an object.""" group = factories.ManagedGroupFactory.create(name="test-group") - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) - workspace = factories.WorkspaceFactory.create( - name="test-workspace", billing_project=billing_project - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") + workspace = factories.WorkspaceFactory.create(name="test-workspace", billing_project=billing_project) json_data = [ { "email": "test-group@firecloud.org", @@ -21125,12 +18887,8 @@ def test_can_create_a_writer_with_can_compute(self): def test_success_message(self): """Response includes a success message if successful.""" group = factories.ManagedGroupFactory.create(name="test-group") - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) - workspace = factories.WorkspaceFactory.create( - name="test-workspace", billing_project=billing_project - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") + workspace = factories.WorkspaceFactory.create(name="test-workspace", billing_project=billing_project) json_data = [ { "email": "test-group@firecloud.org", @@ -21578,23 +19336,17 @@ 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) self.workspace = factories.WorkspaceFactory.create() self.group = factories.ManagedGroupFactory.create() def get_url(self, *args): """Get the url for the view being tested.""" - return reverse( - "anvil_consortium_manager:workspaces:sharing:new_by_group", args=args - ) + return reverse("anvil_consortium_manager:workspaces:sharing:new_by_group", args=args) def get_view(self): """Return the view being tested.""" @@ -21611,9 +19363,7 @@ def get_api_url(self, billing_project_name, workspace_name): ) return url - def get_api_json_response( - self, invites_sent=[], users_not_found=[], users_updated=[] - ): + def get_api_json_response(self, invites_sent=[], users_not_found=[], users_updated=[]): return { "invitesSent": invites_sent, "usersNotFound": users_not_found, @@ -21655,13 +19405,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) request = self.factory.get( self.get_url( @@ -21681,13 +19427,9 @@ def test_access_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo", "bar", "tmp")) request.user = user @@ -21696,9 +19438,7 @@ def test_access_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( self.workspace.billing_project.name, @@ -21726,9 +19466,7 @@ def test_has_form_in_context(self): ) ) self.assertTrue("form" in response.context_data) - self.assertIsInstance( - response.context_data["form"], forms.WorkspaceGroupSharingForm - ) + self.assertIsInstance(response.context_data["form"], forms.WorkspaceGroupSharingForm) def test_context_group(self): """Context contains the group.""" @@ -21767,25 +19505,15 @@ def test_form_hidden_input(self): ) ) self.assertTrue("form" in response.context_data) - self.assertIsInstance( - response.context_data["form"], forms.WorkspaceGroupSharingForm - ) - self.assertIsInstance( - response.context_data["form"].fields["workspace"].widget, HiddenInput - ) - self.assertIsInstance( - response.context_data["form"].fields["group"].widget, HiddenInput - ) + self.assertIsInstance(response.context_data["form"], forms.WorkspaceGroupSharingForm) + self.assertIsInstance(response.context_data["form"].fields["workspace"].widget, HiddenInput) + self.assertIsInstance(response.context_data["form"].fields["group"].widget, HiddenInput) def test_can_create_an_object_reader(self): """Posting valid data to the form creates an object.""" group = factories.ManagedGroupFactory.create(name="test-group") - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) - workspace = factories.WorkspaceFactory.create( - name="test-workspace", billing_project=billing_project - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") + workspace = factories.WorkspaceFactory.create(name="test-workspace", billing_project=billing_project) json_data = [ { "email": "test-group@firecloud.org", @@ -21827,12 +19555,8 @@ def test_can_create_an_object_reader(self): def test_can_create_a_writer_with_can_compute(self): """Posting valid data to the form creates an object.""" group = factories.ManagedGroupFactory.create(name="test-group") - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) - workspace = factories.WorkspaceFactory.create( - name="test-workspace", billing_project=billing_project - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") + workspace = factories.WorkspaceFactory.create(name="test-workspace", billing_project=billing_project) json_data = [ { "email": "test-group@firecloud.org", @@ -21872,12 +19596,8 @@ def test_can_create_a_writer_with_can_compute(self): def test_success_message(self): """Response includes a success message if successful.""" group = factories.ManagedGroupFactory.create(name="test-group") - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) - workspace = factories.WorkspaceFactory.create( - name="test-workspace", billing_project=billing_project - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") + workspace = factories.WorkspaceFactory.create(name="test-workspace", billing_project=billing_project) json_data = [ { "email": "test-group@firecloud.org", @@ -22046,9 +19766,7 @@ def test_get_duplicate_object(self): ) self.client.force_login(self.user) response = self.client.get( - self.get_url( - obj.workspace.billing_project.name, obj.workspace.name, obj.group.name - ), + self.get_url(obj.workspace.billing_project.name, obj.workspace.name, obj.group.name), follow=True, ) self.assertRedirects(response, obj.get_absolute_url()) @@ -22073,9 +19791,7 @@ def test_post_duplicate_object(self): ) self.client.force_login(self.user) response = self.client.post( - self.get_url( - obj.workspace.billing_project.name, obj.workspace.name, obj.group.name - ), + self.get_url(obj.workspace.billing_project.name, obj.workspace.name, obj.group.name), { "group": group.pk, "workspace": workspace.pk, @@ -22097,11 +19813,7 @@ def test_post_duplicate_object(self): def test_get_group_not_found(self): """Raises 404 if group in URL does not exist when posting data.""" - request = self.factory.get( - self.get_url( - self.workspace.billing_project.name, self.workspace.name, "foo" - ) - ) + request = self.factory.get(self.get_url(self.workspace.billing_project.name, self.workspace.name, "foo")) request.user = self.user with self.assertRaises(Http404): self.get_view()( @@ -22115,9 +19827,7 @@ def test_get_group_not_found(self): def test_post_group_not_found(self): """Raises 404 if group in URL does not exist when posting data.""" request = self.factory.post( - self.get_url( - self.workspace.billing_project.name, self.workspace.name, "foo" - ), + self.get_url(self.workspace.billing_project.name, self.workspace.name, "foo"), { "group": self.group.pk + 1, "workspace": self.workspace.pk, @@ -22137,9 +19847,7 @@ def test_post_group_not_found(self): def test_get_billing_project_not_found(self): """Raises 404 if group in URL does not exist when posting data.""" - request = self.factory.get( - self.get_url("foo", self.workspace.name, self.group.name) - ) + request = self.factory.get(self.get_url("foo", self.workspace.name, self.group.name)) request.user = self.user with self.assertRaises(Http404): self.get_view()( @@ -22175,9 +19883,7 @@ def test_get_workspace_not_found(self): """Raises 404 if workspace in URL does not exist when posting data.""" # Create a workspace with the same name but different billing project. factories.WorkspaceFactory.create(name="foo") - request = self.factory.get( - self.get_url(self.workspace.billing_project.name, "foo", self.group.name) - ) + request = self.factory.get(self.get_url(self.workspace.billing_project.name, "foo", self.group.name)) request.user = self.user with self.assertRaises(Http404): self.get_view()( @@ -22414,14 +20120,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -22443,9 +20145,7 @@ def get_api_url(self, billing_project_name, workspace_name): ) return url - def get_api_json_response( - self, invites_sent=[], users_not_found=[], users_updated=[] - ): + def get_api_json_response(self, invites_sent=[], users_not_found=[], users_updated=[]): return { "invitesSent": invites_sent, "usersNotFound": users_not_found, @@ -22455,14 +20155,10 @@ def get_api_json_response( 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("billing_project", "workspace", "group") - ) + response = self.client.get(self.get_url("billing_project", "workspace", "group")) self.assertRedirects( response, - resolve_url(settings.LOGIN_URL) - + "?next=" - + self.get_url("billing_project", "workspace", "group"), + resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url("billing_project", "workspace", "group"), ) def test_status_code_with_user_permission(self): @@ -22470,25 +20166,17 @@ def test_status_code_with_user_permission(self): obj = factories.WorkspaceGroupSharingFactory.create() self.client.force_login(self.user) response = self.client.get( - self.get_url( - obj.workspace.billing_project.name, obj.workspace.name, obj.group.name - ) + self.get_url(obj.workspace.billing_project.name, obj.workspace.name, obj.group.name) ) self.assertEqual(response.status_code, 200) 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) - ) - request = self.factory.get( - self.get_url("billing_project", "workspace", "group") + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) + request = self.factory.get(self.get_url("billing_project", "workspace", "group")) request.user = user_with_view_perm with self.assertRaises(PermissionDenied): self.get_view()( @@ -22500,13 +20188,9 @@ def test_access_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo", "bar", "tmp")) request.user = user @@ -22515,12 +20199,8 @@ def test_access_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" - ) - request = self.factory.get( - self.get_url("billing_project", "workspace", "group") - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") + request = self.factory.get(self.get_url("billing_project", "workspace", "group")) request.user = user_no_perms with self.assertRaises(PermissionDenied): self.get_view()( @@ -22535,17 +20215,13 @@ def test_has_form_in_context(self): obj = factories.WorkspaceGroupSharingFactory.create() self.client.force_login(self.user) response = self.client.get( - self.get_url( - obj.workspace.billing_project.name, obj.workspace.name, obj.group.name - ) + self.get_url(obj.workspace.billing_project.name, obj.workspace.name, obj.group.name) ) self.assertTrue("form" in response.context_data) def test_view_with_invalid_pk(self): """Returns a 404 when the object doesn't exist.""" - request = self.factory.get( - self.get_url("billing_project", "workspace", "group") - ) + request = self.factory.get(self.get_url("billing_project", "workspace", "group")) request.user = self.user with self.assertRaises(Http404): self.get_view()( @@ -22558,12 +20234,8 @@ def test_view_with_invalid_pk(self): def test_can_update_role(self): """Can update the role through the view.""" group = factories.ManagedGroupFactory.create(name="test-group") - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) - workspace = factories.WorkspaceFactory.create( - name="test-workspace", billing_project=billing_project - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") + workspace = factories.WorkspaceFactory.create(name="test-workspace", billing_project=billing_project) obj = factories.WorkspaceGroupSharingFactory.create( group=group, workspace=workspace, access=models.WorkspaceGroupSharing.READER ) @@ -22575,9 +20247,7 @@ def test_can_update_role(self): "canCompute": False, } ] - api_url = self.get_api_url( - obj.workspace.billing_project.name, obj.workspace.name - ) + api_url = self.get_api_url(obj.workspace.billing_project.name, obj.workspace.name) self.anvil_response_mock.add( responses.PATCH, api_url, @@ -22587,9 +20257,7 @@ def test_can_update_role(self): ) self.client.force_login(self.user) response = self.client.post( - self.get_url( - obj.workspace.billing_project.name, obj.workspace.name, obj.group.name - ), + self.get_url(obj.workspace.billing_project.name, obj.workspace.name, obj.group.name), { "access": models.WorkspaceGroupSharing.WRITER, }, @@ -22604,12 +20272,8 @@ def test_can_update_role(self): def test_can_update_can_compute(self): """Can update the can_compute field.""" group = factories.ManagedGroupFactory.create(name="test-group") - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) - workspace = factories.WorkspaceFactory.create( - name="test-workspace", billing_project=billing_project - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") + workspace = factories.WorkspaceFactory.create(name="test-workspace", billing_project=billing_project) obj = factories.WorkspaceGroupSharingFactory.create( group=group, workspace=workspace, access=models.WorkspaceGroupSharing.WRITER ) @@ -22621,9 +20285,7 @@ def test_can_update_can_compute(self): "canCompute": True, } ] - api_url = self.get_api_url( - obj.workspace.billing_project.name, obj.workspace.name - ) + api_url = self.get_api_url(obj.workspace.billing_project.name, obj.workspace.name) self.anvil_response_mock.add( responses.PATCH, api_url, @@ -22633,9 +20295,7 @@ def test_can_update_can_compute(self): ) self.client.force_login(self.user) response = self.client.post( - self.get_url( - obj.workspace.billing_project.name, obj.workspace.name, obj.group.name - ), + self.get_url(obj.workspace.billing_project.name, obj.workspace.name, obj.group.name), {"access": models.WorkspaceGroupSharing.WRITER, "can_compute": True}, ) self.assertEqual(response.status_code, 302) @@ -22646,20 +20306,14 @@ def test_can_update_can_compute(self): def test_invalid_reader_can_compute(self): """The form is not valid when trying to update a READER's can_compute value to True.""" group = factories.ManagedGroupFactory.create(name="test-group") - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) - workspace = factories.WorkspaceFactory.create( - name="test-workspace", billing_project=billing_project - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") + workspace = factories.WorkspaceFactory.create(name="test-workspace", billing_project=billing_project) obj = factories.WorkspaceGroupSharingFactory.create( group=group, workspace=workspace, access=models.WorkspaceGroupSharing.READER ) self.client.force_login(self.user) response = self.client.post( - self.get_url( - obj.workspace.billing_project.name, obj.workspace.name, obj.group.name - ), + self.get_url(obj.workspace.billing_project.name, obj.workspace.name, obj.group.name), {"access": models.WorkspaceGroupSharing.READER, "can_compute": True}, ) self.assertEqual(response.status_code, 200) @@ -22678,12 +20332,8 @@ def test_invalid_reader_can_compute(self): def test_success_message(self): """Response includes a success message if successful.""" group = factories.ManagedGroupFactory.create(name="test-group") - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) - workspace = factories.WorkspaceFactory.create( - name="test-workspace", billing_project=billing_project - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") + workspace = factories.WorkspaceFactory.create(name="test-workspace", billing_project=billing_project) obj = factories.WorkspaceGroupSharingFactory.create( group=group, workspace=workspace, access=models.WorkspaceGroupSharing.READER ) @@ -22695,9 +20345,7 @@ def test_success_message(self): "canCompute": False, } ] - api_url = self.get_api_url( - obj.workspace.billing_project.name, obj.workspace.name - ) + api_url = self.get_api_url(obj.workspace.billing_project.name, obj.workspace.name) self.anvil_response_mock.add( responses.PATCH, api_url, @@ -22707,9 +20355,7 @@ def test_success_message(self): ) self.client.force_login(self.user) response = self.client.post( - self.get_url( - obj.workspace.billing_project.name, obj.workspace.name, obj.group.name - ), + self.get_url(obj.workspace.billing_project.name, obj.workspace.name, obj.group.name), { "access": models.WorkspaceGroupSharing.WRITER, }, @@ -22717,16 +20363,12 @@ def test_success_message(self): ) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.WorkspaceGroupSharingUpdate.success_message, str(messages[0]) - ) + self.assertEqual(views.WorkspaceGroupSharingUpdate.success_message, str(messages[0])) def test_redirects_to_detail(self): """After successfully updating an object, view redirects to the model's get_absolute_url.""" # This needs to use the client because the RequestFactory doesn't handle redirects. - obj = factories.WorkspaceGroupSharingFactory( - access=models.WorkspaceGroupSharing.READER - ) + obj = factories.WorkspaceGroupSharingFactory(access=models.WorkspaceGroupSharing.READER) json_data = [ { "email": obj.group.email, @@ -22735,9 +20377,7 @@ def test_redirects_to_detail(self): "canCompute": False, } ] - api_url = self.get_api_url( - obj.workspace.billing_project.name, obj.workspace.name - ) + api_url = self.get_api_url(obj.workspace.billing_project.name, obj.workspace.name) self.anvil_response_mock.add( responses.PATCH, api_url, @@ -22747,9 +20387,7 @@ def test_redirects_to_detail(self): ) self.client.force_login(self.user) response = self.client.post( - self.get_url( - obj.workspace.billing_project.name, obj.workspace.name, obj.group.name - ), + self.get_url(obj.workspace.billing_project.name, obj.workspace.name, obj.group.name), { "access": models.WorkspaceGroupSharing.WRITER, }, @@ -22758,14 +20396,10 @@ def test_redirects_to_detail(self): def test_post_blank_data_access(self): """Posting blank data to the access field does not update the object.""" - obj = factories.WorkspaceGroupSharingFactory.create( - access=models.WorkspaceGroupSharing.READER - ) + obj = factories.WorkspaceGroupSharingFactory.create(access=models.WorkspaceGroupSharing.READER) self.client.force_login(self.user) response = self.client.post( - self.get_url( - obj.workspace.billing_project.name, obj.workspace.name, obj.group.name - ), + self.get_url(obj.workspace.billing_project.name, obj.workspace.name, obj.group.name), {"access": ""}, ) self.assertEqual(response.status_code, 200) @@ -22796,9 +20430,7 @@ def test_post_blank_data_can_compute(self): "canCompute": False, } ] - api_url = self.get_api_url( - obj.workspace.billing_project.name, obj.workspace.name - ) + api_url = self.get_api_url(obj.workspace.billing_project.name, obj.workspace.name) self.anvil_response_mock.add( responses.PATCH, api_url, @@ -22808,9 +20440,7 @@ def test_post_blank_data_can_compute(self): ) self.client.force_login(self.user) response = self.client.post( - self.get_url( - obj.workspace.billing_project.name, obj.workspace.name, obj.group.name - ), + self.get_url(obj.workspace.billing_project.name, obj.workspace.name, obj.group.name), {"access": models.WorkspaceGroupSharing.WRITER}, ) self.assertEqual(response.status_code, 302) @@ -22820,14 +20450,10 @@ def test_post_blank_data_can_compute(self): def test_post_invalid_data_access(self): """Posting invalid data to the access field does not update the object.""" - obj = factories.WorkspaceGroupSharingFactory.create( - access=models.WorkspaceGroupSharing.READER - ) + obj = factories.WorkspaceGroupSharingFactory.create(access=models.WorkspaceGroupSharing.READER) self.client.force_login(self.user) response = self.client.post( - self.get_url( - obj.workspace.billing_project.name, obj.workspace.name, obj.group.name - ), + self.get_url(obj.workspace.billing_project.name, obj.workspace.name, obj.group.name), {"access": "foo"}, ) self.assertEqual(response.status_code, 200) @@ -22841,9 +20467,7 @@ def test_post_invalid_data_access(self): def test_post_group_pk(self): """Posting a group pk has no effect.""" original_group = factories.ManagedGroupFactory.create() - obj = factories.WorkspaceGroupSharingFactory( - group=original_group, access=models.WorkspaceGroupSharing.READER - ) + obj = factories.WorkspaceGroupSharingFactory(group=original_group, access=models.WorkspaceGroupSharing.READER) new_group = factories.ManagedGroupFactory.create() json_data = [ { @@ -22853,9 +20477,7 @@ def test_post_group_pk(self): "canCompute": False, } ] - api_url = self.get_api_url( - obj.workspace.billing_project.name, obj.workspace.name - ) + api_url = self.get_api_url(obj.workspace.billing_project.name, obj.workspace.name) self.anvil_response_mock.add( responses.PATCH, api_url, @@ -22865,9 +20487,7 @@ def test_post_group_pk(self): ) self.client.force_login(self.user) response = self.client.post( - self.get_url( - obj.workspace.billing_project.name, obj.workspace.name, obj.group.name - ), + self.get_url(obj.workspace.billing_project.name, obj.workspace.name, obj.group.name), { "group": new_group.pk, "access": models.WorkspaceGroupSharing.WRITER, @@ -22892,9 +20512,7 @@ def test_post_workspace_pk(self): "canCompute": False, } ] - api_url = self.get_api_url( - obj.workspace.billing_project.name, obj.workspace.name - ) + api_url = self.get_api_url(obj.workspace.billing_project.name, obj.workspace.name) self.anvil_response_mock.add( responses.PATCH, api_url, @@ -22904,9 +20522,7 @@ def test_post_workspace_pk(self): ) self.client.force_login(self.user) response = self.client.post( - self.get_url( - obj.workspace.billing_project.name, obj.workspace.name, obj.group.name - ), + self.get_url(obj.workspace.billing_project.name, obj.workspace.name, obj.group.name), { "workspace": new_workspace.pk, "access": models.WorkspaceGroupSharing.WRITER, @@ -22919,12 +20535,8 @@ def test_post_workspace_pk(self): def test_api_error(self): """Shows a message if an AnVIL API error occurs.""" # Need a client to check messages. - obj = factories.WorkspaceGroupSharingFactory.create( - access=models.WorkspaceGroupSharing.READER - ) - api_url = self.get_api_url( - obj.workspace.billing_project.name, obj.workspace.name - ) + obj = factories.WorkspaceGroupSharingFactory.create(access=models.WorkspaceGroupSharing.READER) + api_url = self.get_api_url(obj.workspace.billing_project.name, obj.workspace.name) self.anvil_response_mock.add( responses.PATCH, api_url, @@ -22933,9 +20545,7 @@ def test_api_error(self): ) self.client.force_login(self.user) response = self.client.post( - self.get_url( - obj.workspace.billing_project.name, obj.workspace.name, obj.group.name - ), + self.get_url(obj.workspace.billing_project.name, obj.workspace.name, obj.group.name), { "access": models.WorkspaceGroupSharing.WRITER, }, @@ -22968,16 +20578,12 @@ 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) def get_url(self, *args): """Get the url for the view being tested.""" - return reverse( - "anvil_consortium_manager:workspace_group_sharing:list", args=args - ) + return reverse("anvil_consortium_manager:workspace_group_sharing:list", args=args) def get_view(self): """Return the view being tested.""" @@ -22987,9 +20593,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.""" @@ -22999,13 +20603,9 @@ def test_status_code_with_user_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url()) request.user = user @@ -23014,9 +20614,7 @@ def test_access_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): @@ -23026,9 +20624,7 @@ def test_view_has_correct_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.WorkspaceGroupSharingTable - ) + self.assertIsInstance(response.context_data["table"], tables.WorkspaceGroupSharingTable) def test_view_with_no_objects(self): self.client.force_login(self.user) @@ -23066,14 +20662,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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) self.user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME) ) def get_url(self, *args): @@ -23098,14 +20690,10 @@ def get_api_url(self, billing_project_name, workspace_name): 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("billing_project", "workspace", "group") - ) + response = self.client.get(self.get_url("billing_project", "workspace", "group")) self.assertRedirects( response, - resolve_url(settings.LOGIN_URL) - + "?next=" - + self.get_url("billing_project", "workspace", "group"), + resolve_url(settings.LOGIN_URL) + "?next=" + self.get_url("billing_project", "workspace", "group"), ) def test_status_code_with_user_permission(self): @@ -23113,25 +20701,17 @@ def test_status_code_with_user_permission(self): obj = factories.WorkspaceGroupSharingFactory.create() self.client.force_login(self.user) response = self.client.get( - self.get_url( - obj.workspace.billing_project.name, obj.workspace.name, obj.group.name - ) + self.get_url(obj.workspace.billing_project.name, obj.workspace.name, obj.group.name) ) self.assertEqual(response.status_code, 200) 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=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME - ) - ) - request = self.factory.get( - self.get_url("billing_project", "workspace", "group") + Permission.objects.get(codename=models.AnVILProjectManagerAccess.VIEW_PERMISSION_CODENAME) ) + request = self.factory.get(self.get_url("billing_project", "workspace", "group")) request.user = user_with_view_perm with self.assertRaises(PermissionDenied): self.get_view()( @@ -23143,13 +20723,9 @@ def test_access_with_view_permission(self): def test_access_with_limited_view_permission(self): """Raises permission denied if user has limited view permission.""" - user = User.objects.create_user( - username="test-limited", password="test-limited" - ) + user = User.objects.create_user(username="test-limited", password="test-limited") user.user_permissions.add( - Permission.objects.get( - codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME - ) + Permission.objects.get(codename=models.AnVILProjectManagerAccess.LIMITED_VIEW_PERMISSION_CODENAME) ) request = self.factory.get(self.get_url("foo", "bar", "tmp")) request.user = user @@ -23158,12 +20734,8 @@ def test_access_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" - ) - request = self.factory.get( - self.get_url("billing_project", "workspace", "group") - ) + user_no_perms = User.objects.create_user(username="test-none", password="test-none") + request = self.factory.get(self.get_url("billing_project", "workspace", "group")) request.user = user_no_perms with self.assertRaises(PermissionDenied): self.get_view()( @@ -23175,9 +20747,7 @@ def test_access_without_user_permission(self): def test_view_with_invalid_pk(self): """Returns a 404 when the object doesn't exist.""" - request = self.factory.get( - self.get_url("billing_project", "workspace", "group") - ) + request = self.factory.get(self.get_url("billing_project", "workspace", "group")) request.user = self.user with self.assertRaises(Http404): self.get_view()( @@ -23190,15 +20760,9 @@ def test_view_with_invalid_pk(self): def test_view_deletes_object(self): """Posting submit to the form successfully deletes the object.""" group = factories.ManagedGroupFactory.create(name="test-group") - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) - workspace = factories.WorkspaceFactory.create( - name="test-workspace", billing_project=billing_project - ) - obj = factories.WorkspaceGroupSharingFactory.create( - group=group, workspace=workspace - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") + workspace = factories.WorkspaceFactory.create(name="test-workspace", billing_project=billing_project) + obj = factories.WorkspaceGroupSharingFactory.create(group=group, workspace=workspace) json_data = [ { "email": obj.group.email, @@ -23207,9 +20771,7 @@ def test_view_deletes_object(self): "canCompute": False, } ] - api_url = self.get_api_url( - obj.workspace.billing_project.name, obj.workspace.name - ) + api_url = self.get_api_url(obj.workspace.billing_project.name, obj.workspace.name) self.anvil_response_mock.add( responses.PATCH, api_url, @@ -23218,9 +20780,7 @@ def test_view_deletes_object(self): ) self.client.force_login(self.user) response = self.client.post( - self.get_url( - obj.workspace.billing_project.name, obj.workspace.name, obj.group.name - ), + self.get_url(obj.workspace.billing_project.name, obj.workspace.name, obj.group.name), {"submit": ""}, ) self.assertEqual(response.status_code, 302) @@ -23232,15 +20792,9 @@ def test_view_deletes_object(self): def test_success_message(self): """Response includes a success message if successful.""" group = factories.ManagedGroupFactory.create(name="test-group") - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) - workspace = factories.WorkspaceFactory.create( - name="test-workspace", billing_project=billing_project - ) - obj = factories.WorkspaceGroupSharingFactory.create( - group=group, workspace=workspace - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") + workspace = factories.WorkspaceFactory.create(name="test-workspace", billing_project=billing_project) + obj = factories.WorkspaceGroupSharingFactory.create(group=group, workspace=workspace) json_data = [ { "email": obj.group.email, @@ -23249,9 +20803,7 @@ def test_success_message(self): "canCompute": False, } ] - api_url = self.get_api_url( - obj.workspace.billing_project.name, obj.workspace.name - ) + api_url = self.get_api_url(obj.workspace.billing_project.name, obj.workspace.name) self.anvil_response_mock.add( responses.PATCH, api_url, @@ -23260,17 +20812,13 @@ def test_success_message(self): ) self.client.force_login(self.user) response = self.client.post( - self.get_url( - obj.workspace.billing_project.name, obj.workspace.name, obj.group.name - ), + self.get_url(obj.workspace.billing_project.name, obj.workspace.name, obj.group.name), {"submit": ""}, follow=True, ) messages = [m.message for m in get_messages(response.wsgi_request)] self.assertEqual(len(messages), 1) - self.assertEqual( - views.WorkspaceGroupSharingDelete.success_message, str(messages[0]) - ) + self.assertEqual(views.WorkspaceGroupSharingDelete.success_message, str(messages[0])) def test_only_deletes_specified_pk(self): """View only deletes the specified pk.""" @@ -23284,9 +20832,7 @@ def test_only_deletes_specified_pk(self): "canCompute": False, } ] - api_url = self.get_api_url( - obj.workspace.billing_project.name, obj.workspace.name - ) + api_url = self.get_api_url(obj.workspace.billing_project.name, obj.workspace.name) self.anvil_response_mock.add( responses.PATCH, api_url, @@ -23295,9 +20841,7 @@ def test_only_deletes_specified_pk(self): ) self.client.force_login(self.user) response = self.client.post( - self.get_url( - obj.workspace.billing_project.name, obj.workspace.name, obj.group.name - ), + self.get_url(obj.workspace.billing_project.name, obj.workspace.name, obj.group.name), {"submit": ""}, ) self.assertEqual(response.status_code, 302) @@ -23310,12 +20854,8 @@ def test_only_deletes_specified_pk(self): def test_delete_with_can_compute(self): """Can delete a record with can_compute=True.""" group = factories.ManagedGroupFactory.create(name="test-group") - billing_project = factories.BillingProjectFactory.create( - name="test-billing-project" - ) - workspace = factories.WorkspaceFactory.create( - name="test-workspace", billing_project=billing_project - ) + billing_project = factories.BillingProjectFactory.create(name="test-billing-project") + workspace = factories.WorkspaceFactory.create(name="test-workspace", billing_project=billing_project) obj = factories.WorkspaceGroupSharingFactory.create( group=group, workspace=workspace, @@ -23329,9 +20869,7 @@ def test_delete_with_can_compute(self): "canCompute": True, } ] - api_url = self.get_api_url( - obj.workspace.billing_project.name, obj.workspace.name - ) + api_url = self.get_api_url(obj.workspace.billing_project.name, obj.workspace.name) self.anvil_response_mock.add( responses.PATCH, api_url, @@ -23340,9 +20878,7 @@ def test_delete_with_can_compute(self): ) self.client.force_login(self.user) response = self.client.post( - self.get_url( - obj.workspace.billing_project.name, obj.workspace.name, obj.group.name - ), + self.get_url(obj.workspace.billing_project.name, obj.workspace.name, obj.group.name), {"submit": ""}, ) self.assertEqual(response.status_code, 302) @@ -23359,9 +20895,7 @@ def test_success_url(self): "canCompute": False, } ] - api_url = self.get_api_url( - obj.workspace.billing_project.name, obj.workspace.name - ) + api_url = self.get_api_url(obj.workspace.billing_project.name, obj.workspace.name) self.anvil_response_mock.add( responses.PATCH, api_url, @@ -23371,23 +20905,17 @@ def test_success_url(self): # Need to use the client instead of RequestFactory to check redirection url. self.client.force_login(self.user) response = self.client.post( - self.get_url( - obj.workspace.billing_project.name, obj.workspace.name, obj.group.name - ), + self.get_url(obj.workspace.billing_project.name, obj.workspace.name, obj.group.name), {"submit": ""}, ) self.assertEqual(response.status_code, 302) - self.assertRedirects( - response, reverse("anvil_consortium_manager:workspace_group_sharing:list") - ) + self.assertRedirects(response, reverse("anvil_consortium_manager:workspace_group_sharing:list")) def test_api_error(self): """Shows a message if an AnVIL API error occurs.""" # Need a client to check messages. obj = factories.WorkspaceGroupSharingFactory.create() - api_url = self.get_api_url( - obj.workspace.billing_project.name, obj.workspace.name - ) + api_url = self.get_api_url(obj.workspace.billing_project.name, obj.workspace.name) self.anvil_response_mock.add( responses.PATCH, api_url, @@ -23396,9 +20924,7 @@ def test_api_error(self): ) self.client.force_login(self.user) response = self.client.post( - self.get_url( - obj.workspace.billing_project.name, obj.workspace.name, obj.group.name - ), + self.get_url(obj.workspace.billing_project.name, obj.workspace.name, obj.group.name), {"submit": ""}, ) self.assertEqual(response.status_code, 200) diff --git a/anvil_consortium_manager/tests/utils.py b/anvil_consortium_manager/tests/utils.py index 0dd8e640..63f32f7f 100644 --- a/anvil_consortium_manager/tests/utils.py +++ b/anvil_consortium_manager/tests/utils.py @@ -43,17 +43,13 @@ def setUp(self): mock.sentinel.credentials, mock.sentinel.project, ) - self.anvil_response_mock = responses.RequestsMock( - assert_all_requests_are_fired=True - ) + self.anvil_response_mock = responses.RequestsMock(assert_all_requests_are_fired=True) self.anvil_response_mock.start() # Get an instance of the API client to access entry points? self.api_client = AnVILAPIClient() # Set the auth session service account email here, since some functions need it. self.service_account_email = fake.email() - AnVILAPIClient().auth_session.credentials.service_account_email = ( - self.service_account_email - ) + AnVILAPIClient().auth_session.credentials.service_account_email = self.service_account_email def tearDown(self): super().tearDown() diff --git a/anvil_consortium_manager/urls.py b/anvil_consortium_manager/urls.py index 6c065888..0892c75f 100644 --- a/anvil_consortium_manager/urls.py +++ b/anvil_consortium_manager/urls.py @@ -15,9 +15,7 @@ ), path("audit/", views.BillingProjectAudit.as_view(), name="audit"), path("/", views.BillingProjectDetail.as_view(), name="detail"), - path( - "/update/", views.BillingProjectUpdate.as_view(), name="update" - ), + path("/update/", views.BillingProjectUpdate.as_view(), name="update"), ], "billing_projects", ) diff --git a/anvil_consortium_manager/viewmixins.py b/anvil_consortium_manager/viewmixins.py index 5b74097d..18224a7c 100644 --- a/anvil_consortium_manager/viewmixins.py +++ b/anvil_consortium_manager/viewmixins.py @@ -44,15 +44,9 @@ def get_context_data(self, *args, **kwargs): context = super().get_context_data(*args, **kwargs) context["audit_timestamp"] = timezone.now() context["audit_ok"] = self.audit_results.ok() - context["verified_table"] = audit.VerifiedTable( - self.audit_results.get_verified_results() - ) - context["error_table"] = audit.ErrorTable( - self.audit_results.get_error_results() - ) - context["not_in_app_table"] = audit.NotInAppTable( - self.audit_results.get_not_in_app_results() - ) + context["verified_table"] = audit.VerifiedTable(self.audit_results.get_verified_results()) + context["error_table"] = audit.ErrorTable(self.audit_results.get_error_results()) + context["not_in_app_table"] = audit.NotInAppTable(self.audit_results.get_not_in_app_results()) return context @@ -120,10 +114,7 @@ def plot_graph(self): node_x.append(x) node_y.append(y) node_labels.append( - node - + "
Number of groups: {}
Number of accounts: {}".format( - d["n_groups"], d["n_accounts"] - ) + node + "
Number of groups: {}
Number of accounts: {}".format(d["n_groups"], d["n_accounts"]) ) node_annotations.append( go.layout.Annotation( @@ -260,8 +251,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 @@ -301,8 +291,6 @@ class RegisteredWorkspaceAdaptersMixin(ContextMixin): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # Instantiate each adapter class for use in the template. - registered_workspaces = [ - x() for x in workspace_adapter_registry.get_registered_adapters().values() - ] + registered_workspaces = [x() for x in workspace_adapter_registry.get_registered_adapters().values()] context["registered_workspace_adapters"] = registered_workspaces return context diff --git a/anvil_consortium_manager/views.py b/anvil_consortium_manager/views.py index 812cbed1..906a1754 100644 --- a/anvil_consortium_manager/views.py +++ b/anvil_consortium_manager/views.py @@ -13,34 +13,14 @@ from django.utils.translation import gettext_lazy as _ from django.views.generic import CreateView from django.views.generic import DeleteView as DjangoDeleteView -from django.views.generic import ( - DetailView, - FormView, - RedirectView, - TemplateView, - UpdateView, -) -from django.views.generic.detail import ( - BaseDetailView, - SingleObjectMixin, - SingleObjectTemplateResponseMixin, -) +from django.views.generic import DetailView, FormView, RedirectView, TemplateView, UpdateView +from django.views.generic.detail import BaseDetailView, SingleObjectMixin, SingleObjectTemplateResponseMixin from django.views.generic.edit import BaseDeleteView as DjangoBaseDeleteView from django.views.generic.edit import DeletionMixin, FormMixin from django_filters.views import FilterView from django_tables2 import SingleTableMixin, SingleTableView -from . import ( - __version__, - anvil_api, - auth, - exceptions, - filters, - forms, - models, - tables, - viewmixins, -) +from . import __version__, anvil_api, auth, exceptions, filters, forms, models, tables, viewmixins from .adapters.account import get_account_adapter from .adapters.workspace import workspace_adapter_registry from .anvil_api import AnVILAPIClient, AnVILAPIError @@ -128,22 +108,16 @@ def get_context_data(self, **kwargs): context["anvil_user"] = response.json()["userEmail"] except AnVILAPIError: # If the API call failed, rerender the page with the responses and show a message. - messages.add_message( - self.request, messages.ERROR, "AnVIL API Error: error checking API user" - ) + messages.add_message(self.request, messages.ERROR, "AnVIL API Error: error checking API user") context["anvil_user"] = None return context -class BillingProjectImport( - auth.AnVILConsortiumManagerEditRequired, SuccessMessageMixin, CreateView -): +class BillingProjectImport(auth.AnVILConsortiumManagerEditRequired, SuccessMessageMixin, CreateView): model = models.BillingProject form_class = forms.BillingProjectImportForm template_name = "anvil_consortium_manager/billingproject_import.html" - message_not_users_of_billing_project = ( - "Not a user of requested billing project or it doesn't exist on AnVIL." - ) + message_not_users_of_billing_project = "Not a user of requested billing project or it doesn't exist on AnVIL." success_message = "Successfully imported Billing Project from AnVIL." def form_valid(self, form): @@ -155,24 +129,18 @@ def form_valid(self, form): ) except anvil_api.AnVILAPIError404: # Either the workspace doesn't exist or we don't have permission for it. - messages.add_message( - self.request, messages.ERROR, self.message_not_users_of_billing_project - ) + messages.add_message(self.request, messages.ERROR, self.message_not_users_of_billing_project) return self.render_to_response(self.get_context_data(form=form)) except anvil_api.AnVILAPIError as e: # If the API call failed for some other reason, rerender the page with the responses and show a message. - 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)) messages.add_message(self.request, messages.SUCCESS, self.success_message) return HttpResponseRedirect(self.get_success_url()) -class BillingProjectUpdate( - auth.AnVILConsortiumManagerEditRequired, SuccessMessageMixin, UpdateView -): +class BillingProjectUpdate(auth.AnVILConsortiumManagerEditRequired, SuccessMessageMixin, UpdateView): """View to update information about a Billing Project.""" model = models.BillingProject @@ -182,33 +150,23 @@ class BillingProjectUpdate( success_message = "Successfully updated Billing Project." -class BillingProjectDetail( - auth.AnVILConsortiumManagerViewRequired, SingleTableMixin, DetailView -): +class BillingProjectDetail(auth.AnVILConsortiumManagerViewRequired, SingleTableMixin, DetailView): model = models.BillingProject slug_field = "name" context_table_name = "workspace_table" def get_table(self): - return tables.WorkspaceTable( - self.object.workspace_set.all(), exclude="billing_project" - ) + return tables.WorkspaceTable(self.object.workspace_set.all(), exclude="billing_project") def get_context_data(self, **kwargs): """Add show_edit_links to context data.""" context = super().get_context_data(**kwargs) - edit_permission_codename = ( - models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) - context["show_edit_links"] = self.request.user.has_perm( - "anvil_consortium_manager." + edit_permission_codename - ) + edit_permission_codename = models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME + context["show_edit_links"] = self.request.user.has_perm("anvil_consortium_manager." + edit_permission_codename) return context -class BillingProjectList( - auth.AnVILConsortiumManagerViewRequired, SingleTableMixin, FilterView -): +class BillingProjectList(auth.AnVILConsortiumManagerViewRequired, SingleTableMixin, FilterView): model = models.BillingProject table_class = tables.BillingProjectTable ordering = ("name",) @@ -217,9 +175,7 @@ class BillingProjectList( filterset_class = filters.BillingProjectListFilter -class BillingProjectAutocomplete( - auth.AnVILConsortiumManagerViewRequired, autocomplete.Select2QuerySetView -): +class BillingProjectAutocomplete(auth.AnVILConsortiumManagerViewRequired, autocomplete.Select2QuerySetView): """View to provide autocompletion for BillingProjects. Only billing project where the app is a user are included.""" def get_queryset(self): @@ -232,9 +188,7 @@ def get_queryset(self): return qs -class BillingProjectAudit( - auth.AnVILConsortiumManagerViewRequired, viewmixins.AnVILAuditMixin, TemplateView -): +class BillingProjectAudit(auth.AnVILConsortiumManagerViewRequired, viewmixins.AnVILAuditMixin, TemplateView): """View to run an audit on Workspaces and display the results.""" template_name = "anvil_consortium_manager/billing_project_audit.html" @@ -252,12 +206,8 @@ def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # Add an indicator of whether the account is inactive. context["is_inactive"] = self.object.status == models.Account.INACTIVE_STATUS - edit_permission_codename = ( - models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) - context["show_edit_links"] = self.request.user.has_perm( - "anvil_consortium_manager." + edit_permission_codename - ) + edit_permission_codename = models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME + context["show_edit_links"] = self.request.user.has_perm("anvil_consortium_manager." + edit_permission_codename) context["show_deactivate_button"] = not context["is_inactive"] context["show_reactivate_button"] = context["is_inactive"] @@ -271,15 +221,11 @@ def get_context_data(self, **kwargs): group__in=self.object.get_all_groups(), ).order_by("workspace", "group") - context["accessible_workspace_table"] = tables.WorkspaceGroupSharingTable( - workspace_sharing - ) + context["accessible_workspace_table"] = tables.WorkspaceGroupSharingTable(workspace_sharing) return context -class AccountImport( - auth.AnVILConsortiumManagerEditRequired, SuccessMessageMixin, CreateView -): +class AccountImport(auth.AnVILConsortiumManagerEditRequired, SuccessMessageMixin, CreateView): """Import an account from AnVIL. This view checks that the specified email has a valid AnVIL account. If so, it saves a record in the database. @@ -291,9 +237,7 @@ class AccountImport( message_account_does_not_exist = "This account does not exist on AnVIL." """A string that can be displayed if the account does not exist on AnVIL.""" - message_email_associated_with_group = ( - "This email is associated with a group, not a user." - ) + message_email_associated_with_group = "This email is associated with a group, not a user." """A string that can be displayed if the account does not exist on AnVIL.""" form_class = forms.AccountImportForm @@ -313,9 +257,7 @@ def form_valid(self, form): messages.add_message(self.request, messages.ERROR, msg) return self.render_to_response(self.get_context_data(form=form)) if not account_exists: - messages.add_message( - self.request, messages.ERROR, self.message_account_does_not_exist - ) + messages.add_message(self.request, messages.ERROR, self.message_account_does_not_exist) # Re-render the page with a message. return self.render_to_response(self.get_context_data(form=form)) @@ -336,9 +278,7 @@ class AccountUpdate( success_message = "Successfully updated Account." -class AccountLink( - auth.AnVILConsortiumManagerAccountLinkRequired, SuccessMessageMixin, FormView -): +class AccountLink(auth.AnVILConsortiumManagerAccountLinkRequired, SuccessMessageMixin, FormView): """View where a user enter their AnVIL email to get an email verification link.""" login_url = settings.LOGIN_URL @@ -346,13 +286,9 @@ class AccountLink( model = models.UserEmailEntry message_account_does_not_exist = "This account does not exist on AnVIL." message_user_already_linked = "You have already linked an AnVIL account." - message_account_already_exists = ( - "An AnVIL Account with this email already exists in this app." - ) + message_account_already_exists = "An AnVIL Account with this email already exists in this app." form_class = forms.UserEmailEntryForm - success_message = ( - "To complete linking the account, check your email for a verification link." - ) + success_message = "To complete linking the account, check your email for a verification link." def get(self, request, *args, **kwargs): """Check if the user already has an account linked and redirect.""" @@ -362,9 +298,7 @@ def get(self, request, *args, **kwargs): return super().get(request, *args, **kwargs) else: # The user already has a linked account, so redirect with a message. - messages.add_message( - self.request, messages.ERROR, self.message_user_already_linked - ) + messages.add_message(self.request, messages.ERROR, self.message_user_already_linked) return HttpResponseRedirect(reverse(settings.ANVIL_ACCOUNT_LINK_REDIRECT)) def post(self, request, *args, **kwargs): @@ -375,9 +309,7 @@ def post(self, request, *args, **kwargs): return super().post(request, *args, **kwargs) else: # The user already has a linked account, so redirect with a message. - messages.add_message( - self.request, messages.ERROR, self.message_user_already_linked - ) + messages.add_message(self.request, messages.ERROR, self.message_user_already_linked) return HttpResponseRedirect(reverse(settings.ANVIL_ACCOUNT_LINK_REDIRECT)) def get_success_url(self): @@ -388,9 +320,7 @@ def form_valid(self, form): email = form.cleaned_data.get("email") try: - email_entry = models.UserEmailEntry.objects.get( - email__iexact=email, user=self.request.user - ) + email_entry = models.UserEmailEntry.objects.get(email__iexact=email, user=self.request.user) except models.UserEmailEntry.DoesNotExist: email_entry = models.UserEmailEntry(email=email, user=self.request.user) @@ -398,24 +328,18 @@ def form_valid(self, form): # Don't need to check the user, because a user who has already linked their account shouldn't get here. if models.Account.objects.filter(email=email).count(): # The user already has a linked account, so redirect with a message. - messages.add_message( - self.request, messages.ERROR, self.message_account_already_exists - ) + messages.add_message(self.request, messages.ERROR, self.message_account_already_exists) return HttpResponseRedirect(reverse(settings.ANVIL_ACCOUNT_LINK_REDIRECT)) # Check if it exists on AnVIL. try: anvil_account_exists = email_entry.anvil_account_exists() 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)) if not anvil_account_exists: - messages.add_message( - self.request, messages.ERROR, self.message_account_does_not_exist - ) + messages.add_message(self.request, messages.ERROR, self.message_account_does_not_exist) # Re-render the page with a message. return self.render_to_response(self.get_context_data(form=form)) @@ -431,9 +355,7 @@ class AccountLinkVerify(auth.AnVILConsortiumManagerAccountLinkRequired, Redirect message_already_linked = "You have already linked an AnVIL account." message_link_invalid = "AnVIL account verification link is invalid." - message_account_already_exists = ( - "An AnVIL Account with this email already exists in this app." - ) + message_account_already_exists = "An AnVIL Account with this email already exists in this app." message_account_does_not_exist = "This account does not exist on AnVIL." message_success = "Thank you for verifying your email." @@ -443,9 +365,7 @@ def get_redirect_url(self, *args, **kwargs): def get(self, request, *args, **kwargs): # Check if this user already has an account linked. if models.Account.objects.filter(user=request.user).count(): - messages.add_message( - self.request, messages.ERROR, self.message_already_linked - ) + messages.add_message(self.request, messages.ERROR, self.message_already_linked) return super().get(request, *args, **kwargs) uuid = kwargs.get("uuid") @@ -454,23 +374,17 @@ def get(self, request, *args, **kwargs): try: email_entry = models.UserEmailEntry.objects.get(uuid=uuid) except models.UserEmailEntry.DoesNotExist: - messages.add_message( - self.request, messages.ERROR, self.message_link_invalid - ) + messages.add_message(self.request, messages.ERROR, self.message_link_invalid) return super().get(request, *args, **kwargs) # Check if the email is already linked to an account. if models.Account.objects.filter(email=email_entry.email).count(): - messages.add_message( - self.request, messages.ERROR, self.message_account_already_exists - ) + messages.add_message(self.request, messages.ERROR, self.message_account_already_exists) return super().get(request, *args, **kwargs) # Check that the token maches. if not account_verification_token.check_token(email_entry, token): - messages.add_message( - self.request, messages.ERROR, self.message_link_invalid - ) + messages.add_message(self.request, messages.ERROR, self.message_link_invalid) return super().get(request, *args, **kwargs) # Create an account for this user from this email. @@ -485,15 +399,11 @@ def get(self, request, *args, **kwargs): try: anvil_account_exists = account.anvil_exists() 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 super().get(request, *args, **kwargs) if not anvil_account_exists: - messages.add_message( - self.request, messages.ERROR, self.message_account_does_not_exist - ) + messages.add_message(self.request, messages.ERROR, self.message_account_does_not_exist) return super().get(request, *args, **kwargs) # Mark the entry as verified. @@ -566,7 +476,9 @@ class AccountDeactivate( form_class = Form template_name = "anvil_consortium_manager/account_confirm_deactivate.html" context_table_name = "group_table" - message_error_removing_from_groups = "Error removing account from groups; manually verify group memberships on AnVIL. (AnVIL API Error: {})" # noqa + message_error_removing_from_groups = ( + "Error removing account from groups; manually verify group memberships on AnVIL. (AnVIL API Error: {})" # noqa + ) message_already_inactive = "This Account is already inactive." success_message = "Successfully deactivated Account in app." @@ -584,9 +496,7 @@ def get(self, *args, **kwargs): response = super().get(self, *args, **kwargs) # Check if account is inactive. if self.object.status == self.object.INACTIVE_STATUS: - messages.add_message( - self.request, messages.ERROR, self.message_already_inactive - ) + messages.add_message(self.request, messages.ERROR, self.message_already_inactive) # Redirect to the object detail page. return HttpResponseRedirect(self.object.get_absolute_url()) return response @@ -598,9 +508,7 @@ def form_valid(self, form): self.object = self.get_object() if self.object.status == self.object.INACTIVE_STATUS: - messages.add_message( - self.request, messages.ERROR, self.message_already_inactive - ) + messages.add_message(self.request, messages.ERROR, self.message_already_inactive) # Redirect to the object detail page. return HttpResponseRedirect(self.object.get_absolute_url()) @@ -630,7 +538,9 @@ class AccountReactivate( context_table_name = "group_table" form_class = Form template_name = "anvil_consortium_manager/account_confirm_reactivate.html" - message_error_adding_to_groups = "Error adding account to groups; manually verify group memberships on AnVIL. (AnVIL API Error: {})" # noqa + message_error_adding_to_groups = ( + "Error adding account to groups; manually verify group memberships on AnVIL. (AnVIL API Error: {})" # noqa + ) message_already_active = "This Account is already active." success_message = "Successfully reactivated Account in app." @@ -648,9 +558,7 @@ def get(self, *args, **kwargs): self.object = self.get_object() # Check if account is inactive. if self.object.status == self.object.ACTIVE_STATUS: - messages.add_message( - self.request, messages.ERROR, self.message_already_active - ) + messages.add_message(self.request, messages.ERROR, self.message_already_active) # Redirect to the object detail page. return HttpResponseRedirect(self.object.get_absolute_url()) return super().get(self, *args, **kwargs) @@ -660,9 +568,7 @@ def form_valid(self, form): # Set the status to active. self.object = self.get_object() if self.object.status == self.object.ACTIVE_STATUS: - messages.add_message( - self.request, messages.ERROR, self.message_already_active - ) + messages.add_message(self.request, messages.ERROR, self.message_already_active) # Redirect to the object detail page. return HttpResponseRedirect(self.object.get_absolute_url()) @@ -688,7 +594,9 @@ class AccountDelete( DeleteView, ): model = models.Account - message_error_removing_from_groups = "Error removing account from groups; manually verify group memberships on AnVIL. (AnVIL API Error: {})" # noqa + message_error_removing_from_groups = ( + "Error removing account from groups; manually verify group memberships on AnVIL. (AnVIL API Error: {})" # noqa + ) success_message = "Successfully deleted Account from app." def get_success_url(self): @@ -710,9 +618,7 @@ def form_valid(self, form): return super().form_valid(form) -class AccountAutocomplete( - auth.AnVILConsortiumManagerViewRequired, autocomplete.Select2QuerySetView -): +class AccountAutocomplete(auth.AnVILConsortiumManagerViewRequired, autocomplete.Select2QuerySetView): """View to provide autocompletion for Accounts. Only active accounts are included.""" def get_result_label(self, item): @@ -725,9 +631,7 @@ def get_selected_result_label(self, item): def get_queryset(self): # Only active accounts. - qs = models.Account.objects.filter( - status=models.Account.ACTIVE_STATUS - ).order_by("email") + qs = models.Account.objects.filter(status=models.Account.ACTIVE_STATUS).order_by("email") # Use the account adapter to process the query. adapter = get_account_adapter() @@ -736,9 +640,7 @@ def get_queryset(self): return qs -class AccountAudit( - auth.AnVILConsortiumManagerViewRequired, viewmixins.AnVILAuditMixin, TemplateView -): +class AccountAudit(auth.AnVILConsortiumManagerViewRequired, viewmixins.AnVILAuditMixin, TemplateView): """View to run an audit on Accounts and display the results.""" template_name = "anvil_consortium_manager/account_audit.html" @@ -785,15 +687,11 @@ def get_context_data(self, **kwargs): self.object.workspacegroupsharing_set.all(), exclude="group" ) context["active_account_table"] = tables.GroupAccountMembershipTable( - self.object.groupaccountmembership_set.filter( - account__status=models.Account.ACTIVE_STATUS - ), + self.object.groupaccountmembership_set.filter(account__status=models.Account.ACTIVE_STATUS), exclude="group", ) context["inactive_account_table"] = tables.GroupAccountMembershipTable( - self.object.groupaccountmembership_set.filter( - account__status=models.Account.INACTIVE_STATUS - ), + self.object.groupaccountmembership_set.filter(account__status=models.Account.INACTIVE_STATUS), exclude="group", ) context["group_table"] = tables.GroupGroupMembershipTable( @@ -802,18 +700,12 @@ def get_context_data(self, **kwargs): context["parent_table"] = tables.GroupGroupMembershipTable( self.object.parent_memberships.all(), exclude="child_group" ) - edit_permission_codename = ( - models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) - context["show_edit_links"] = self.request.user.has_perm( - "anvil_consortium_manager." + edit_permission_codename - ) + edit_permission_codename = models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME + context["show_edit_links"] = self.request.user.has_perm("anvil_consortium_manager." + edit_permission_codename) return context -class ManagedGroupCreate( - auth.AnVILConsortiumManagerEditRequired, SuccessMessageMixin, CreateView -): +class ManagedGroupCreate(auth.AnVILConsortiumManagerEditRequired, SuccessMessageMixin, CreateView): model = models.ManagedGroup form_class = forms.ManagedGroupCreateForm template_name = "anvil_consortium_manager/managedgroup_create.html" @@ -830,9 +722,7 @@ def form_valid(self, form): self.object.anvil_create() except AnVILAPIError as e: # If the API call failed, rerender the page with the responses and show a message. - 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)) # The object is saved by the super's form_valid method. return super().form_valid(form) @@ -852,9 +742,7 @@ class ManagedGroupUpdate( success_message = "Successfully updated ManagedGroup." -class ManagedGroupList( - auth.AnVILConsortiumManagerViewRequired, SingleTableMixin, FilterView -): +class ManagedGroupList(auth.AnVILConsortiumManagerViewRequired, SingleTableMixin, FilterView): model = models.ManagedGroup table_class = tables.ManagedGroupTable ordering = ("name",) @@ -877,30 +765,16 @@ def get_graph(self): self.graph = G -class ManagedGroupDelete( - auth.AnVILConsortiumManagerEditRequired, SuccessMessageMixin, DeleteView -): +class ManagedGroupDelete(auth.AnVILConsortiumManagerEditRequired, SuccessMessageMixin, DeleteView): model = models.ManagedGroup slug_field = "name" - message_not_managed_by_app = ( - "Cannot delete group because it is not managed by this app." - ) - message_is_auth_domain = ( - "Cannot delete group since it is an authorization domain for a workspace." - ) - message_is_member_of_another_group = ( - "Cannot delete group since it is a member of another group." - ) - message_has_access_to_workspace = ( - "Cannot delete group because it has access to at least one workspace." - ) + message_not_managed_by_app = "Cannot delete group because it is not managed by this app." + message_is_auth_domain = "Cannot delete group since it is an authorization domain for a workspace." + message_is_member_of_another_group = "Cannot delete group since it is a member of another group." + message_has_access_to_workspace = "Cannot delete group because it has access to at least one workspace." # In some cases the AnVIL API returns a successful code but the group is not deleted. - message_could_not_delete_group_from_app = ( - "Cannot delete group from app due to foreign key restrictions." - ) - message_could_not_delete_group_from_anvil = ( - "Cannot not delete group from AnVIL - unknown reason." - ) + message_could_not_delete_group_from_app = "Cannot delete group from app due to foreign key restrictions." + message_could_not_delete_group_from_anvil = "Cannot not delete group from AnVIL - unknown reason." success_message = "Successfully deleted Group on AnVIL." def get_success_url(self): @@ -910,30 +784,22 @@ def get(self, *args, **kwargs): response = super().get(self, *args, **kwargs) # Check if managed by the app. if not self.object.is_managed_by_app: - messages.add_message( - self.request, messages.ERROR, self.message_not_managed_by_app - ) + messages.add_message(self.request, messages.ERROR, self.message_not_managed_by_app) # Redirect to the object detail page. return HttpResponseRedirect(self.object.get_absolute_url()) # Check authorization domains if self.object.workspaceauthorizationdomain_set.count() > 0: # Add a message and redirect. - messages.add_message( - self.request, messages.ERROR, self.message_is_auth_domain - ) + messages.add_message(self.request, messages.ERROR, self.message_is_auth_domain) # Redirect to the object detail page. return HttpResponseRedirect(self.object.get_absolute_url()) # Check that it is not a member of other groups. # This is enforced by AnVIL. if self.object.parent_memberships.count() > 0: - messages.add_message( - self.request, messages.ERROR, self.message_is_member_of_another_group - ) + messages.add_message(self.request, messages.ERROR, self.message_is_member_of_another_group) return HttpResponseRedirect(self.object.get_absolute_url()) if self.object.workspacegroupsharing_set.count() > 0: - messages.add_message( - self.request, messages.ERROR, self.message_has_access_to_workspace - ) + messages.add_message(self.request, messages.ERROR, self.message_has_access_to_workspace) return HttpResponseRedirect(self.object.get_absolute_url()) # Otherwise, return the response. return response @@ -945,30 +811,22 @@ def form_valid(self, form): self.object = self.get_object() # Check that the group is managed by the app. if not self.object.is_managed_by_app: - messages.add_message( - self.request, messages.ERROR, self.message_not_managed_by_app - ) + messages.add_message(self.request, messages.ERROR, self.message_not_managed_by_app) # Redirect to the object detail page. return HttpResponseRedirect(self.object.get_absolute_url()) # Check if it's an auth domain for any workspaces. if self.object.workspaceauthorizationdomain_set.count() > 0: # Add a message and redirect. - messages.add_message( - self.request, messages.ERROR, self.message_is_auth_domain - ) + messages.add_message(self.request, messages.ERROR, self.message_is_auth_domain) # Redirect to the object detail page. return HttpResponseRedirect(self.object.get_absolute_url()) # Check that it is not a member of other groups. # This is enforced by AnVIL. if self.object.parent_memberships.count() > 0: - messages.add_message( - self.request, messages.ERROR, self.message_is_member_of_another_group - ) + messages.add_message(self.request, messages.ERROR, self.message_is_member_of_another_group) return HttpResponseRedirect(self.object.get_absolute_url()) if self.object.workspacegroupsharing_set.count() > 0: - messages.add_message( - self.request, messages.ERROR, self.message_has_access_to_workspace - ) + messages.add_message(self.request, messages.ERROR, self.message_has_access_to_workspace) return HttpResponseRedirect(self.object.get_absolute_url()) try: @@ -988,17 +846,13 @@ def form_valid(self, form): response = HttpResponseRedirect(self.object.get_absolute_url()) except AnVILAPIError as e: # The AnVIL call has failed for some reason. - messages.add_message( - self.request, messages.ERROR, "AnVIL API Error: " + str(e) - ) + messages.add_message(self.request, messages.ERROR, "AnVIL API Error: " + str(e)) # Rerender the same page with an error message. response = self.render_to_response(self.get_context_data()) return response -class ManagedGroupAutocomplete( - auth.AnVILConsortiumManagerViewRequired, autocomplete.Select2QuerySetView -): +class ManagedGroupAutocomplete(auth.AnVILConsortiumManagerViewRequired, autocomplete.Select2QuerySetView): """View to provide autocompletion for ManagedGroups.""" def get_queryset(self): @@ -1015,9 +869,7 @@ def get_queryset(self): return qs -class ManagedGroupAudit( - auth.AnVILConsortiumManagerViewRequired, viewmixins.AnVILAuditMixin, TemplateView -): +class ManagedGroupAudit(auth.AnVILConsortiumManagerViewRequired, viewmixins.AnVILAuditMixin, TemplateView): """View to run an audit on ManagedGroups and display the results.""" template_name = "anvil_consortium_manager/managedgroup_audit.html" @@ -1035,9 +887,7 @@ class ManagedGroupMembershipAudit( model = models.ManagedGroup slug_field = "name" template_name = "anvil_consortium_manager/managedgroup_membership_audit.html" - message_not_managed_by_app = ( - "Cannot audit membership because group is not managed by this app." - ) + message_not_managed_by_app = "Cannot audit membership because group is not managed by this app." def get(self, request, *args, **kwargs): self.object = self.get_object() @@ -1066,12 +916,8 @@ class WorkspaceLandingPage( def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - edit_permission_codename = ( - models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) - context["show_edit_links"] = self.request.user.has_perm( - "anvil_consortium_manager." + edit_permission_codename - ) + edit_permission_codename = models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME + context["show_edit_links"] = self.request.user.has_perm("anvil_consortium_manager." + edit_permission_codename) return context @@ -1093,16 +939,13 @@ def get_object(self, queryset=None): # Filter the queryset based on kwargs. billing_project_slug = self.kwargs.get("billing_project_slug", None) workspace_slug = self.kwargs.get("workspace_slug", None) - queryset = queryset.filter( - billing_project__name=billing_project_slug, name=workspace_slug - ) + queryset = queryset.filter(billing_project__name=billing_project_slug, name=workspace_slug) try: # Get the single item from the filtered queryset 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 @@ -1125,12 +968,8 @@ def get_context_data(self, **kwargs): self.object.authorization_domains.all(), exclude=["workspace", "number_groups", "number_accounts"], ) - edit_permission_codename = ( - models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) - context["show_edit_links"] = self.request.user.has_perm( - "anvil_consortium_manager." + edit_permission_codename - ) + edit_permission_codename = models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME + context["show_edit_links"] = self.request.user.has_perm("anvil_consortium_manager." + edit_permission_codename) return context def get_template_names(self): @@ -1219,31 +1058,21 @@ def form_valid(self, form): return self.forms_invalid(form, workspace_data_formset) # Now save the auth domains and the workspace_data_form. for auth_domain in form.cleaned_data["authorization_domains"]: - models.WorkspaceAuthorizationDomain.objects.create( - workspace=self.workspace, group=auth_domain - ) + models.WorkspaceAuthorizationDomain.objects.create(workspace=self.workspace, group=auth_domain) workspace_data_formset.forms[0].save() # Then create the workspace on AnVIL. self.workspace.anvil_create() except AnVILAPIError as e: # If the API call failed, rerender the page with the responses and show a message. - 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, workspace_data_formset=workspace_data_formset - ) + self.get_context_data(form=form, workspace_data_formset=workspace_data_formset) ) return super().form_valid(form) def forms_invalid(self, form, workspace_data_formset): """If the form(s) are invalid, render the invalid form.""" - return self.render_to_response( - self.get_context_data( - form=form, workspace_data_formset=workspace_data_formset - ) - ) + return self.render_to_response(self.get_context_data(form=form, workspace_data_formset=workspace_data_formset)) def get_success_url(self): return self.workspace.get_absolute_url() @@ -1256,9 +1085,7 @@ class WorkspaceImport( FormView, ): template_name = "anvil_consortium_manager/workspace_import.html" - message_anvil_no_access_to_workspace = ( - "Requested workspace doesn't exist or you don't have permission to see it." - ) + message_anvil_no_access_to_workspace = "Requested workspace doesn't exist or you don't have permission to see it." message_anvil_not_owner = "Not an owner of this workspace." message_workspace_exists = "This workspace already exists in the web app." message_error_fetching_workspaces = "Unable to fetch workspaces from AnVIL." @@ -1271,11 +1098,7 @@ def get_form(self): """Return the form instance with the list of available workspaces to import.""" try: all_workspaces = ( - AnVILAPIClient() - .list_workspaces( - fields="workspace.namespace,workspace.name,accessLevel" - ) - .json() + AnVILAPIClient().list_workspaces(fields="workspace.namespace,workspace.name,accessLevel").json() ) # Filter workspaces to only owners and not imported. workspaces = [ @@ -1292,19 +1115,13 @@ def get_form(self): workspace_choices = [(x, x) for x in workspaces] if not len(workspace_choices): - messages.add_message( - self.request, messages.INFO, self.message_no_available_workspaces - ) + messages.add_message(self.request, messages.INFO, self.message_no_available_workspaces) except AnVILAPIError: workspace_choices = [] - messages.add_message( - self.request, messages.ERROR, self.message_error_fetching_workspaces - ) + messages.add_message(self.request, messages.ERROR, self.message_error_fetching_workspaces) - return forms.WorkspaceImportForm( - workspace_choices=workspace_choices, **self.get_form_kwargs() - ) + return forms.WorkspaceImportForm(workspace_choices=workspace_choices, **self.get_form_kwargs()) def get_workspace_data_formset(self): """Return an instance of the workspace data form to be used in this view.""" @@ -1382,19 +1199,13 @@ def form_valid(self, form): return self.forms_invalid(form, workspace_data_formset) workspace_data_formset.forms[0].save() except anvil_api.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)) return super().form_valid(form) def forms_invalid(self, form, workspace_data_formset): """If the form is invalid, render the invalid form.""" - return self.render_to_response( - self.get_context_data( - form=form, workspace_data_formset=workspace_data_formset - ) - ) + return self.render_to_response(self.get_context_data(form=form, workspace_data_formset=workspace_data_formset)) class WorkspaceClone( @@ -1416,16 +1227,13 @@ def get_object(self, queryset=None): # Filter the queryset based on kwargs. billing_project_slug = self.kwargs.get("billing_project_slug") workspace_slug = self.kwargs.get("workspace_slug") - queryset = queryset.filter( - billing_project__name=billing_project_slug, name=workspace_slug - ) + queryset = queryset.filter(billing_project__name=billing_project_slug, name=workspace_slug) try: # Get the single item from the filtered queryset 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 @@ -1513,9 +1321,7 @@ def form_valid(self, form): return self.forms_invalid(form, workspace_data_formset) # Now save the auth domains and the workspace_data_form. for auth_domain in form.cleaned_data["authorization_domains"]: - models.WorkspaceAuthorizationDomain.objects.create( - workspace=self.new_workspace, group=auth_domain - ) + models.WorkspaceAuthorizationDomain.objects.create(workspace=self.new_workspace, group=auth_domain) workspace_data_formset.forms[0].save() # Then create the workspace on AnVIL. authorization_domains = self.new_workspace.authorization_domains.all() @@ -1526,23 +1332,15 @@ def form_valid(self, form): ) except AnVILAPIError as e: # If the API call failed, rerender the page with the responses and show a message. - 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, workspace_data_formset=workspace_data_formset - ) + self.get_context_data(form=form, workspace_data_formset=workspace_data_formset) ) return super().form_valid(form) def forms_invalid(self, form, workspace_data_formset): """If the form(s) are invalid, render the invalid form.""" - return self.render_to_response( - self.get_context_data( - form=form, workspace_data_formset=workspace_data_formset - ) - ) + return self.render_to_response(self.get_context_data(form=form, workspace_data_formset=workspace_data_formset)) def get_success_url(self): return self.new_workspace.get_absolute_url() @@ -1584,16 +1382,13 @@ def get_object(self, queryset=None): # Filter the queryset based on kwargs. billing_project_slug = self.kwargs.get("billing_project_slug", None) workspace_slug = self.kwargs.get("workspace_slug", None) - queryset = queryset.filter( - billing_project__name=billing_project_slug, name=workspace_slug - ) + queryset = queryset.filter(billing_project__name=billing_project_slug, name=workspace_slug) try: # Get the single item from the filtered queryset 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 @@ -1630,9 +1425,7 @@ def get_workspace_data_formset(self): initial=[{"workspace": self.object}], ) else: - formset = formset_factory( - prefix=formset_prefix, initial=[{}], instance=self.object - ) + formset = formset_factory(prefix=formset_prefix, initial=[{}], instance=self.object) return formset def get_context_data(self, **kwargs): @@ -1664,19 +1457,13 @@ def form_valid(self, form, workspace_data_formset): def forms_invalid(self, form, workspace_data_formset): """If the form(s) are invalid, render the invalid form.""" - return self.render_to_response( - self.get_context_data( - form=form, workspace_data_formset=workspace_data_formset - ) - ) + return self.render_to_response(self.get_context_data(form=form, workspace_data_formset=workspace_data_formset)) def get_success_url(self): return self.object.get_absolute_url() -class WorkspaceList( - auth.AnVILConsortiumManagerViewRequired, SingleTableMixin, FilterView -): +class WorkspaceList(auth.AnVILConsortiumManagerViewRequired, SingleTableMixin, FilterView): """Display a list of all workspaces using the default table.""" model = models.Workspace @@ -1719,14 +1506,10 @@ def get_table_class(self): return table_class -class WorkspaceDelete( - auth.AnVILConsortiumManagerEditRequired, SuccessMessageMixin, DeleteView -): +class WorkspaceDelete(auth.AnVILConsortiumManagerEditRequired, SuccessMessageMixin, DeleteView): model = models.Workspace success_message = "Successfully deleted Workspace on AnVIL." - message_could_not_delete_workspace_from_app = ( - "Cannot delete workspace from app due to foreign key restrictions." - ) + message_could_not_delete_workspace_from_app = "Cannot delete workspace from app due to foreign key restrictions." message_workspace_locked = "Cannot delete workspace because it is locked." def get(self, request, *args, **kwargs): @@ -1758,16 +1541,13 @@ def get_object(self, queryset=None): # Filter the queryset based on kwargs. billing_project_slug = self.kwargs.get("billing_project_slug", None) workspace_slug = self.kwargs.get("workspace_slug", None) - queryset = queryset.filter( - billing_project__name=billing_project_slug, name=workspace_slug - ) + queryset = queryset.filter(billing_project__name=billing_project_slug, name=workspace_slug) try: # Get the single item from the filtered queryset 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 @@ -1799,17 +1579,13 @@ def form_valid(self, form): response = HttpResponseRedirect(self.object.get_absolute_url()) except AnVILAPIError as e: # The AnVIL call has failed for some reason. - messages.add_message( - self.request, messages.ERROR, "AnVIL API Error: " + str(e) - ) + messages.add_message(self.request, messages.ERROR, "AnVIL API Error: " + str(e)) # Rerender the same page with an error message. response = self.render_to_response(self.get_context_data()) return response -class WorkspaceAudit( - auth.AnVILConsortiumManagerViewRequired, viewmixins.AnVILAuditMixin, TemplateView -): +class WorkspaceAudit(auth.AnVILConsortiumManagerViewRequired, viewmixins.AnVILAuditMixin, TemplateView): """View to run an audit on Workspaces and display the results.""" template_name = "anvil_consortium_manager/workspace_audit.html" @@ -1837,16 +1613,13 @@ def get_object(self, queryset=None): # Filter the queryset based on kwargs. billing_project_slug = self.kwargs.get("billing_project_slug", None) workspace_slug = self.kwargs.get("workspace_slug", None) - queryset = queryset.filter( - billing_project__name=billing_project_slug, name=workspace_slug - ) + queryset = queryset.filter(billing_project__name=billing_project_slug, name=workspace_slug) try: # Get the single item from the filtered queryset 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 @@ -1859,9 +1632,7 @@ def get_audit_instance(self): return audit.WorkspaceSharingAudit(self.object) -class WorkspaceAutocomplete( - auth.AnVILConsortiumManagerViewRequired, autocomplete.Select2QuerySetView -): +class WorkspaceAutocomplete(auth.AnVILConsortiumManagerViewRequired, autocomplete.Select2QuerySetView): """View to provide autocompletion for Workspaces. Right now this only matches Workspace name, not billing project.""" @@ -1893,9 +1664,7 @@ def get_queryset(self): ) # Use the workspace adapter to process the query. - qs = self.adapter.get_autocomplete_queryset( - qs, self.q, forwarded=self.forwarded - ) + qs = self.adapter.get_autocomplete_queryset(qs, self.q, forwarded=self.forwarded) return qs @@ -1913,33 +1682,24 @@ def get_object(self, queryset=None): # Filter the queryset based on kwargs. parent_group_slug = self.kwargs.get("parent_group_slug", None) child_group_slug = self.kwargs.get("child_group_slug", None) - queryset = queryset.filter( - parent_group__name=parent_group_slug, child_group__name=child_group_slug - ) + queryset = queryset.filter(parent_group__name=parent_group_slug, child_group__name=child_group_slug) try: # Get the single item from the filtered queryset 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) - edit_permission_codename = ( - models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) - context["show_edit_links"] = self.request.user.has_perm( - "anvil_consortium_manager." + edit_permission_codename - ) + edit_permission_codename = models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME + context["show_edit_links"] = self.request.user.has_perm("anvil_consortium_manager." + edit_permission_codename) return context -class GroupGroupMembershipCreate( - auth.AnVILConsortiumManagerEditRequired, SuccessMessageMixin, CreateView -): +class GroupGroupMembershipCreate(auth.AnVILConsortiumManagerEditRequired, SuccessMessageMixin, CreateView): model = models.GroupGroupMembership form_class = forms.GroupGroupMembershipForm success_message = "Successfully created group membership." @@ -1956,9 +1716,7 @@ def form_valid(self, form): self.object.anvil_create() except AnVILAPIError as e: # If the API call failed, rerender the page with the responses and show a message. - 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)) # The object is saved by the super's form_valid method. return super().form_valid(form) @@ -2063,13 +1821,9 @@ def get_success_url(self): class GroupGroupMembershipCreateByParentChild(GroupGroupMembershipCreate): """View to create a new GroupGroupMembership object for the parent and child groups specified in the url.""" - template_name = ( - "anvil_consortium_manager/groupgroupmembership_form_byparentchild.html" - ) + template_name = "anvil_consortium_manager/groupgroupmembership_form_byparentchild.html" - message_already_exists = ( - "Child group is already a member of the parent Managed Group." - ) + message_already_exists = "Child group is already a member of the parent Managed Group." message_cannot_add_group_to_itself = "Cannot add a group to itself as a member." message_circular_relationship = "Cannot add a circular group relationship." message_not_managed_by_app = "Parent group is not managed by this app." @@ -2107,9 +1861,7 @@ def get(self, request, *args, **kwargs): messages.error(self.request, error) return HttpResponseRedirect(self.parent_group.get_absolute_url()) try: - obj = models.GroupGroupMembership.objects.get( - parent_group=self.parent_group, child_group=self.child_group - ) + obj = models.GroupGroupMembership.objects.get(parent_group=self.parent_group, child_group=self.child_group) messages.error(self.request, self.message_already_exists) return HttpResponseRedirect(obj.get_absolute_url()) except models.GroupGroupMembership.DoesNotExist: @@ -2123,9 +1875,7 @@ def post(self, request, *args, **kwargs): messages.error(self.request, error) return HttpResponseRedirect(self.parent_group.get_absolute_url()) try: - obj = models.GroupGroupMembership.objects.get( - parent_group=self.parent_group, child_group=self.child_group - ) + obj = models.GroupGroupMembership.objects.get(parent_group=self.parent_group, child_group=self.child_group) messages.error(self.request, self.message_already_exists) return HttpResponseRedirect(obj.get_absolute_url()) except models.GroupGroupMembership.DoesNotExist: @@ -2154,16 +1904,12 @@ def get_success_url(self): return self.object.get_absolute_url() -class GroupGroupMembershipList( - auth.AnVILConsortiumManagerViewRequired, SingleTableView -): +class GroupGroupMembershipList(auth.AnVILConsortiumManagerViewRequired, SingleTableView): model = models.GroupGroupMembership table_class = tables.GroupGroupMembershipTable -class GroupGroupMembershipDelete( - auth.AnVILConsortiumManagerEditRequired, SuccessMessageMixin, DeleteView -): +class GroupGroupMembershipDelete(auth.AnVILConsortiumManagerEditRequired, SuccessMessageMixin, DeleteView): model = models.GroupGroupMembership success_message = "Successfully deleted group membership on AnVIL." @@ -2181,16 +1927,13 @@ def get_object(self, queryset=None): # Filter the queryset based on kwargs. parent_group_slug = self.kwargs.get("parent_group_slug", None) child_group_slug = self.kwargs.get("child_group_slug", None) - queryset = queryset.filter( - parent_group__name=parent_group_slug, child_group__name=child_group_slug - ) + queryset = queryset.filter(parent_group__name=parent_group_slug, child_group__name=child_group_slug) try: # Get the single item from the filtered queryset 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 @@ -2231,9 +1974,7 @@ def form_valid(self, form): self.object.anvil_delete() except AnVILAPIError as e: # The AnVIL call has failed for some reason. - messages.add_message( - self.request, messages.ERROR, "AnVIL API Error: " + str(e) - ) + messages.add_message(self.request, messages.ERROR, "AnVIL API Error: " + str(e)) # Rerender the same page with an error message. return self.render_to_response(self.get_context_data()) return super().form_valid(form) @@ -2258,25 +1999,18 @@ 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) - edit_permission_codename = ( - models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) - context["show_edit_links"] = self.request.user.has_perm( - "anvil_consortium_manager." + edit_permission_codename - ) + edit_permission_codename = models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME + context["show_edit_links"] = self.request.user.has_perm("anvil_consortium_manager." + edit_permission_codename) return context -class GroupAccountMembershipCreate( - auth.AnVILConsortiumManagerEditRequired, SuccessMessageMixin, CreateView -): +class GroupAccountMembershipCreate(auth.AnVILConsortiumManagerEditRequired, SuccessMessageMixin, CreateView): model = models.GroupAccountMembership form_class = forms.GroupAccountMembershipForm success_message = "Successfully added account membership." @@ -2293,9 +2027,7 @@ def form_valid(self, form): self.object.anvil_create() except AnVILAPIError as e: # If the API call failed, rerender the page with the responses and show a message. - 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)) # The object is saved by the super's form_valid method. return super().form_valid(form) @@ -2306,9 +2038,7 @@ class GroupAccountMembershipCreateByGroup(GroupAccountMembershipCreate): template_name = "anvil_consortium_manager/groupaccountmembership_form_bygroup.html" - message_not_managed_by_app = ( - "Cannot add Account because this group is not managed by the app." - ) + message_not_managed_by_app = "Cannot add Account because this group is not managed by the app." message_group_not_found = "Managed Group not found on AnVIL." """Message to display when the ManagedGroup was not found on AnVIL.""" @@ -2359,13 +2089,9 @@ def get_success_url(self): class GroupAccountMembershipCreateByAccount(GroupAccountMembershipCreate): """View to create a new GroupAccountMembership for the account specified in the url.""" - template_name = ( - "anvil_consortium_manager/groupaccountmembership_form_byaccount.html" - ) + template_name = "anvil_consortium_manager/groupaccountmembership_form_byaccount.html" - message_not_managed_by_app = ( - "Cannot add Account because this group is not managed by the app." - ) + message_not_managed_by_app = "Cannot add Account because this group is not managed by the app." message_group_not_found = "Managed Group not found on AnVIL." """Message to display when the ManagedGroup was not found on AnVIL.""" @@ -2410,9 +2136,7 @@ def get_success_url(self): class GroupAccountMembershipCreateByGroupAccount(GroupAccountMembershipCreate): """View to create a new GroupAccountMembership object for the group and account specified in the url.""" - template_name = ( - "anvil_consortium_manager/groupaccountmembership_form_bygroupaccount.html" - ) + template_name = "anvil_consortium_manager/groupaccountmembership_form_bygroupaccount.html" message_group_not_found = "Managed Group not found on AnVIL." """Message to display when the ManagedGroup was not found on AnVIL.""" @@ -2439,9 +2163,7 @@ def get(self, request, *args, **kwargs): self.account = self.get_account() self.group = self.get_group() try: - obj = models.GroupAccountMembership.objects.get( - account=self.account, group=self.group - ) + obj = models.GroupAccountMembership.objects.get(account=self.account, group=self.group) messages.error(self.request, self.message_already_exists) return HttpResponseRedirect(obj.get_absolute_url()) except models.GroupAccountMembership.DoesNotExist: @@ -2451,9 +2173,7 @@ def post(self, request, *args, **kwargs): self.account = self.get_account() self.group = self.get_group() try: - obj = models.GroupAccountMembership.objects.get( - account=self.account, group=self.group - ) + obj = models.GroupAccountMembership.objects.get(account=self.account, group=self.group) messages.error(self.request, self.message_already_exists) return HttpResponseRedirect(obj.get_absolute_url()) except models.GroupAccountMembership.DoesNotExist: @@ -2482,18 +2202,14 @@ def get_success_url(self): return self.object.get_absolute_url() -class GroupAccountMembershipList( - auth.AnVILConsortiumManagerViewRequired, SingleTableView -): +class GroupAccountMembershipList(auth.AnVILConsortiumManagerViewRequired, SingleTableView): """Show a list of all group memberships regardless of account active/inactive status.""" model = models.GroupAccountMembership table_class = tables.GroupAccountMembershipTable -class GroupAccountMembershipActiveList( - auth.AnVILConsortiumManagerViewRequired, SingleTableView -): +class GroupAccountMembershipActiveList(auth.AnVILConsortiumManagerViewRequired, SingleTableView): """Show a list of all group memberships for active accounts.""" model = models.GroupAccountMembership @@ -2507,9 +2223,7 @@ def get_queryset(self): return self.model.objects.filter(account__status=models.Account.ACTIVE_STATUS) -class GroupAccountMembershipInactiveList( - auth.AnVILConsortiumManagerViewRequired, SingleTableView -): +class GroupAccountMembershipInactiveList(auth.AnVILConsortiumManagerViewRequired, SingleTableView): """Show a list of all group memberships for inactive accounts.""" model = models.GroupAccountMembership @@ -2523,15 +2237,11 @@ def get_queryset(self): return self.model.objects.filter(account__status=models.Account.INACTIVE_STATUS) -class GroupAccountMembershipDelete( - auth.AnVILConsortiumManagerEditRequired, SuccessMessageMixin, DeleteView -): +class GroupAccountMembershipDelete(auth.AnVILConsortiumManagerEditRequired, SuccessMessageMixin, DeleteView): model = models.GroupAccountMembership success_message = "Successfully deleted account membership on AnVIL." - message_group_not_managed_by_app = ( - "Cannot remove members from group because it is not managed by this app." - ) + message_group_not_managed_by_app = "Cannot remove members from group because it is not managed by this app." def get_object(self, queryset=None): """Return the object the view is displaying.""" @@ -2549,8 +2259,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 @@ -2561,9 +2270,7 @@ def get(self, request, *args, **kwargs): response = super().get(self, *args, **kwargs) # Check if managed by the app. if not self.object.group.is_managed_by_app: - messages.add_message( - self.request, messages.ERROR, self.message_group_not_managed_by_app - ) + messages.add_message(self.request, messages.ERROR, self.message_group_not_managed_by_app) # Redirect to the object detail page. return HttpResponseRedirect(self.object.get_absolute_url()) # Otherwise, return the response. @@ -2577,9 +2284,7 @@ def form_valid(self, form): self.group = self.object.group # Check if managed by the app. if not self.object.group.is_managed_by_app: - messages.add_message( - self.request, messages.ERROR, self.message_group_not_managed_by_app - ) + messages.add_message(self.request, messages.ERROR, self.message_group_not_managed_by_app) # Redirect to the object detail page. return HttpResponseRedirect(self.object.get_absolute_url()) # Try to delete from AnVIL. @@ -2587,9 +2292,7 @@ def form_valid(self, form): self.object.anvil_delete() except AnVILAPIError as e: # The AnVIL call has failed for some reason. - messages.add_message( - self.request, messages.ERROR, "AnVIL API Error: " + str(e) - ) + messages.add_message(self.request, messages.ERROR, "AnVIL API Error: " + str(e)) # Rerender the same page with an error message. return self.render_to_response(self.get_context_data()) return super().form_valid(form) @@ -2619,25 +2322,18 @@ 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) - edit_permission_codename = ( - models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME - ) - context["show_edit_links"] = self.request.user.has_perm( - "anvil_consortium_manager." + edit_permission_codename - ) + edit_permission_codename = models.AnVILProjectManagerAccess.EDIT_PERMISSION_CODENAME + context["show_edit_links"] = self.request.user.has_perm("anvil_consortium_manager." + edit_permission_codename) return context -class WorkspaceGroupSharingCreate( - auth.AnVILConsortiumManagerEditRequired, SuccessMessageMixin, CreateView -): +class WorkspaceGroupSharingCreate(auth.AnVILConsortiumManagerEditRequired, SuccessMessageMixin, CreateView): """View to create a new WorkspaceGroupSharing object and share the Workspace with a Group on AnVIL.""" model = models.WorkspaceGroupSharing @@ -2660,15 +2356,11 @@ def form_valid(self, form): try: self.object.anvil_create_or_update() except exceptions.AnVILGroupNotFound: - messages.add_message( - self.request, messages.ERROR, self.message_group_not_found - ) + messages.add_message(self.request, messages.ERROR, self.message_group_not_found) return self.render_to_response(self.get_context_data(form=form)) except AnVILAPIError as e: # If the API call failed, rerender the page with the responses and show a message. - 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)) # The object is saved by the super's form_valid method. return super().form_valid(form) @@ -2679,26 +2371,20 @@ class WorkspaceGroupSharingCreateByWorkspace(WorkspaceGroupSharingCreate): model = models.WorkspaceGroupSharing form_class = forms.WorkspaceGroupSharingForm - template_name = ( - "anvil_consortium_manager/workspacegroupsharing_form_byworkspace.html" - ) + template_name = "anvil_consortium_manager/workspacegroupsharing_form_byworkspace.html" success_message = "Successfully shared Workspace with Group." """Message to display when the WorkspaceGroupSharing object was successfully created in the app and on AnVIL.""" message_group_not_found = "Managed Group not found on AnVIL." """Message to display when the ManagedGroup was not found on AnVIL.""" - message_already_exists = ( - "This workspace has already been shared with this managed group." - ) + message_already_exists = "This workspace has already been shared with this managed group." def get_workspace(self): try: billing_project_slug = self.kwargs["billing_project_slug"] workspace_slug = self.kwargs["workspace_slug"] - workspace = models.Workspace.objects.get( - billing_project__name=billing_project_slug, name=workspace_slug - ) + workspace = models.Workspace.objects.get(billing_project__name=billing_project_slug, name=workspace_slug) except models.Workspace.DoesNotExist: raise Http404("Workspace not found.") return workspace @@ -2743,9 +2429,7 @@ class WorkspaceGroupSharingCreateByGroup(WorkspaceGroupSharingCreate): message_group_not_found = "Managed Group not found on AnVIL." """Message to display when the ManagedGroup was not found on AnVIL.""" - message_already_exists = ( - "This workspace has already been shared with this managed group." - ) + message_already_exists = "This workspace has already been shared with this managed group." def get_group(self): try: @@ -2788,26 +2472,20 @@ class WorkspaceGroupSharingCreateByWorkspaceGroup(WorkspaceGroupSharingCreate): model = models.WorkspaceGroupSharing form_class = forms.WorkspaceGroupSharingForm - template_name = ( - "anvil_consortium_manager/workspacegroupsharing_form_byworkspacegroup.html" - ) + template_name = "anvil_consortium_manager/workspacegroupsharing_form_byworkspacegroup.html" success_message = "Successfully shared Workspace with Group." """Message to display when the WorkspaceGroupSharing object was successfully created in the app and on AnVIL.""" message_group_not_found = "Managed Group not found on AnVIL." """Message to display when the ManagedGroup was not found on AnVIL.""" - message_already_exists = ( - "This workspace has already been shared with this managed group." - ) + message_already_exists = "This workspace has already been shared with this managed group." def get_workspace(self): try: billing_project_slug = self.kwargs["billing_project_slug"] workspace_slug = self.kwargs["workspace_slug"] - workspace = models.Workspace.objects.get( - billing_project__name=billing_project_slug, name=workspace_slug - ) + workspace = models.Workspace.objects.get(billing_project__name=billing_project_slug, name=workspace_slug) except models.Workspace.DoesNotExist: raise Http404("Workspace not found.") return workspace @@ -2824,9 +2502,7 @@ def get(self, request, *args, **kwargs): self.workspace = self.get_workspace() self.group = self.get_group() try: - obj = models.WorkspaceGroupSharing.objects.get( - workspace=self.workspace, group=self.group - ) + obj = models.WorkspaceGroupSharing.objects.get(workspace=self.workspace, group=self.group) messages.error(self.request, self.message_already_exists) return HttpResponseRedirect(obj.get_absolute_url()) except models.WorkspaceGroupSharing.DoesNotExist: @@ -2836,9 +2512,7 @@ def post(self, request, *args, **kwargs): self.workspace = self.get_workspace() self.group = self.get_group() try: - obj = models.WorkspaceGroupSharing.objects.get( - workspace=self.workspace, group=self.group - ) + obj = models.WorkspaceGroupSharing.objects.get(workspace=self.workspace, group=self.group) messages.error(self.request, self.message_already_exists) return HttpResponseRedirect(obj.get_absolute_url()) except models.WorkspaceGroupSharing.DoesNotExist: @@ -2867,9 +2541,7 @@ def get_success_url(self): return self.object.get_absolute_url() -class WorkspaceGroupSharingUpdate( - auth.AnVILConsortiumManagerEditRequired, SuccessMessageMixin, UpdateView -): +class WorkspaceGroupSharingUpdate(auth.AnVILConsortiumManagerEditRequired, SuccessMessageMixin, UpdateView): """View to update a WorkspaceGroupSharing object and on AnVIL.""" model = models.WorkspaceGroupSharing @@ -2902,8 +2574,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 @@ -2916,24 +2587,18 @@ def form_valid(self, form): self.object.anvil_create_or_update() except AnVILAPIError as e: # If the API call failed, rerender the page with the responses and show a message. - 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)) # The object is saved by the super's form_valid method. return super().form_valid(form) -class WorkspaceGroupSharingList( - auth.AnVILConsortiumManagerViewRequired, SingleTableView -): +class WorkspaceGroupSharingList(auth.AnVILConsortiumManagerViewRequired, SingleTableView): model = models.WorkspaceGroupSharing table_class = tables.WorkspaceGroupSharingTable -class WorkspaceGroupSharingDelete( - auth.AnVILConsortiumManagerEditRequired, SuccessMessageMixin, DeleteView -): +class WorkspaceGroupSharingDelete(auth.AnVILConsortiumManagerEditRequired, SuccessMessageMixin, DeleteView): model = models.WorkspaceGroupSharing success_message = "Successfully removed workspace sharing on AnVIL." @@ -2958,8 +2623,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 @@ -2975,9 +2639,7 @@ def form_valid(self, form): self.object.anvil_delete() except AnVILAPIError as e: # The AnVIL call has failed for some reason. - messages.add_message( - self.request, messages.ERROR, "AnVIL API Error: " + str(e) - ) + messages.add_message(self.request, messages.ERROR, "AnVIL API Error: " + str(e)) # Rerender the same page with an error message. return self.render_to_response(self.get_context_data()) return super().form_valid(form) diff --git a/example_site/__init__.py b/example_site/__init__.py index e1d86152..eed836da 100644 --- a/example_site/__init__.py +++ b/example_site/__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/example_site/settings.py b/example_site/settings.py index 92253f91..24f79c94 100644 --- a/example_site/settings.py +++ b/example_site/settings.py @@ -168,10 +168,7 @@ "version": 1, "disable_existing_loggers": False, "formatters": { - "verbose": { - "format": "%(levelname)s %(asctime)s %(module)s " - "%(process)d %(thread)d %(message)s" - } + "verbose": {"format": "%(levelname)s %(asctime)s %(module)s " "%(process)d %(thread)d %(message)s"} }, "handlers": { "console": { @@ -223,6 +220,4 @@ "example_site.app.adapters.CustomWorkspaceAdapter", ] # Account adapter. -ANVIL_ACCOUNT_ADAPTER = ( - "anvil_consortium_manager.adapters.default.DefaultAccountAdapter" -) +ANVIL_ACCOUNT_ADAPTER = "anvil_consortium_manager.adapters.default.DefaultAccountAdapter" diff --git a/pyproject.toml b/pyproject.toml index 97fe5794..28af285a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,8 +43,12 @@ dependencies = [ [tool.setuptools.packages.find] include = ["anvil_consortium_manager*"] +[tool.black] +line-length = 119 + [tool.isort] -line_length = 88 +profile = "black" +line_length = 119 known_first_party = ["anvil_consortium_manager", "example_site"] multi_line_output = 3 default_section = "THIRDPARTY" From 0cc7f6837bde61efdc9b12153ba42a1eb47fe42e Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 31 Oct 2023 14:26:31 -0700 Subject: [PATCH 08/14] Remove mypy settins from setup.cfg --- setup.cfg | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/setup.cfg b/setup.cfg index b1c9d56f..7269b491 100644 --- a/setup.cfg +++ b/setup.cfg @@ -63,22 +63,6 @@ exclude = .tox,.git,*/migrations/*,*/static/CACHE/*,docs,node_modules,venv # force_grid_wrap = 0 # use_parentheses = true -[mypy] -python_version = 3.9 -check_untyped_defs = True -ignore_missing_imports = True -warn_unused_ignores = True -warn_redundant_casts = True -warn_unused_configs = True -plugins = mypy_django_plugin.main - -[mypy.plugins.django-stubs] -django_settings_module = anvil_consortium_manager.tests.settings.test - -[mypy-*.migrations.*] -# Django migrations should not produce any errors: -ignore_errors = True - [coverage:run] include = anvil_consortium_manager/* omit = *migrations*, *tests* From f2296353db50ebf055aa7c026de575c1693d8af9 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 31 Oct 2023 14:30:03 -0700 Subject: [PATCH 09/14] Move coverage configuration to pyproject.toml --- pyproject.toml | 6 ++++++ setup.cfg | 10 +++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 28af285a..ee615f6e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -57,3 +57,9 @@ skip_glob = ["**/migrations/*.py"] include_trailing_comma = true force_grid_wrap = 0 use_parentheses = true + + +[tool.coverage.run] +include = ["anvil_consortium_manager/*"] +omit = ["*migrations*", "*tests*"] +plugins = ["django_coverage_plugin"] diff --git a/setup.cfg b/setup.cfg index 7269b491..7aa85273 100644 --- a/setup.cfg +++ b/setup.cfg @@ -63,8 +63,8 @@ exclude = .tox,.git,*/migrations/*,*/static/CACHE/*,docs,node_modules,venv # force_grid_wrap = 0 # use_parentheses = true -[coverage:run] -include = anvil_consortium_manager/* -omit = *migrations*, *tests* -plugins = - django_coverage_plugin +# [coverage:run] +# include = anvil_consortium_manager/* +# omit = *migrations*, *tests* +# plugins = +# django_coverage_plugin From 9c6f63a7c7f589303c994b1a839b7de2c8aade36 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 31 Oct 2023 14:42:31 -0700 Subject: [PATCH 10/14] Clean up config files Rearrange pyproject.toml and add additional spacing lines. Remove commented out lines in setup.cfg that had been migrated to the pyproject.toml file. --- pyproject.toml | 13 +++++++---- setup.cfg | 63 -------------------------------------------------- 2 files changed, 9 insertions(+), 67 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index ee615f6e..a99a30c5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,3 @@ -[build-system] -requires = ['setuptools>=40.8.0', 'wheel'] -build-backend = "setuptools.build_meta" - [project] name = "django-anvil-consortium-manager" # Version needs to be updated such that the canonical version is only stored in one place. @@ -36,16 +32,25 @@ dependencies = [ "numpy >= 1.24", ] + +[build-system] +requires = ['setuptools>=40.8.0', 'wheel'] +build-backend = "setuptools.build_meta" + + [project.urls] "Homepage" = "https://github.com/UW-GAC/django-anvil-consortium-manager" "Bug Tracker" = "https://github.com/UW-GAC/django-anvil-consortium-manager/issues" + [tool.setuptools.packages.find] include = ["anvil_consortium_manager*"] + [tool.black] line-length = 119 + [tool.isort] profile = "black" line_length = 119 diff --git a/setup.cfg b/setup.cfg index 7aa85273..07b66553 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,49 +1,3 @@ -# [metadata] -# name = django-anvil-consortium-manager -# version = attr: anvil_consortium_manager.__version__ -# description = A Django app to manage Consortium AnVIL groups, workspaces, and access. -# long_description = file: README.md -# url = https://github.com/UW-GAC/django-anvil-consortium-manager -# author = Adrienne Stilp -# author_email = amstilp@uw.edu -# license = MIT -# classifiers = -# Environment :: Web Environment -# Framework :: Django -# Framework :: Django :: 3.2 -# Intended Audience :: Developers -# License :: OSI Approved :: MIT License -# Operating System :: OS Independent -# Programming Language :: Python -# Programming Language :: Python :: 3 -# Programming Language :: Python :: 3 :: Only -# Programming Language :: Python :: 3.8 -# Programming Language :: Python :: 3.9 -# Programming Language :: Python :: 3.10 -# Topic :: Internet :: WWW/HTTP -# Topic :: Internet :: WWW/HTTP :: Dynamic Content - -[options] -# include_package_data = true -# packages = find: -# python_requires = >=3.8 -# install_requires = -# Django >= 3.2 -# pytz >= 0 -# crispy-bootstrap5 >= 0.6 -# django-crispy-forms >= 1.12 -# google-auth >= 2.6 -# fontawesomefree >= 6.1 -# django-autocomplete-light >= 3.9 -# django-filter >= 23.0 -# django-tables2 >= 2.4 -# django-simple-history >= 3.1.1 -# django-extensions >= 3.1.5 -# plotly >= 5.11.0 -# networkx >= 2.8.2 -# numpy >= 1.24 - - [flake8] max-line-length = 120 exclude = .tox,.git,*/migrations/*,*/static/CACHE/*,docs,node_modules,venv @@ -51,20 +5,3 @@ exclude = .tox,.git,*/migrations/*,*/static/CACHE/*,docs,node_modules,venv [pycodestyle] max-line-length = 120 exclude = .tox,.git,*/migrations/*,*/static/CACHE/*,docs,node_modules,venv - -# [isort] -# line_length = 88 -# known_first_party = anvil_consortium_manager,example_site -# multi_line_output = 3 -# default_section = THIRDPARTY -# skip = venv/ -# skip_glob = **/migrations/*.py -# include_trailing_comma = true -# force_grid_wrap = 0 -# use_parentheses = true - -# [coverage:run] -# include = anvil_consortium_manager/* -# omit = *migrations*, *tests* -# plugins = -# django_coverage_plugin From 28616ca7757f79b20b4c5546911f56420d0438cd Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 31 Oct 2023 14:46:55 -0700 Subject: [PATCH 11/14] Move pytest options to pyproject.toml --- pyproject.toml | 7 +++++++ pytest.ini | 4 ---- 2 files changed, 7 insertions(+), 4 deletions(-) delete mode 100644 pytest.ini diff --git a/pyproject.toml b/pyproject.toml index a99a30c5..c24f81e9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -68,3 +68,10 @@ use_parentheses = true include = ["anvil_consortium_manager/*"] omit = ["*migrations*", "*tests*"] plugins = ["django_coverage_plugin"] + + +[tool.pytest.ini_options] +minversion = "6.0" +addopts = "--ds=anvil_consortium_manager.tests.settings.test --reuse-db --ignore=anvil_consortium_manager/tests/test_app/" +python_files = ["anvil_consortium_manager/tests/test*.py"] +python_classes = ["!TestWorkspaceDataFactory"] diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index 0614495c..00000000 --- a/pytest.ini +++ /dev/null @@ -1,4 +0,0 @@ -[pytest] -addopts = --ds=anvil_consortium_manager.tests.settings.test --reuse-db --ignore=anvil_consortium_manager/tests/test_app/ -python_files = anvil_consortium_manager/tests/test*.py -python_classes = !TestWorkspaceDataFactory From 51ba924e38611c4c75a007f7db8c03e557a87d00 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 31 Oct 2023 14:54:01 -0700 Subject: [PATCH 12/14] Add comment explaining why we still have the tox.ini file --- tox.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tox.ini b/tox.ini index f4fe49de..3a2bd708 100644 --- a/tox.ini +++ b/tox.ini @@ -1,4 +1,6 @@ # content of: tox.ini , put in same dir as setup.py +# Tox does not yet natively support pyproject.toml, so keep the separate tox.ini file for now. +# See Github issue: https://github.com/tox-dev/tox/issues/999 [tox] envlist = py{38,39,310,311}-django{32,41,42}-{sqlite,mysql} isolated_build = true From b25879fc4e892572bb5ab6b33cd5d6baa90f1c8c Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 31 Oct 2023 15:30:21 -0700 Subject: [PATCH 13/14] Use dynamic versioning --- pyproject.toml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c24f81e9..b05c55a0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "django-anvil-consortium-manager" # Version needs to be updated such that the canonical version is only stored in one place. -version = "0.19" +# version = "0.19" authors = [ {name="Adrienne Stilp", email="amstilp@uw.edu"}, ] @@ -31,6 +31,7 @@ dependencies = [ "networkx >= 2.8.2", "numpy >= 1.24", ] +dynamic = ["version"] [build-system] @@ -43,6 +44,9 @@ build-backend = "setuptools.build_meta" "Bug Tracker" = "https://github.com/UW-GAC/django-anvil-consortium-manager/issues" +[tool.setuptools.dynamic] +version = {attr = "anvil_consortium_manager.__version__"} + [tool.setuptools.packages.find] include = ["anvil_consortium_manager*"] From ba7cb21c2986ee5740b4ba0543f78b7fee182b67 Mon Sep 17 00:00:00 2001 From: Adrienne Stilp Date: Tue, 31 Oct 2023 15:52:56 -0700 Subject: [PATCH 14/14] Bump version number and update changelog --- CHANGELOG.md | 4 ++++ anvil_consortium_manager/__init__.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c26bdac..92f554a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change log +## Devel + +* Switch to using `pyproject.toml` where possible. + ## 0.19 (2023-10-27) * Add filtering in list views. diff --git a/anvil_consortium_manager/__init__.py b/anvil_consortium_manager/__init__.py index 5fb6b765..887278f1 100644 --- a/anvil_consortium_manager/__init__.py +++ b/anvil_consortium_manager/__init__.py @@ -1 +1 @@ -__version__ = "0.19" +__version__ = "0.20dev1"