From 65591f7bb340f9d60d1744fdbb606ae2d24437fe Mon Sep 17 00:00:00 2001 From: Hadley King Date: Thu, 27 Jul 2023 17:33:13 -0400 Subject: [PATCH 01/20] Testing setup (#200) * unit tests test_fixtures.py - Exports the database as a pytest fixture that can be used for testing * Add files via upload * New api test files * Fixed test_api_accounts_describe Changes to be committed: modified: api/apps.py modified: api/model/groups.py modified: api/model/prefix.py deleted: api/tests/test_bcos.json deleted: api/tests/test_forms.py deleted: api/tests/test_group_post_api.py deleted: api/tests/test_model_bco.py deleted: api/tests/test_model_groups.py deleted: api/tests/test_model_prefix.py deleted: api/tests/test_model_user.py deleted: api/tests/test_prefix_post_api.py deleted: api/tests/test_views.py deleted: api/tests_automated.py modified: api/views.py modified: bcodb/settings.py renamed: api/tests/__init__.py -> tests/__init__.py new file: tests/fixtures/test_data.json modified: tests/test_fixtures.py new file: tests/test_views/__init__.py modified: tests/test_views/test_api_accounts_describe.py * Fix Bulk Publish function Changes to be committed: modified: api/scripts/method_specific/POST_api_objects_publish.py modified: api/scripts/utilities/JsonUtils.py * Add reset_token API Issue #158 * Formatting for Add/Remove ORCID updated dev DB Related to https://github.com/biocompute-objects/portal_userdb/issues/90 Changes to be committed: modified: admin_only/db.sqlite3.dev modified: authentication/apis.py * Fix #134 Changes to be committed: modified: authentication/services.py * Bump django from 3.2.10 to 3.2.13 Bumps [django](https://github.com/django/django) from 3.2.10 to 3.2.13. - [Release notes](https://github.com/django/django/releases) - [Commits](https://github.com/django/django/compare/3.2.10...3.2.13) --- updated-dependencies: - dependency-name: django dependency-type: direct:production ... Signed-off-by: dependabot[bot] * new test - auth/remove * conflicts solved and merged * new bracnh for conflict resolution Changes to be committed: modified: .github/workflows/django.yml modified: tests/test_views/test_api_objects_drafts_create.py * update (#198) * Fix Bulk Publish function Changes to be committed: modified: api/scripts/method_specific/POST_api_objects_publish.py modified: api/scripts/utilities/JsonUtils.py * Add reset_token API Issue #158 * Formatting for Add/Remove ORCID updated dev DB Related to https://github.com/biocompute-objects/portal_userdb/issues/90 Changes to be committed: modified: admin_only/db.sqlite3.dev modified: authentication/apis.py * Fix #134 Changes to be committed: modified: authentication/services.py * Bump django from 3.2.10 to 3.2.13 Bumps [django](https://github.com/django/django) from 3.2.10 to 3.2.13. - [Release notes](https://github.com/django/django/releases) - [Commits](https://github.com/django/django/compare/3.2.10...3.2.13) --- updated-dependencies: - dependency-name: django dependency-type: direct:production ... Signed-off-by: dependabot[bot] * added new test file- api/auth/remove.py (#196) * unit tests test_fixtures.py - Exports the database as a pytest fixture that can be used for testing * Add files via upload * New api test files * Fixed test_api_accounts_describe Changes to be committed: modified: api/apps.py modified: api/model/groups.py modified: api/model/prefix.py deleted: api/tests/test_bcos.json deleted: api/tests/test_forms.py deleted: api/tests/test_group_post_api.py deleted: api/tests/test_model_bco.py deleted: api/tests/test_model_groups.py deleted: api/tests/test_model_prefix.py deleted: api/tests/test_model_user.py deleted: api/tests/test_prefix_post_api.py deleted: api/tests/test_views.py deleted: api/tests_automated.py modified: api/views.py modified: bcodb/settings.py renamed: api/tests/__init__.py -> tests/__init__.py new file: tests/fixtures/test_data.json modified: tests/test_fixtures.py new file: tests/test_views/__init__.py modified: tests/test_views/test_api_accounts_describe.py * Fix Bulk Publish function Changes to be committed: modified: api/scripts/method_specific/POST_api_objects_publish.py modified: api/scripts/utilities/JsonUtils.py * Add reset_token API Issue #158 * Formatting for Add/Remove ORCID updated dev DB Related to https://github.com/biocompute-objects/portal_userdb/issues/90 Changes to be committed: modified: admin_only/db.sqlite3.dev modified: authentication/apis.py * Fix #134 Changes to be committed: modified: authentication/services.py * Bump django from 3.2.10 to 3.2.13 Bumps [django](https://github.com/django/django) from 3.2.10 to 3.2.13. - [Release notes](https://github.com/django/django/releases) - [Commits](https://github.com/django/django/compare/3.2.10...3.2.13) --- updated-dependencies: - dependency-name: django dependency-type: direct:production ... Signed-off-by: dependabot[bot] * new test - auth/remove * conflicts solved and merged --------- Signed-off-by: dependabot[bot] Co-authored-by: Hadley King Co-authored-by: hadleyking Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Reeya Gupta <56750374+Reeya123@users.noreply.github.com> --------- Signed-off-by: dependabot[bot] Co-authored-by: Reeya Gupta Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Reeya Gupta <56750374+Reeya123@users.noreply.github.com> --- .github/workflows/django.yml | 2 +- .../test_api_objects_drafts_create.py | 53 ++++++++++++------- 2 files changed, 35 insertions(+), 20 deletions(-) diff --git a/.github/workflows/django.yml b/.github/workflows/django.yml index 8e4c83e9..14787cc7 100644 --- a/.github/workflows/django.yml +++ b/.github/workflows/django.yml @@ -26,4 +26,4 @@ jobs: pip install -r requirements.txt - name: Run Tests run: | - cd bco_api;python3.9 manage.py test + python3.9 manage.py test diff --git a/tests/test_views/test_api_objects_drafts_create.py b/tests/test_views/test_api_objects_drafts_create.py index 249f1f87..a9537fd7 100644 --- a/tests/test_views/test_api_objects_drafts_create.py +++ b/tests/test_views/test_api_objects_drafts_create.py @@ -1,31 +1,46 @@ -from django.test import TestCase, Client -from django.contrib.auth.models import User + + import json +from django.test import TestCase +from django.contrib.auth.models import User +from rest_framework.authtoken.models import Token +from rest_framework.test import APIClient class BcoDraftCreateTestCase(TestCase): - def setUp(self): - self.client = Client() - self.url = '/api/objects/drafts/create' # The URL for the create draft endpoint - self.user = User.objects.create_user(username='bco_api_user', password='biocompute') + fixtures = ['tests/fixtures/test_data'] + + # def setUp(self): + # self.client = Client() + # self.url = '/api/objects/drafts/create' # The URL for the create draft endpoint + # self.user = User.objects.create_user(username='bco_api_user', password='biocompute') def test_successful_creation(self): - # force logging - self.client.force_login(self.user) + """200: Creation of BCO draft is successful. + """ + + client = APIClient() + token = Token.objects.get(user=User.objects.get(username='bco_api_user')).key + client.credentials(HTTP_AUTHORIZATION='Token ' + token) - # Test case for successful creation (response code 200) data = { - 'prefix': 'string', - 'owner_group': 'string', - 'object_id': 'string', - 'schema': 'string', - 'contents': { - "additionalProp1": {} - } + 'POST_api_objects_draft_create': [ + { + 'prefix': 'BCO', + 'owner_group': 'bco_drafter', + 'schema': 'IEEE', + 'contents': {} + }, + { + 'prefix': 'Hadley', + 'owner_group': 'bco_drafter', + 'schema': 'IEEE', + 'contents': {} + } + ] } - response = self.client.post(self.url, data=json.dumps(data), content_type='application/json', follow=True) + response = client.post('/api/objects/drafts/create/',data, format='json') + import pdb; pdb.set_trace() self.assertEqual(response.status_code, 200) - # Checking the response. I believe it's JSON) - response_data = json.loads(response.content) def test_partial_failure(self): # Test case for partial failure (response code 300) From f2743d25e550aebf98e99b2bcf37259b40c89a2f Mon Sep 17 00:00:00 2001 From: Hadley King Date: Thu, 27 Jul 2023 17:52:40 -0400 Subject: [PATCH 02/20] Get published object by (#201) * unit tests test_fixtures.py - Exports the database as a pytest fixture that can be used for testing * Add files via upload * New api test files * Fixed test_api_accounts_describe Changes to be committed: modified: api/apps.py modified: api/model/groups.py modified: api/model/prefix.py deleted: api/tests/test_bcos.json deleted: api/tests/test_forms.py deleted: api/tests/test_group_post_api.py deleted: api/tests/test_model_bco.py deleted: api/tests/test_model_groups.py deleted: api/tests/test_model_prefix.py deleted: api/tests/test_model_user.py deleted: api/tests/test_prefix_post_api.py deleted: api/tests/test_views.py deleted: api/tests_automated.py modified: api/views.py modified: bcodb/settings.py renamed: api/tests/__init__.py -> tests/__init__.py new file: tests/fixtures/test_data.json modified: tests/test_fixtures.py new file: tests/test_views/__init__.py modified: tests/test_views/test_api_accounts_describe.py * Fix Bulk Publish function Changes to be committed: modified: api/scripts/method_specific/POST_api_objects_publish.py modified: api/scripts/utilities/JsonUtils.py * Add reset_token API Issue #158 * Formatting for Add/Remove ORCID updated dev DB Related to https://github.com/biocompute-objects/portal_userdb/issues/90 Changes to be committed: modified: admin_only/db.sqlite3.dev modified: authentication/apis.py * Fix #134 Changes to be committed: modified: authentication/services.py * Bump django from 3.2.10 to 3.2.13 Bumps [django](https://github.com/django/django) from 3.2.10 to 3.2.13. - [Release notes](https://github.com/django/django/releases) - [Commits](https://github.com/django/django/compare/3.2.10...3.2.13) --- updated-dependencies: - dependency-name: django dependency-type: direct:production ... Signed-off-by: dependabot[bot] * new test - auth/remove * conflicts solved and merged * new bracnh for conflict resolution Changes to be committed: modified: .github/workflows/django.yml modified: tests/test_views/test_api_objects_drafts_create.py * update (#198) * Fix Bulk Publish function Changes to be committed: modified: api/scripts/method_specific/POST_api_objects_publish.py modified: api/scripts/utilities/JsonUtils.py * Add reset_token API Issue #158 * Formatting for Add/Remove ORCID updated dev DB Related to https://github.com/biocompute-objects/portal_userdb/issues/90 Changes to be committed: modified: admin_only/db.sqlite3.dev modified: authentication/apis.py * Fix #134 Changes to be committed: modified: authentication/services.py * Bump django from 3.2.10 to 3.2.13 Bumps [django](https://github.com/django/django) from 3.2.10 to 3.2.13. - [Release notes](https://github.com/django/django/releases) - [Commits](https://github.com/django/django/compare/3.2.10...3.2.13) --- updated-dependencies: - dependency-name: django dependency-type: direct:production ... Signed-off-by: dependabot[bot] * added new test file- api/auth/remove.py (#196) * unit tests test_fixtures.py - Exports the database as a pytest fixture that can be used for testing * Add files via upload * New api test files * Fixed test_api_accounts_describe Changes to be committed: modified: api/apps.py modified: api/model/groups.py modified: api/model/prefix.py deleted: api/tests/test_bcos.json deleted: api/tests/test_forms.py deleted: api/tests/test_group_post_api.py deleted: api/tests/test_model_bco.py deleted: api/tests/test_model_groups.py deleted: api/tests/test_model_prefix.py deleted: api/tests/test_model_user.py deleted: api/tests/test_prefix_post_api.py deleted: api/tests/test_views.py deleted: api/tests_automated.py modified: api/views.py modified: bcodb/settings.py renamed: api/tests/__init__.py -> tests/__init__.py new file: tests/fixtures/test_data.json modified: tests/test_fixtures.py new file: tests/test_views/__init__.py modified: tests/test_views/test_api_accounts_describe.py * Fix Bulk Publish function Changes to be committed: modified: api/scripts/method_specific/POST_api_objects_publish.py modified: api/scripts/utilities/JsonUtils.py * Add reset_token API Issue #158 * Formatting for Add/Remove ORCID updated dev DB Related to https://github.com/biocompute-objects/portal_userdb/issues/90 Changes to be committed: modified: admin_only/db.sqlite3.dev modified: authentication/apis.py * Fix #134 Changes to be committed: modified: authentication/services.py * Bump django from 3.2.10 to 3.2.13 Bumps [django](https://github.com/django/django) from 3.2.10 to 3.2.13. - [Release notes](https://github.com/django/django/releases) - [Commits](https://github.com/django/django/compare/3.2.10...3.2.13) --- updated-dependencies: - dependency-name: django dependency-type: direct:production ... Signed-off-by: dependabot[bot] * new test - auth/remove * conflicts solved and merged --------- Signed-off-by: dependabot[bot] Co-authored-by: Hadley King Co-authored-by: hadleyking Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Reeya Gupta <56750374+Reeya123@users.noreply.github.com> * Fix Swagger for `GET_published_object_by_id` * tests and documentation for 'get_object_id' Fix #178 --------- Signed-off-by: dependabot[bot] Co-authored-by: Reeya Gupta Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Reeya Gupta <56750374+Reeya123@users.noreply.github.com> --- .../GET_published_object_by_id.py | 4 +-- api/views.py | 18 +++---------- .../test_views/test_published_object_by_id.py | 26 +++++++++++++++++++ 3 files changed, 31 insertions(+), 17 deletions(-) create mode 100644 tests/test_views/test_published_object_by_id.py diff --git a/api/scripts/method_specific/GET_published_object_by_id.py b/api/scripts/method_specific/GET_published_object_by_id.py index 58d15908..986cf98c 100755 --- a/api/scripts/method_specific/GET_published_object_by_id.py +++ b/api/scripts/method_specific/GET_published_object_by_id.py @@ -1,5 +1,5 @@ # The BCO model -from ...models import BCO +from api.models import BCO # Responses from rest_framework import status @@ -107,5 +107,5 @@ def GET_published_object_by_id(oi_root): print("No objects were found for the root ID provided.") return Response( data="No objects were found for the root ID provided.", - status=status.HTTP_400_BAD_REQUEST, + status=status.HTTP_404_NOT_FOUND, ) diff --git a/api/views.py b/api/views.py index 8a4ecad6..7dc90d4a 100755 --- a/api/views.py +++ b/api/views.py @@ -1669,19 +1669,10 @@ def get(self, request, object_id): class ObjectIdRootObjectId(APIView): """ View Published BCO by ID - -------------------- - - Reads and returns a published BCO based on an object ID. - + Reads and returns a published BCO based on an object ID. This will return the highest versioned object. """ - # For the success and error messages - # renderer_classes = [ - # TemplateHTMLRenderer - # ] - # template_name = 'api/account_activation_message.html' - auth = [] auth.append( openapi.Parameter( @@ -1692,17 +1683,14 @@ class ObjectIdRootObjectId(APIView): ) ) - # Anyone can view a published object authentication_classes = [] permission_classes = [] @swagger_auto_schema( manual_parameters=auth, responses={ - 201: "Account has been authorized.", - 208: "Account has already been authorized.", - 403: "Requestor's credentials were rejected.", - 424: "Account has not been registered.", + 200: "Object returned.", + 404: "Object not found." }, tags=["BCO Management"], ) diff --git a/tests/test_views/test_published_object_by_id.py b/tests/test_views/test_published_object_by_id.py new file mode 100644 index 00000000..d5a599cc --- /dev/null +++ b/tests/test_views/test_published_object_by_id.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 + +"""Root Object Id Testing +Tests for 'Object Found' (200) and 'Object Not Found'(404) +""" + +from django.test import TestCase +from rest_framework.test import APIClient + +class ObjectIdRootObjectIdTest(TestCase): + fixtures = ['tests/fixtures/test_data'] + + def test_seccussfull_retrieval(self): + """200: Object returned. + """ + + client = APIClient() + response = self.client.get('/BCO_000001') + self.assertEqual(response.status_code, 200) + + def test_object_not_found(self): + """404: Object not found. + """ + + response = self.client.get('/BCO_001000') + self.assertEqual(response.status_code, 404) \ No newline at end of file From 82dfcc276f4deb7ced0725188ae699221b42fa39 Mon Sep 17 00:00:00 2001 From: hadleyking Date: Fri, 28 Jul 2023 09:46:46 -0400 Subject: [PATCH 03/20] Closes Develop tests and document Fix #169 Changes to be committed: modified: authentication/apis.py modified: authentication/services.py modified: tests/fixtures/test_data.json modified: tests/test_views/test_api_auth_add.py --- authentication/apis.py | 10 +-- authentication/services.py | 10 ++- tests/fixtures/test_data.json | 13 ++++ tests/test_views/test_api_auth_add.py | 94 ++++++++++++--------------- 4 files changed, 67 insertions(+), 60 deletions(-) diff --git a/authentication/apis.py b/authentication/apis.py index b47c2cf2..8b98eb26 100644 --- a/authentication/apis.py +++ b/authentication/apis.py @@ -123,9 +123,10 @@ class AddAuthenticationApi(APIView): @swagger_auto_schema( request_body=schema, responses={ - 200: "Add authentication is successful.", - 201: "Authentication credentials were created and added.", + 200: "New authentication credentials added to existing object.", + 201: "Authentication object created and added to account.", 400: "Bad request.", + 403: "Authentication credentials were not provided.", 409: "That object already exists for this account.", }, tags=["Authentication"], @@ -140,7 +141,6 @@ def post(self, request): return Response(status=status.HTTP_400_BAD_REQUEST, data=result) try: auth_object = Authentication.objects.get(username=request.user.username) - if request.data in auth_object.auth_service: return Response( status=status.HTTP_409_CONFLICT, @@ -150,7 +150,7 @@ def post(self, request): auth_object.save() return Response( status=status.HTTP_200_OK, - data={"message": "Authentication added to existing object"} + data={"message": "New authentication credentials added to existing object"} ) except Authentication.DoesNotExist: @@ -161,7 +161,7 @@ def post(self, request): print('status=status.HTTP_201_CREATED') return Response( status=status.HTTP_201_CREATED, - data={"message": "Authentication object added to account"} + data={"message": "Authentication object created and added to account"} ) except Exception as err: diff --git a/authentication/services.py b/authentication/services.py index 992a73c2..2a27c67a 100644 --- a/authentication/services.py +++ b/authentication/services.py @@ -72,8 +72,14 @@ def validate_auth_service(value): "required": ["iss", "sub"], "additionalProperties": False, "properties": { - "iss": {"type": "string", "description": "The 'iss' (issuer) claim identifies the principal that issued the JWT."}, - "sub": {"type": "string", "description": "The 'sub' (subject) claim identifies the principal that is the subject of the JWT."} + "iss": { + "type": "string", + "description": "The 'iss' (issuer) claim identifies the principal that issued the JWT." + }, + "sub": { + "type": "string", + "description": "The 'sub' (subject) claim identifies the principal that is the subject of the JWT." + } } } try: diff --git a/tests/fixtures/test_data.json b/tests/fixtures/test_data.json index 2a0bcbeb..0f5dc0a0 100644 --- a/tests/fixtures/test_data.json +++ b/tests/fixtures/test_data.json @@ -207,6 +207,19 @@ "change_message": "[]" } }, + { + "model": "authentication.authentication", + "pk": 1, + "fields": { + "username": "bco_api_user", + "auth_service": [ + { + "iss": "Reeya1", + "sub": "ReeyaGupta1" + } + ] + } + }, { "model": "auth.permission", "pk": 1, diff --git a/tests/test_views/test_api_auth_add.py b/tests/test_views/test_api_auth_add.py index 99733eae..9a701cb7 100644 --- a/tests/test_views/test_api_auth_add.py +++ b/tests/test_views/test_api_auth_add.py @@ -1,72 +1,60 @@ -##test for api/auth/add -##07801a1a4cdbf1945e22ac8439f1db27fe813f7a +#!/usr/bin/env python3 + +"""Add Authentication +Tests for 'New authentication credentials added to existing object' (200), +'Authentication credentials were created and added' (201), 'Bad request' (400), +'That object already exists for this account' (409) +""" + from django.test import TestCase, Client from rest_framework.test import APIClient from rest_framework.authtoken.models import Token from django.contrib.auth.models import User +from authentication.models import Authentication class AuthenticationTestCase(TestCase): + fixtures = ['tests/fixtures/test_data'] + def setUp(self): self.client = APIClient() + def test_credentials_created_response(self): + """Add authentication is successful (200) + """ - # Creating a user for authentication - self.user = User.objects.create(username='testuser') - - # Checking if user already has token, if not then creating one - if not Token.objects.filter(user=self.user).exists(): - self.token = Token.objects.create(user=self.user) - else: - self.token = Token.objects.get(user=self.user) - def test_success_response(self): - # successfull request - data = { - "iss": "Reeya1", - "sub": "ReeyaGupta1" - } + token = Token.objects.get(user=User.objects.get(username='test50')).key + data = {"iss": "Reeya1","sub": "ReeyaGupta1"} - self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) + self.client.credentials(HTTP_AUTHORIZATION='Token ' + token) response = self.client.post('/api/auth/add/', data=data) - '''fails with "AssertionError: 201 != 200": - This test case is expecting a status code of 200 (OK) when making a successful request, - but it receives a status code of 201 (Created) instead. It seems like the endpoint I am - testing is returning a 201 status code instead of the expected 200. To fix this, I - updated the test case to expect a status code of 201. - ''' self.assertEqual(response.status_code, 201) - def test_credentials_created_response(self): - # Simulate a request where authentication credentials were created and added - data = { - "iss": "Reeya1", - "sub": "ReeyaGupta1" - } - self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) - response = self.client.post('/api/auth/add/', data=data) - self.assertEqual(response.status_code, 201) + def test_credentials_added(self): + """New authentication credentials added to existing object (200) + """ + + token = Token.objects.get(user=User.objects.get(username='bco_api_user')).key + data = {"iss": "new","sub": "new One"} + self.client.credentials(HTTP_AUTHORIZATION='Token ' + token) + response = self.client.post('/api/auth/add/', data=data, format='json') + self.assertEqual(response.status_code, 200) def test_bad_request_response(self): - # bad request - data = { - # Missing required fields - } - self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) - response = self.client.post('/api/auth/add/', data=data) + """Bad request (400) + """ + + token = Token.objects.get(user=User.objects.get(username='test50')).key + data = {"Missing required fields"} + self.client.credentials(HTTP_AUTHORIZATION='Token ' + token) + response = self.client.post('/api/auth/add/', data=data, format='json') self.assertEqual(response.status_code, 400) def test_object_already_exists_response(self): - # an object that already exists for this account - data = { - "iss": "Reeya", - "sub": "ReeyaGupta" - } - self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) - response = self.client.post('/api/auth/add/', data=data) - '''fails with "AssertionError: 201 != 409" - Similarly, this test case is expecting 409 (Conflict) when trying to - create an object that already exists, but it receives 201 (Created). - This endpoint is not handling the object's existence as expected. - I updated the test case to expect a status code of 201 when creating an object - that already exists. - ''' - self.assertEqual(response.status_code, 201) + """That object already exists for this account (409) + """ + + token = Token.objects.get(user=User.objects.get(username='bco_api_user')).key + data = {"iss": "Reeya1","sub": "ReeyaGupta1"} + self.client.credentials(HTTP_AUTHORIZATION='Token ' + token) + response = self.client.post('/api/auth/add/', data=data, format='json') + self.assertEqual(response.status_code, 409) From 2f0fdd0ec8296a7bc70af866f04cea8c72a50eca Mon Sep 17 00:00:00 2001 From: hadleyking Date: Fri, 28 Jul 2023 14:23:09 -0400 Subject: [PATCH 04/20] remove 1 line --- tests/test_views/test_api_objects_drafts_create.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_views/test_api_objects_drafts_create.py b/tests/test_views/test_api_objects_drafts_create.py index a9537fd7..e8631599 100644 --- a/tests/test_views/test_api_objects_drafts_create.py +++ b/tests/test_views/test_api_objects_drafts_create.py @@ -39,7 +39,6 @@ def test_successful_creation(self): ] } response = client.post('/api/objects/drafts/create/',data, format='json') - import pdb; pdb.set_trace() self.assertEqual(response.status_code, 200) def test_partial_failure(self): From c4eadba6478023eff3791376c0018496c4c79a98 Mon Sep 17 00:00:00 2001 From: hadleyking Date: Tue, 15 Aug 2023 09:04:59 -0400 Subject: [PATCH 05/20] update version --- server.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.conf b/server.conf index 454a7100..209f01d2 100644 --- a/server.conf +++ b/server.conf @@ -7,7 +7,7 @@ production=False # DB Version [VERSION] -version=22.11 +version=23.09 # NOTE: Valid values are True or False (note the capitalization). # Is this a publish-only server? From b4e523a05c82758fd6fb8c454615c454089dd24b Mon Sep 17 00:00:00 2001 From: Reeya Gupta Date: Thu, 3 Aug 2023 12:28:44 -0400 Subject: [PATCH 06/20] Create test_get_objectid.py --- tests/test_views/test_get_objectid.py | 42 +++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 tests/test_views/test_get_objectid.py diff --git a/tests/test_views/test_get_objectid.py b/tests/test_views/test_get_objectid.py new file mode 100644 index 00000000..0ec934e2 --- /dev/null +++ b/tests/test_views/test_get_objectid.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 + +"""Get ObjectID +Tests for 'Successful request with valid object id' (200), +'Request with a non-existent object ID' (404), 'unauthorized- Request without authentication credentials' (401), +'Forbidden- Request with valid object ID but unauthorized user' (403) +""" + + +from django.test import TestCase +from rest_framework.test import APIClient + +class BCOViewTestCase(TestCase): + fixtures = ['tests/fixtures/test_data'] + def setUp(self): + self.client = APIClient() + + def test_view_published_bco_success(self): + # Successful request with valid object ID + object_id = "TEST_000001" + response = self.client.get(f'/api/{object_id}/') + self.assertEqual(response.status_code, 200) + + def test_view_published_bco_not_found(self): + # Request with a non-existent object ID + object_id = "invalid_object_id" + response = self.client.get(f'/api/{object_id}/') + self.assertEqual(response.status_code, 404) + + def test_view_published_bco_unauthorized(self): + # Request without authentication credentials + response = self.client.get('/api/TEST_000001/') + self.assertEqual(response.status_code, 401) + + def test_view_published_bco_forbidden(self): + # Request with valid object ID but unauthorized user + # (ie-user without sufficient permissions to access the BCO) + object_id = "TEST_000001" + # Authenticate as a user without sufficient permissions ?? + # self.client.credentials(HTTP_AUTHORIZATION='Token your_invalid_token_here') + response = self.client.get(f'/api/{object_id}/') + self.assertEqual(response.status_code, 403) \ No newline at end of file From 66bc2a17c50821f698f67b02c9e0c6a175fda98d Mon Sep 17 00:00:00 2001 From: Reeya Gupta Date: Mon, 7 Aug 2023 09:48:05 -0400 Subject: [PATCH 07/20] new branch- objects_drafts_publish --- tests/fixtures/test_data.json | 87 +------------------ .../test_api_objects_drafts_publish.py | 70 +++++++++++++++ 2 files changed, 72 insertions(+), 85 deletions(-) create mode 100644 tests/test_views/test_api_objects_drafts_publish.py diff --git a/tests/fixtures/test_data.json b/tests/fixtures/test_data.json index 0f5dc0a0..2730380b 100644 --- a/tests/fixtures/test_data.json +++ b/tests/fixtures/test_data.json @@ -994,91 +994,8 @@ "codename": "view_authentication" } }, - { - "model": "auth.group", - "pk": 1, - "fields": { - "name": "bco_drafter", - "permissions": [ - 53, - 54, - 55, - 57, - 56 - ] - } - }, - { - "model": "auth.group", - "pk": 2, - "fields": { - "name": "bco_publisher", - "permissions": [ - 53, - 54, - 55, - 57, - 58, - 56 - ] - } - }, - { - "model": "auth.group", - "pk": 3, - "fields": { - "name": "anon", - "permissions": [ - - ] - } - }, - { - "model": "auth.group", - "pk": 4, - "fields": { - "name": "wheel", - "permissions": [ - - ] - } - }, - { - "model": "auth.group", - "pk": 5, - "fields": { - "name": "group_admins", - "permissions": [ - 9, - 10, - 11, - 12 - ] - } - }, - { - "model": "auth.group", - "pk": 6, - "fields": { - "name": "prefix_admins", - "permissions": [ - 49, - 50, - 51, - 52 - ] - } - }, - { - "model": "auth.group", - "pk": 7, - "fields": { - "name": "AnonymousUser", - "permissions": [ - - ] - } - }, + + { "model": "auth.group", "pk": 8, diff --git a/tests/test_views/test_api_objects_drafts_publish.py b/tests/test_views/test_api_objects_drafts_publish.py new file mode 100644 index 00000000..f9100166 --- /dev/null +++ b/tests/test_views/test_api_objects_drafts_publish.py @@ -0,0 +1,70 @@ +from django.test import TestCase +from rest_framework.test import APIClient +from rest_framework.authtoken.models import Token +from django.contrib.auth.models import User +from rest_framework.test import APITestCase + + +class PublishDraftBCOTestCase(TestCase): + fixtures = ['tests/fixtures/test_data'] + def setUp(self): + self.client = APIClient() + + def test_publish_bco_success(self): + # Successful request to publish a draft BCO + data = { + "POST_api_objects_drafts_publish": [ + { + "prefix": "string", + "draft_id": "string", + "object_id": "string", + "delete_draft": True + } + ] + } + #self.client.force_authenticate(user=self.user) + response = self.client.post('/api/objects/drafts/publish/', data=data, format='json') + self.assertEqual(response.status_code, 200) + + def test_publish_bco_partial_failure(self): + # Some requests failed while publishing the draft BCO + data = { + "POST_api_objects_drafts_publish": [ + { + "prefix": "string", + "draft_id": "string", + "object_id": "strin", + "delete_draft": True + }, + # Add more objects if needed to simulate partial failures + ] + } + + response = self.client.post('/api/objects/drafts/publish/', data=data, format='json') + self.assertEqual(response.status_code, 300) + + def test_publish_bco_bad_request(self): + # Bad request: Invalid or missing data + data = { + # Missing required fields or invalid data + } + #self.client.force_authenticate(user=self.user) + response = self.client.post('/api/objects/drafts/publish/', data=data, format='json') + self.assertEqual(response.status_code, 400) + + def test_publish_bco_invalid_token(self): + # Request with invalid token or without authentication credentials + data = { + "POST_api_objects_drafts_publish": [ + { + "prefix": "string", + "draft_id": "string", + "object_id": "string", + "delete_draft": True + } + ] + } + #using invalid token + self.client.credentials(HTTP_AUTHORIZATION='invalid token') + response = self.client.post('/api/objects/drafts/publish/', data=data, format='json') + self.assertEqual(response.status_code, 403) From 94fa30f4050ec182ba898c058d2ca85cdfb61b9e Mon Sep 17 00:00:00 2001 From: hadleyking Date: Mon, 7 Aug 2023 09:55:25 -0400 Subject: [PATCH 08/20] Fix test file --- tests/fixtures/test_data.json | 87 ++++++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 2 deletions(-) diff --git a/tests/fixtures/test_data.json b/tests/fixtures/test_data.json index 2730380b..0f5dc0a0 100644 --- a/tests/fixtures/test_data.json +++ b/tests/fixtures/test_data.json @@ -994,8 +994,91 @@ "codename": "view_authentication" } }, - - + { + "model": "auth.group", + "pk": 1, + "fields": { + "name": "bco_drafter", + "permissions": [ + 53, + 54, + 55, + 57, + 56 + ] + } + }, + { + "model": "auth.group", + "pk": 2, + "fields": { + "name": "bco_publisher", + "permissions": [ + 53, + 54, + 55, + 57, + 58, + 56 + ] + } + }, + { + "model": "auth.group", + "pk": 3, + "fields": { + "name": "anon", + "permissions": [ + + ] + } + }, + { + "model": "auth.group", + "pk": 4, + "fields": { + "name": "wheel", + "permissions": [ + + ] + } + }, + { + "model": "auth.group", + "pk": 5, + "fields": { + "name": "group_admins", + "permissions": [ + 9, + 10, + 11, + 12 + ] + } + }, + { + "model": "auth.group", + "pk": 6, + "fields": { + "name": "prefix_admins", + "permissions": [ + 49, + 50, + 51, + 52 + ] + } + }, + { + "model": "auth.group", + "pk": 7, + "fields": { + "name": "AnonymousUser", + "permissions": [ + + ] + } + }, { "model": "auth.group", "pk": 8, From 10b10fb167bf200b8346e0feef75a54c61eb9b0d Mon Sep 17 00:00:00 2001 From: Reeya Gupta Date: Mon, 14 Aug 2023 10:31:45 -0400 Subject: [PATCH 09/20] Objects_drafts_publish --- .../test_api_objects_drafts_publish.py | 78 ++++++++++++++----- tests/test_views/test_api_objects_search.py | 55 +++++++++++++ 2 files changed, 115 insertions(+), 18 deletions(-) create mode 100644 tests/test_views/test_api_objects_search.py diff --git a/tests/test_views/test_api_objects_drafts_publish.py b/tests/test_views/test_api_objects_drafts_publish.py index f9100166..20b648ec 100644 --- a/tests/test_views/test_api_objects_drafts_publish.py +++ b/tests/test_views/test_api_objects_drafts_publish.py @@ -1,3 +1,12 @@ +#!/usr/bin/env python3 + +'''Publish BCO Draft + expecting a response status code of 200,300, 400, but receiving a 207 status code (Multi-status rsponse), which might indicate that + suggesting that there are multiple operations being performed in the background as a result of the request. + + Tests for 403(Invalid token) + ''' + from django.test import TestCase from rest_framework.test import APIClient from rest_framework.authtoken.models import Token @@ -8,47 +17,79 @@ class PublishDraftBCOTestCase(TestCase): fixtures = ['tests/fixtures/test_data'] def setUp(self): + fixtures = ['tests/fixtures/test_data'] self.client = APIClient() + # Checking if the user 'bco_api_user' already exists + try: + self.user = User.objects.get(username='bco_api_user') + except User.DoesNotExist: + self.user = User.objects.create_user(username='bco_api_user') + + # Checking if user already has token, if not then creating one + if not Token.objects.filter(user=self.user).exists(): + self.token = Token.objects.create(user=self.user) + else: + self.token = Token.objects.get(user=self.user) def test_publish_bco_success(self): - # Successful request to publish a draft BCO + # Test for Successful request to publish a draft BCO + #Returns 207 instead of 200 + data = { "POST_api_objects_drafts_publish": [ { - "prefix": "string", - "draft_id": "string", - "object_id": "string", - "delete_draft": True + "prefix": "BCO", + "draft_id": "http://127.0.0.1:8000/BCO_000000/DRAFT", + + "delete_draft": False + } ] } - #self.client.force_authenticate(user=self.user) + self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) response = self.client.post('/api/objects/drafts/publish/', data=data, format='json') self.assertEqual(response.status_code, 200) def test_publish_bco_partial_failure(self): # Some requests failed while publishing the draft BCO + #Returns 207 instead of 300 + data = { "POST_api_objects_drafts_publish": [ { - "prefix": "string", - "draft_id": "string", - "object_id": "strin", - "delete_draft": True + "prefix": "BCO", + "draft_id": "http://127.0.0.1:8000/BCO_000001/DRAFT", + + "delete_draft": False }, - # Add more objects if needed to simulate partial failures + { + "prefix": "InvalidPrefix", + "draft_id": "InvalidDraftId", + + "delete_draft": False + } + ] } - + self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) response = self.client.post('/api/objects/drafts/publish/', data=data, format='json') self.assertEqual(response.status_code, 300) def test_publish_bco_bad_request(self): # Bad request: Invalid or missing data + #Returns 207 instead of 400 + data = { - # Missing required fields or invalid data + "POST_api_objects_drafts_publish": [ + { + "prefix": "BCO", + "draft_id": "InvalidID", + "delete_draft": False + }, + + ] } - #self.client.force_authenticate(user=self.user) + self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) response = self.client.post('/api/objects/drafts/publish/', data=data, format='json') self.assertEqual(response.status_code, 400) @@ -57,10 +98,11 @@ def test_publish_bco_invalid_token(self): data = { "POST_api_objects_drafts_publish": [ { - "prefix": "string", - "draft_id": "string", - "object_id": "string", - "delete_draft": True + "prefix": "BCO", + "draft_id": "http://127.0.0.1:8000/BCO_000000/DRAFT", + + "delete_draft": False + } ] } diff --git a/tests/test_views/test_api_objects_search.py b/tests/test_views/test_api_objects_search.py new file mode 100644 index 00000000..54130e48 --- /dev/null +++ b/tests/test_views/test_api_objects_search.py @@ -0,0 +1,55 @@ +from django.test import TestCase +from rest_framework.test import APIClient +from rest_framework.authtoken.models import Token +from django.contrib.auth.models import User +from rest_framework.test import APITestCase + +class ObjectsSearchTestCase(APITestCase): + def setUp(self): + fixtures = ['tests/fixtures/test_data'] + self.client = APIClient() + # Checking if the user 'bco_api_user' already exists + try: + self.user = User.objects.get(username='bco_api_user') + except User.DoesNotExist: + self.user = User.objects.create_user(username='bco_api_user') + + # Checking if user already has token, if not then creating one + if not Token.objects.filter(user=self.user).exists(): + self.token = Token.objects.create(user=self.user) + else: + self.token = Token.objects.get(user=self.user) + + def test_search_successful(self): + # Test case for a successful search (status code: 200) + ###Gives 404 instead of 200. + data = { + "POST_api_objects_search": [ + { + "type": "prefix", + "search": "TEST" + } + ] + } + self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) + response = self.client.post("/api/objects/search/", data=data, format="json") + + self.assertEqual(response.status_code, 200) + + + + def test_prefix_not_found(self): + # Test case for prefix not found (status code: 404) + data = { + "POST_api_objects_search": [ + { + "type": "prefix", + "search": "invalid prefix" + } + ] + } + self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) + + response = self.client.post("/api/objects/search/", data=data, format="json") + + self.assertEqual(response.status_code, 404) \ No newline at end of file From c3550a91cc94ef10c878939750fa558ae5e74ee0 Mon Sep 17 00:00:00 2001 From: hadleyking Date: Wed, 16 Aug 2023 09:32:49 -0400 Subject: [PATCH 10/20] UPdated Swagger Docs for `objects_draft_publish` Changes to be committed: modified: api/scripts/method_specific/POST_api_objects_drafts_publish.py modified: api/views.py --- .../POST_api_objects_drafts_publish.py | 24 +++++++++++--- api/views.py | 31 +++++++++++++++---- 2 files changed, 45 insertions(+), 10 deletions(-) diff --git a/api/scripts/method_specific/POST_api_objects_drafts_publish.py b/api/scripts/method_specific/POST_api_objects_drafts_publish.py index c30307df..388697eb 100755 --- a/api/scripts/method_specific/POST_api_objects_drafts_publish.py +++ b/api/scripts/method_specific/POST_api_objects_drafts_publish.py @@ -10,9 +10,9 @@ from django.contrib.auth.models import Group from django.utils import timezone from guardian.shortcuts import get_perms -from rest_framework import status +from rest_framework import status, authtoken from rest_framework.response import Response - +from authentication.selectors import get_user_from_auth_token def post_api_objects_drafts_publish(request): """Publish draft @@ -37,13 +37,29 @@ def post_api_objects_drafts_publish(request): returning = [] any_failed = False db_utils = DbUtils.DbUtils() - user = UserUtils.UserUtils().user_from_request(request=request) + + try: + user = UserUtils.UserUtils().user_from_request(request=request) + except authtoken.models.Token.DoesNotExist: + user = get_user_from_auth_token(request.META.get("HTTP_AUTHORIZATION").split(" ")[1]) prefix_perms = UserUtils.UserUtils().prefix_perms_for_user( flatten=True, user_object=user ) - bulk_request = request.data["POST_api_objects_drafts_publish"] + try: + bulk_request = request.data["POST_api_objects_drafts_publish"] + except: + return Response(status=status.HTTP_400_BAD_REQUEST, data={"Request format not accepted."}) for publish_object in bulk_request: + if "draft_id" not in publish_object: + returning.append( + db_utils.messages(parameters={})[ + "400_bad_request" + ] + ) + any_failed = True + continue + draft_exists = BCO.objects.filter( object_id=publish_object["draft_id"], state="DRAFT" ).exists() diff --git a/api/views.py b/api/views.py index 7dc90d4a..c59b4227 100755 --- a/api/views.py +++ b/api/views.py @@ -79,6 +79,7 @@ # For helper functions from api.scripts.utilities import UserUtils +from authentication.services import CustomJSONWebTokenAuthentication ################################################################################################ # NOTES @@ -800,22 +801,39 @@ def post(self, request) -> Response: # TODO: What is the difference between this and ApiObjectsPublish? class ApiObjectsDraftsPublish(APIView): """ - Publish a BCO + Bulk Publish BCOs -------------------- + + Publish draft BCO objects. Once published, a BCO object becomes immutable. + The `object_id` field is optional, and is used to specify if the object + should be published as a specific version, instead of the next available numeric + version. + - Publish a draft BCO object. Once published, a BCO object becomes immutable. + ```json + { + "POST_api_objects_drafts_publish": [ + { + "prefix": "TEST", + "draft_id": "http://127.0.0.1:8000/TEST_000001", + "object_id": "http://127.0.0.1:8000/TEST_000001/1.0", + "delete_draft": false + } + ] + } """ # TODO: This seems to be missing group, which I would expect to be part of the publication permission_classes = [IsAuthenticated] + authentication_classes = [CustomJSONWebTokenAuthentication] POST_api_objects_drafts_publish_schema = openapi.Schema( type=openapi.TYPE_OBJECT, required=["draft_id", "prefix"], properties={ "prefix": openapi.Schema( - type=openapi.TYPE_STRING, description="BCO Prefix to publish with." + type=openapi.TYPE_STRING, description="BCO Prefix to publish with." ), "draft_id": openapi.Schema( type=openapi.TYPE_STRING, description="BCO Object Draft ID." @@ -847,13 +865,14 @@ class ApiObjectsDraftsPublish(APIView): @swagger_auto_schema( request_body=request_body, responses={ - 200: "BCO Publication is successful.", - 300: "Some requests failed.", + 200: "All BCO publications successful.", + 207: "Some or all publications failed.", 400: "Bad request.", - 403: "Invalid token.", + 403: "Authentication credentials were not provided.", }, tags=["BCO Management"], ) + def post(self, request) -> Response: return check_post_and_process(request, post_api_objects_drafts_publish) From c647fa6e1f5a08280be2880d10730f95ce022be9 Mon Sep 17 00:00:00 2001 From: Reeya Gupta Date: Wed, 16 Aug 2023 13:04:17 -0400 Subject: [PATCH 11/20] Update test_api_objects_drafts_publish.py --- .../test_views/test_api_objects_drafts_publish.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/tests/test_views/test_api_objects_drafts_publish.py b/tests/test_views/test_api_objects_drafts_publish.py index 20b648ec..561da5cd 100644 --- a/tests/test_views/test_api_objects_drafts_publish.py +++ b/tests/test_views/test_api_objects_drafts_publish.py @@ -1,9 +1,7 @@ #!/usr/bin/env python3 '''Publish BCO Draft - expecting a response status code of 200,300, 400, but receiving a 207 status code (Multi-status rsponse), which might indicate that - suggesting that there are multiple operations being performed in the background as a result of the request. - + expecting a response status code of 200,300, 400, but receiving a 404 status code (Forbidden) Tests for 403(Invalid token) ''' @@ -17,7 +15,7 @@ class PublishDraftBCOTestCase(TestCase): fixtures = ['tests/fixtures/test_data'] def setUp(self): - fixtures = ['tests/fixtures/test_data'] + self.client = APIClient() # Checking if the user 'bco_api_user' already exists try: @@ -33,7 +31,7 @@ def setUp(self): def test_publish_bco_success(self): # Test for Successful request to publish a draft BCO - #Returns 207 instead of 200 + #Returns 403 instead of 200 data = { "POST_api_objects_drafts_publish": [ @@ -52,7 +50,7 @@ def test_publish_bco_success(self): def test_publish_bco_partial_failure(self): # Some requests failed while publishing the draft BCO - #Returns 207 instead of 300 + #Returns 403 instead of 300 data = { "POST_api_objects_drafts_publish": [ @@ -77,13 +75,13 @@ def test_publish_bco_partial_failure(self): def test_publish_bco_bad_request(self): # Bad request: Invalid or missing data - #Returns 207 instead of 400 + #Returns 403 instead of 400 data = { "POST_api_objects_drafts_publish": [ { "prefix": "BCO", - "draft_id": "InvalidID", + #"draft_id": "InvalidID", "delete_draft": False }, From 6b3dd4f72556832d4a47e43112cc07d94101f205 Mon Sep 17 00:00:00 2001 From: hadleyking Date: Fri, 18 Aug 2023 10:36:59 -0400 Subject: [PATCH 12/20] Fix #181 Changes to be committed: modified: api/scripts/method_specific/POST_api_objects_drafts_publish.py modified: api/views.py modified: tests/fixtures/test_data.json modified: tests/test_views/test_api_objects_drafts_publish.py --- .../POST_api_objects_drafts_publish.py | 5 -- api/views.py | 4 +- tests/fixtures/test_data.json | 4 +- .../test_api_objects_drafts_publish.py | 73 ++++++++++--------- 4 files changed, 41 insertions(+), 45 deletions(-) diff --git a/api/scripts/method_specific/POST_api_objects_drafts_publish.py b/api/scripts/method_specific/POST_api_objects_drafts_publish.py index 388697eb..e0ee71f4 100755 --- a/api/scripts/method_specific/POST_api_objects_drafts_publish.py +++ b/api/scripts/method_specific/POST_api_objects_drafts_publish.py @@ -211,11 +211,6 @@ def post_api_objects_drafts_publish(request): # # Does the requestor have delete permissions on # # the object? - # As this view is for a bulk operation, status 200 - # means that the request was successfully processed, - # but NOT necessarily each item in the request. - # For example, a table may not have been found for the first - # requested draft. if any_failed: return Response(status=status.HTTP_207_MULTI_STATUS, data=returning) diff --git a/api/views.py b/api/views.py index c59b4227..e011f303 100755 --- a/api/views.py +++ b/api/views.py @@ -825,8 +825,8 @@ class ApiObjectsDraftsPublish(APIView): """ # TODO: This seems to be missing group, which I would expect to be part of the publication - permission_classes = [IsAuthenticated] - authentication_classes = [CustomJSONWebTokenAuthentication] + permission_classes = [IsAuthenticated,] + # authentication_classes = [CustomJSONWebTokenAuthentication] POST_api_objects_drafts_publish_schema = openapi.Schema( type=openapi.TYPE_OBJECT, diff --git a/tests/fixtures/test_data.json b/tests/fixtures/test_data.json index 0f5dc0a0..62398b49 100644 --- a/tests/fixtures/test_data.json +++ b/tests/fixtures/test_data.json @@ -1627,7 +1627,7 @@ "etag": "0275321b6011324035289a5624c635ce5490fbdec588aa5f3bcaf63b85369b4a", "provenance_domain": { "name": "Influenza A reference gene sequences", - "version": "1.0", + "version": "1.1", "created": "2021-12-01T15:20:13.614Z", "modified": "2022-06-28T23:10:12.804Z", "review": [ @@ -1845,7 +1845,7 @@ "etag": "11ee4c3b8a04ad16dcca19a6f478c0870d3fe668ed6454096ab7165deb1ab8ea", "provenance_domain": { "name": "HCV1a ledipasvir resistance SNP detection", - "version": "1.0", + "version": "1.1", "created": "2017-01-24T09:40:17-0500", "modified": "2022-06-28T23:12:50.369Z", "review": [ diff --git a/tests/test_views/test_api_objects_drafts_publish.py b/tests/test_views/test_api_objects_drafts_publish.py index 561da5cd..874bfef5 100644 --- a/tests/test_views/test_api_objects_drafts_publish.py +++ b/tests/test_views/test_api_objects_drafts_publish.py @@ -1,98 +1,99 @@ #!/usr/bin/env python3 -'''Publish BCO Draft - expecting a response status code of 200,300, 400, but receiving a 404 status code (Forbidden) - Tests for 403(Invalid token) - ''' +"""Test Bulk Publish BCOs +Tests for 'All BCO publications successful.' (200), 'Some or all publications +failed.' (207), 'Bad request.' (400), and 'Authentication credentials were not +provided.' (404) +""" from django.test import TestCase from rest_framework.test import APIClient from rest_framework.authtoken.models import Token from django.contrib.auth.models import User -from rest_framework.test import APITestCase +from rest_framework.test import APITestCase, APIClient class PublishDraftBCOTestCase(TestCase): fixtures = ['tests/fixtures/test_data'] def setUp(self): - self.client = APIClient() - # Checking if the user 'bco_api_user' already exists - try: - self.user = User.objects.get(username='bco_api_user') - except User.DoesNotExist: - self.user = User.objects.create_user(username='bco_api_user') - - # Checking if user already has token, if not then creating one - if not Token.objects.filter(user=self.user).exists(): - self.token = Token.objects.create(user=self.user) - else: - self.token = Token.objects.get(user=self.user) def test_publish_bco_success(self): - # Test for Successful request to publish a draft BCO - #Returns 403 instead of 200 + """All BCO publications successful (200) + """ + + token = Token.objects.get(user=User.objects.get(username='test50')).key data = { "POST_api_objects_drafts_publish": [ { "prefix": "BCO", "draft_id": "http://127.0.0.1:8000/BCO_000000/DRAFT", - "delete_draft": False - + }, + { + "prefix": "BCO", + "draft_id": "http://127.0.0.1:8000/BCO_000001/DRAFT", + "object_id" "http://127.0.0.1:8000/BCO_000000/1.1" + "delete_draft": False } ] } - self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) + self.client.credentials(HTTP_AUTHORIZATION='Token ' + token) response = self.client.post('/api/objects/drafts/publish/', data=data, format='json') self.assertEqual(response.status_code, 200) def test_publish_bco_partial_failure(self): - # Some requests failed while publishing the draft BCO - #Returns 403 instead of 300 + """Some or all publications failed (207) + """ + + token = Token.objects.get(user=User.objects.get(username='test50')).key data = { "POST_api_objects_drafts_publish": [ { "prefix": "BCO", - "draft_id": "http://127.0.0.1:8000/BCO_000001/DRAFT", - + "draft_id": "http://127.0.0.1:8000/BCO_000001/DRAFT", "delete_draft": False }, { "prefix": "InvalidPrefix", "draft_id": "InvalidDraftId", - "delete_draft": False } ] } - self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) + self.client.credentials(HTTP_AUTHORIZATION='Token ' + token) response = self.client.post('/api/objects/drafts/publish/', data=data, format='json') - self.assertEqual(response.status_code, 300) + self.assertEqual(response.status_code, 207) def test_publish_bco_bad_request(self): - # Bad request: Invalid or missing data - #Returns 403 instead of 400 - + """Bad request (400) + """ + + token = Token.objects.get(user=User.objects.get(username='test50')).key + data = { - "POST_api_objects_drafts_publish": [ + "POST_wrong_thing": [ { "prefix": "BCO", #"draft_id": "InvalidID", "delete_draft": False - }, + } ] } - self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) + self.client.credentials(HTTP_AUTHORIZATION='Token ' + token) response = self.client.post('/api/objects/drafts/publish/', data=data, format='json') self.assertEqual(response.status_code, 400) def test_publish_bco_invalid_token(self): - # Request with invalid token or without authentication credentials + """Authentication credentials were not provided. (404) + """ + + token = Token.objects.get(user=User.objects.get(username='test50')).key + data = { "POST_api_objects_drafts_publish": [ { From 560098894ff90270b0c5e56545d81ff1adb7cf51 Mon Sep 17 00:00:00 2001 From: Reeya Gupta <56750374+Reeya123@users.noreply.github.com> Date: Fri, 18 Aug 2023 13:03:49 -0400 Subject: [PATCH 13/20] Objects_search (#224) * objects_search * Fix #175 Changes to be committed: modified: search/apis.py modified: tests/test_views/test_api_objects_drafts_publish.py modified: tests/test_views/test_api_objects_search.py --------- Co-authored-by: hadleyking --- search/apis.py | 17 ++++++++--------- .../test_api_objects_drafts_publish.py | 2 +- tests/test_views/test_api_objects_search.py | 19 ++++++++++++++----- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/search/apis.py b/search/apis.py index 718eae8c..7ccfbe5f 100644 --- a/search/apis.py +++ b/search/apis.py @@ -12,11 +12,16 @@ from itertools import chain class SearchObjectsAPI(APIView): - """Search the BCODB **BETA** + """ + Search the BCODB ------------------- + Endpoint for use of query string based search. """ + + #TODO: multiple values in the URL will only return the last one. + authentication_classes = [CustomJSONWebTokenAuthentication] permission_classes = [AllowAny,] @@ -46,18 +51,12 @@ class SearchObjectsAPI(APIView): ) ], responses={ - 201: "Account has been authorized.", - 208: "Account has already been authorized.", - 403: "Requestor's credentials were rejected.", - 424: "Account has not been registered.", + 200: "" }, - tags=["Account Management"], + tags=["BCO Management"], ) def get(self, request) -> Response: - """GET search - TODO: multiple values in the URL will only return the last one. - """ return_values = [ "contents", "last_update", diff --git a/tests/test_views/test_api_objects_drafts_publish.py b/tests/test_views/test_api_objects_drafts_publish.py index 874bfef5..e7087ac0 100644 --- a/tests/test_views/test_api_objects_drafts_publish.py +++ b/tests/test_views/test_api_objects_drafts_publish.py @@ -105,7 +105,7 @@ def test_publish_bco_invalid_token(self): } ] } - #using invalid token + self.client.credentials(HTTP_AUTHORIZATION='invalid token') response = self.client.post('/api/objects/drafts/publish/', data=data, format='json') self.assertEqual(response.status_code, 403) diff --git a/tests/test_views/test_api_objects_search.py b/tests/test_views/test_api_objects_search.py index 54130e48..f2e1e73b 100644 --- a/tests/test_views/test_api_objects_search.py +++ b/tests/test_views/test_api_objects_search.py @@ -1,3 +1,10 @@ +#!/usr/bin/env python3 + +"""Objects Search +Tests for successful search (status code: 200), +prefix not found (status code: 404) +""" + from django.test import TestCase from rest_framework.test import APIClient from rest_framework.authtoken.models import Token @@ -5,8 +12,10 @@ from rest_framework.test import APITestCase class ObjectsSearchTestCase(APITestCase): + + fixtures = ['tests/fixtures/test_data'] def setUp(self): - fixtures = ['tests/fixtures/test_data'] + self.client = APIClient() # Checking if the user 'bco_api_user' already exists try: @@ -22,7 +31,7 @@ def setUp(self): def test_search_successful(self): # Test case for a successful search (status code: 200) - ###Gives 404 instead of 200. + data = { "POST_api_objects_search": [ { @@ -40,16 +49,16 @@ def test_search_successful(self): def test_prefix_not_found(self): # Test case for prefix not found (status code: 404) + data = { "POST_api_objects_search": [ { "type": "prefix", - "search": "invalid prefix" + "search": "invalidprefix" } ] } - self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) + self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) response = self.client.post("/api/objects/search/", data=data, format="json") - self.assertEqual(response.status_code, 404) \ No newline at end of file From 7a51f0f86cf530405154fd938d53515c222d2b2d Mon Sep 17 00:00:00 2001 From: Reeya Gupta Date: Wed, 23 Aug 2023 10:41:54 -0400 Subject: [PATCH 14/20] branch- accounts_new --- tests/test_views/test_api_accounts_new.py | 94 +++++++++++++++++++++++ tests/test_views/test_api_verify.py | 55 +++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 tests/test_views/test_api_accounts_new.py create mode 100644 tests/test_views/test_api_verify.py diff --git a/tests/test_views/test_api_accounts_new.py b/tests/test_views/test_api_accounts_new.py new file mode 100644 index 00000000..865a8194 --- /dev/null +++ b/tests/test_views/test_api_accounts_new.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python3 + +'''Account Creation + Gives 409 instead of 200, 403 and 201 instead of 400. Requires debugging + + Successfully tests for 409(Account has already been authenticated or requested) and 500(internal server error) + ''' + +from django.test import TestCase +from rest_framework.test import APIClient +from rest_framework.authtoken.models import Token +from django.contrib.auth.models import User +from rest_framework.test import APITestCase + +class AccountCreationTestCase(TestCase): + fixtures = ['tests/fixtures/test_data'] + def setUp(self): + + self.client = APIClient() + # Checking if the user 'bco_api_user' already exists + try: + self.user = User.objects.get(username='bco_api_user') + except User.DoesNotExist: + self.user = User.objects.create_user(username='bco_api_user') + + # Checking if user already has token, if not then creating one + if not Token.objects.filter(user=self.user).exists(): + self.token = Token.objects.create(user=self.user) + else: + self.token = Token.objects.get(user=self.user) + + + def test_account_creation_success(self): + ##Gives 409 instead of 200 + #Same request body as 409 + + data = { + "hostname": "http://localhost:8000", + "email": "object.biocompute@gmail.com", + "token": self.token.key + } + self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) + response = self.client.post('/api/accounts/new/', data=data, format='json') + self.assertEqual(response.status_code, 200) + + def test_account_creation_bad_request(self): + # Provide invalid or missing data + ##Gives 201 instead of 400 + data = { + "hostname": "http://localhost:8000", + "email": "invalid@example.com", + #"token": self.token.key + } + #self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) + response = self.client.post('/api/accounts/new/', data=data, format='json') + self.assertEqual(response.status_code, 400) + + def test_account_creation_invalid_token(self): + #Provide invalid token + ##Gives 409 instead of 403 + + data = { + "hostname": "http://localhost:8000", + "email": "" + #"token": self.token.key + } + self.client.credentials(HTTP_AUTHORIZATION='Invalid token') + response = self.client.post('/api/accounts/new/', data=data, format='json') + self.assertEqual(response.status_code, 403) + + def test_account_creation_already_authenticated(self): + ##Tests for conflict - same request body as 200 + data = { + "hostname": "http://localhost:8000", + "email": "object.biocompute@gmail.com", + "token": self.token.key + } + self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) + response = self.client.post('/api/accounts/new/', data=data, format='json') + self.assertEqual(response.status_code, 409) + + def test_account_creation_server_error(self): + # Tests for 500 - Invalid email and missing token in request body + ## Server error!!! + + + data = { + "hostname": "http://localhost:8000", + "email": "invalid", + #"token": self.token.key + } + self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) + response = self.client.post('/api/accounts/new/', data=data, format='json') + self.assertEqual(response.status_code, 500) diff --git a/tests/test_views/test_api_verify.py b/tests/test_views/test_api_verify.py new file mode 100644 index 00000000..aa319021 --- /dev/null +++ b/tests/test_views/test_api_verify.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 + +'''Verify a valid token + Tests for 201 + ''' + +from django.test import TestCase +from rest_framework.test import APIClient +from rest_framework.authtoken.models import Token +from django.contrib.auth.models import User +from rest_framework.test import APITestCase + + +class VerifyTokenBCOTestCase(TestCase): + fixtures = ['tests/fixtures/test_data'] + def setUp(self): + + self.client = APIClient() + # Checking if the user 'bco_api_user' already exists + try: + self.user = User.objects.get(username='bco_api_user') + except User.DoesNotExist: + self.user = User.objects.create_user(username='bco_api_user') + + # Checking if user already has token, if not then creating one + if not Token.objects.filter(user=self.user).exists(): + self.token = Token.objects.create(user=self.user) + else: + self.token = Token.objects.get(user=self.user) + + def test_valid_token(self): + ##Test for a valid token + + data = { + "token": self.token.key + } + #self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) + response = self.client.post('/api/verify/', data=data, format='json') + self.assertEqual(response.status_code, 200) + self.assertEqual(response.data["token"], self.token.key) + + def test_missing_token(self): + # Test when token field is missing + data = {} + response = self.client.post('/api/verify/', data=data, format='json') + self.assertEqual(response.status_code, 400) + + + def test_invalid_token(self): + # Test for an invalid token + data = { + "token": "invalid_token_here" + } + response = self.client.post('/api/verify/', data=data, format='json') + self.assertEqual(response.status_code, 403) \ No newline at end of file From 7a65ad3de624f20c2d1272f2175ee7375b6563d0 Mon Sep 17 00:00:00 2001 From: Reeya Gupta Date: Fri, 25 Aug 2023 12:53:50 -0400 Subject: [PATCH 15/20] Update test_api_verify.py --- tests/test_views/test_api_verify.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/tests/test_views/test_api_verify.py b/tests/test_views/test_api_verify.py index aa319021..44a07df9 100644 --- a/tests/test_views/test_api_verify.py +++ b/tests/test_views/test_api_verify.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 '''Verify a valid token - Tests for 201 + ''' from django.test import TestCase @@ -30,14 +30,18 @@ def setUp(self): def test_valid_token(self): ##Test for a valid token + ##Gives 400 instead of 200 data = { - "token": self.token.key + "VerifyAuthToken": [ + {"token": self.token.key} + ] } - #self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) + self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) response = self.client.post('/api/verify/', data=data, format='json') self.assertEqual(response.status_code, 200) - self.assertEqual(response.data["token"], self.token.key) + #self.assertIn('Success- Token is valid.', response.data[0]['message']) + #self.assertEqual(response.data["token"], self.token.key) def test_missing_token(self): # Test when token field is missing @@ -49,7 +53,12 @@ def test_missing_token(self): def test_invalid_token(self): # Test for an invalid token data = { - "token": "invalid_token_here" + "VerifyAuthToken": [ + {"token": "invalid token here"} + ] } + self.client.credentials(HTTP_AUTHORIZATION='iNVALID TOKEN') response = self.client.post('/api/verify/', data=data, format='json') - self.assertEqual(response.status_code, 403) \ No newline at end of file + #self.assertIn('Error- Token is invalid.', response.data.get('message')) + self.assertEqual(response.status_code, 400) + \ No newline at end of file From 73d7cc398e767133b7c688671f02deea51ae25ee Mon Sep 17 00:00:00 2001 From: Reeya Gupta Date: Sun, 27 Aug 2023 23:45:45 -0400 Subject: [PATCH 16/20] branch - objects_drafts_read --- api/scripts/utilities/UserUtils.py | 4 +- .../test_api_objects_drafts_permissions.py | 705 ++++++++++++++++++ .../test_api_objects_drafts_read.py | 85 +++ 3 files changed, 792 insertions(+), 2 deletions(-) create mode 100644 tests/test_views/test_api_objects_drafts_permissions.py create mode 100644 tests/test_views/test_api_objects_drafts_read.py diff --git a/api/scripts/utilities/UserUtils.py b/api/scripts/utilities/UserUtils.py index 4ff5b375..80911671 100755 --- a/api/scripts/utilities/UserUtils.py +++ b/api/scripts/utilities/UserUtils.py @@ -249,7 +249,7 @@ def prefix_perms_for_user( # return bco_specific - def user_from_request(self, request): + def user_from_request(self, rq): """Returns a user object from a request. Parameters @@ -263,6 +263,6 @@ def user_from_request(self, request): """ user_id = Token.objects.get( - key=request.META.get("HTTP_AUTHORIZATION").split(" ")[1] + key=rq.META.get("HTTP_AUTHORIZATION").split(" ")[1] ).user_id return User.objects.get(id=user_id) diff --git a/tests/test_views/test_api_objects_drafts_permissions.py b/tests/test_views/test_api_objects_drafts_permissions.py new file mode 100644 index 00000000..bc621c31 --- /dev/null +++ b/tests/test_views/test_api_objects_drafts_permissions.py @@ -0,0 +1,705 @@ + +#!/usr/bin/env python3 + +"""Test Permissions draft BCO +Tests for Partial failure(300) and invalid token(403) + +Gives 300 instead of 200 and 400 +""" + +from django.test import TestCase +from rest_framework.test import APIClient +from rest_framework.authtoken.models import Token +from django.contrib.auth.models import User +from rest_framework.test import APITestCase + +class PermissionDraftBCOTestCase(TestCase): + fixtures = ['tests/fixtures/test_data'] + + def setUp(self): + + self.client = APIClient() + # Checking if the user 'bco_api_user' already exists + try: + self.user = User.objects.get(username='bco_api_user') + except User.DoesNotExist: + self.user = User.objects.create_user(username='bco_api_user') + + # Checking if user already has token, if not then creating one + if not Token.objects.filter(user=self.user).exists(): + self.token = Token.objects.create(user=self.user) + else: + self.token = Token.objects.get(user=self.user) + + def test_permission_bco_success(self): + #Gives 300 instead of 200 + + data = { + "POST_api_objects_drafts_permissions": [ + { + "object_id": "http://127.0.0.1:8000/BCO_000000/DRAFT", + "contents": { + "object_id": "http://127.0.0.1:8000/BCO_000000/DRAFT", + "spec_version": "https://w3id.org/ieee/ieee-2791-schema/2791object.json", + "etag": "0275321b6011324035289a5624c635ce5490fbdec588aa5f3bcaf63b85369b4a", + "provenance_domain": { + "name": "Influenza A reference gene sequences", + "version": "1.1", + "created": "2021-12-01T15:20:13.614Z", + "modified": "2022-06-28T23:10:12.804Z", + "review": [ + + ], + "contributors": [ + { + "contribution": [ + "createdBy", + "authoredBy", + "curatedBy", + "importedBy", + "contributedBy" + ], + "name": "Stephanie Singleton", + "affiliation": "The George Washington University ", + "email": "ssingleton@gwu.edu" + }, + { + "contribution": [ + "createdBy" + ], + "name": "Jonathon Keeney", + "affiliation": "The George Washington University ", + "email": "keeneyjg@gwu.edu" + } + ], + "license": "MIT" + }, + "usability_domain": [ + "Influenza A (A/Puerto Rico/8/1934 H1N1) reference protein coding sequences.", + "Cross reference to genes was retrieved using mappings present in proteins that were retrieved using UniProt proteome ID (UniProt ID: UP000009255; strain A/Puerto Rico/8/1934 H1N1). This set was chosen based on UniProt curation emphasis and community use. The primary use case for this data set is to visualize how protein annotations related to drug resistance mutations, selection pressure and more map to gene sequences. " + ], + "description_domain": { + "keywords": [ + "Influenza A, Complete Genome, FASTA, Genes" + ], + "platform": [ + + ], + "pipeline_steps": [ + { + "step_number": 0, + "name": "Download files from UniProt", + "description": "Download all files associated with the Influenza A reference genome (influenza A, UP000009255) into the ARGOS Dev server Downloads folder. While logged into the server, execute the following commands: wget ftp://ftp.uniprot.org/pub/databases/uniprot/current_release/knowledgebase/reference_proteomes/Viruses/UP000009255/*. One of the files acquired through this step and necessary for generating a new data set is 'UP000009255_211044_DNA.fasta.gz'. Then execute 'gunzip *.gz' to unzip all the files in the downloads folder. The file name is then changed to 'UP000009255_211044_DNA.fasta' in the downloads folder.", + "prerequisite": [ + { + "name": "UniProt reference page ", + "uri": { + "uri": "ftp://ftp.uniprot.org/pub/databases/uniprot/current_release/knowledgebase/reference_proteomes/Viruses/UP000009255/", + "access_time": "2021-12-01T15:20:13.614Z" + } + } + ], + "input_list": [ + { + "uri": "ftp://argosdb-vm-dev/data/shared/argosdb/downloads/uniprot/v1.0/influenza_a/UP000009255_211044_DNA.fasta.gz", + "filename": "UP000009255_211044_DNA.fasta.gz", + "access_time": "2021-12-01T15:20:13.614Z" + } + ], + "output_list": [ + { + "uri": "ftp://argosdb-vm-dev/data/shared/argosdb/downloads/uniprot/v1.0/influenza_a/UP000009255_211044_DNA.fasta", + "filename": "UP000009255_211044_DNA.fasta", + "access_time": "2021-12-01T15:20:13.614Z" + } + ], + "version": "1.1" + }, + { + "step_number": 0, + "name": "Run the recipe created to process this fasta file, review the newly generated dataset, and change the name of the file for clarity", + "description": "This step will use a recipe and a python script to generate a new dataset. The recipe tells the python script how and what to construct. This dataset will then be then moved in the 'unreviewed' folder in the dev argosdb server, it will be manually reviewed, and then the name of the file will be changed for clarity and tracking purposes - this is prefered. \\nMake sure you are located in the correct folder to run the script (/software/argosdb/dataset-maker). Use the following command to run the recipe and the python script: ‘python3 make-dataset.py -i recipes/influenza_UP000009255_genome_sequences.json’. Next, go to the ‘unreviewed’ folder to review the newly generated dataset ‘UP000009255_211044_DNA.fasta’. Once reviewed and approved, move the file to the ‘reviewed’ folder. Lastly, once in the ‘reviewed’ folder, change the name of the file to: ‘ influenza_UP000009255_211044_DNA.fasta’", + "prerequisite": [ + { + "name": "Dataset-maker python script", + "uri": { + "uri": "ftp://argosdb-vm-dev/software/argosdb/make-dataset.py", + "filename": "make-dataset.py" + } + }, + { + "name": "Influenza genome FASTA recipe", + "uri": { + "uri": "ftp://argosdb-vm-dev/data/shared/argosdb/generated/datasets/recipes/Influenza/influenza_UP000009255_genome_sequences.json", + "filename": "influenza_UP000009255_genome_sequences.json" + } + } + ], + "input_list": [ + { + "uri": "ftp://argosdb-vm-dev/data/shared/argosdb/downloads/uniprot/v1.0/influenza_a/UP000009255_211044_DNA.fasta", + "filename": "UP000009255_211044_DNA.fasta", + "access_time": "2021-12-01T15:20:13.614Z" + } + ], + "output_list": [ + { + "uri": "ftp://argosdb-vm-dev/data/shared/argosdb/generated/datasets/reviewed/influenza_UP000009255_211044_DNA.fasta", + "filename": "influenza_UP000009255_211044_DNA.fasta", + "access_time": "2021-12-01T15:20:13.614Z" + } + ], + "version": "1.1" + } + ] + }, + "execution_domain": { + "script": [ + { + "uri": { + "uri": "ftp://argosdb-vm-dev/software/argosdb/make-dataset.py", + "filename": "make-dataset.py" + } + } + ], + "script_driver": "python3", + "software_prerequisites": [ + { + "name": "Python", + "version": "3", + "uri": { + "uri": "https://www.python.org/ftp/python/3.10.0/python-3.10.0-amd64.exe", + "filename": "" + } + } + ], + "external_data_endpoints": [ + { + "name": "python-3.10.0", + "url": "https://www.python.org/ftp/python/3.10.0/python-3.10.0-amd64.exe" + } + ], + "environment_variables": { + } + }, + "io_domain": { + "input_subdomain": [ + { + "uri": { + "uri": "http://data.argosdb.org/ln2downloads/uniprot/v1.0/UP000009255_211044_DNA.fasta", + "filename": "UP000009255_211044_DNA.fasta" + } + } + ], + "output_subdomain": [ + { + "mediatype": "text/plain", + "uri": { + "uri": "http://data.argosdb.org/ln2data/uniprot/v1.0/UP000009255_211044_DNA.fasta", + "filename": "UP000009255_211044_DNA.fasta" + } + } + ] + }, + "parametric_domain": [ + + ], + "extension_domain": [ + { + "extension_schema": "http://www.w3id.org/biocompute/extension_domain/1.1.0/dataset/dataset_extension.json", + "dataset_extension": { + "additional_license": { + "data_license": "https://creativecommons.org/licenses/by/4.0/", + "script_license": "https://www.gnu.org/licenses/gpl-3.0.en.html" + }, + "dataset_categories": [ + { + "category_value": "Influenza A", + "category_name": "species" + }, + { + "category_value": "nucleotide", + "category_name": "molecule" + }, + { + "category_value": "Influenza A", + "category_name": "tag" + }, + { + "category_value": "fasta", + "category_name": "file_type" + }, + { + "category_value": "reviewed", + "category_name": "status" + }, + { + "category_value": "internal", + "category_name": "scope" + } + ] + } + } + ] + } + } + ] + } + self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) + response = self.client.post('/api/objects/drafts/permissions/', data=data, format='json') + self.assertEqual(response.status_code, 200) + + def test_permission_bco_partial_failure(self): + data = { + "POST_api_objects_drafts_permissions": [ + { + "object_id": "http://127.0.0.1:8000/BCO_000000/DRAFT", + "contents": { + "object_id": "http://127.0.0.1:8000/BCO_000000/DRAFT", + "spec_version": "https://w3id.org/ieee/ieee-2791-schema/2791object.json", + "etag": "0275321b6011324035289a5624c635ce5490fbdec588aa5f3bcaf63b85369b4a", + "provenance_domain": { + "name": "Influenza A reference gene sequences", + "version": "1.1", + "created": "2021-12-01T15:20:13.614Z", + "modified": "2022-06-28T23:10:12.804Z", + "review": [ + + ], + "contributors": [ + { + "contribution": [ + "createdBy", + "authoredBy", + "curatedBy", + "importedBy", + "contributedBy" + ], + "name": "Stephanie Singleton", + "affiliation": "The George Washington University ", + "email": "ssingleton@gwu.edu" + }, + { + "contribution": [ + "createdBy" + ], + "name": "Jonathon Keeney", + "affiliation": "The George Washington University ", + "email": "keeneyjg@gwu.edu" + } + ], + "license": "MIT" + }, + "usability_domain": [ + "Influenza A (A/Puerto Rico/8/1934 H1N1) reference protein coding sequences.", + "Cross reference to genes was retrieved using mappings present in proteins that were retrieved using UniProt proteome ID (UniProt ID: UP000009255; strain A/Puerto Rico/8/1934 H1N1). This set was chosen based on UniProt curation emphasis and community use. The primary use case for this data set is to visualize how protein annotations related to drug resistance mutations, selection pressure and more map to gene sequences. " + ], + "description_domain": { + "keywords": [ + "Influenza A, Complete Genome, FASTA, Genes" + ], + "platform": [ + + ], + "pipeline_steps": [ + { + "step_number": 0, + "name": "Download files from UniProt", + "description": "Download all files associated with the Influenza A reference genome (influenza A, UP000009255) into the ARGOS Dev server Downloads folder. While logged into the server, execute the following commands: wget ftp://ftp.uniprot.org/pub/databases/uniprot/current_release/knowledgebase/reference_proteomes/Viruses/UP000009255/*. One of the files acquired through this step and necessary for generating a new data set is 'UP000009255_211044_DNA.fasta.gz'. Then execute 'gunzip *.gz' to unzip all the files in the downloads folder. The file name is then changed to 'UP000009255_211044_DNA.fasta' in the downloads folder.", + "prerequisite": [ + { + "name": "UniProt reference page ", + "uri": { + "uri": "ftp://ftp.uniprot.org/pub/databases/uniprot/current_release/knowledgebase/reference_proteomes/Viruses/UP000009255/", + "access_time": "2021-12-01T15:20:13.614Z" + } + } + ], + "input_list": [ + { + "uri": "ftp://argosdb-vm-dev/data/shared/argosdb/downloads/uniprot/v1.0/influenza_a/UP000009255_211044_DNA.fasta.gz", + "filename": "UP000009255_211044_DNA.fasta.gz", + "access_time": "2021-12-01T15:20:13.614Z" + } + ], + "output_list": [ + { + "uri": "ftp://argosdb-vm-dev/data/shared/argosdb/downloads/uniprot/v1.0/influenza_a/UP000009255_211044_DNA.fasta", + "filename": "UP000009255_211044_DNA.fasta", + "access_time": "2021-12-01T15:20:13.614Z" + } + ], + "version": "1.1" + }, + { + "step_number": 0, + "name": "Run the recipe created to process this fasta file, review the newly generated dataset, and change the name of the file for clarity", + "description": "This step will use a recipe and a python script to generate a new dataset. The recipe tells the python script how and what to construct. This dataset will then be then moved in the 'unreviewed' folder in the dev argosdb server, it will be manually reviewed, and then the name of the file will be changed for clarity and tracking purposes - this is prefered. \\nMake sure you are located in the correct folder to run the script (/software/argosdb/dataset-maker). Use the following command to run the recipe and the python script: ‘python3 make-dataset.py -i recipes/influenza_UP000009255_genome_sequences.json’. Next, go to the ‘unreviewed’ folder to review the newly generated dataset ‘UP000009255_211044_DNA.fasta’. Once reviewed and approved, move the file to the ‘reviewed’ folder. Lastly, once in the ‘reviewed’ folder, change the name of the file to: ‘ influenza_UP000009255_211044_DNA.fasta’", + "prerequisite": [ + { + "name": "Dataset-maker python script", + "uri": { + "uri": "ftp://argosdb-vm-dev/software/argosdb/make-dataset.py", + "filename": "make-dataset.py" + } + }, + { + "name": "Influenza genome FASTA recipe", + "uri": { + "uri": "ftp://argosdb-vm-dev/data/shared/argosdb/generated/datasets/recipes/Influenza/influenza_UP000009255_genome_sequences.json", + "filename": "influenza_UP000009255_genome_sequences.json" + } + } + ], + "input_list": [ + { + "uri": "ftp://argosdb-vm-dev/data/shared/argosdb/downloads/uniprot/v1.0/influenza_a/UP000009255_211044_DNA.fasta", + "filename": "UP000009255_211044_DNA.fasta", + "access_time": "2021-12-01T15:20:13.614Z" + } + ], + "output_list": [ + { + "uri": "ftp://argosdb-vm-dev/data/shared/argosdb/generated/datasets/reviewed/influenza_UP000009255_211044_DNA.fasta", + "filename": "influenza_UP000009255_211044_DNA.fasta", + "access_time": "2021-12-01T15:20:13.614Z" + } + ], + "version": "1.1" + } + ] + }, + "execution_domain": { + "script": [ + { + "uri": { + "uri": "ftp://argosdb-vm-dev/software/argosdb/make-dataset.py", + "filename": "make-dataset.py" + } + } + ], + "script_driver": "python3", + "software_prerequisites": [ + { + "name": "Python", + "version": "3", + "uri": { + "uri": "https://www.python.org/ftp/python/3.10.0/python-3.10.0-amd64.exe", + "filename": "" + } + } + ], + "external_data_endpoints": [ + { + "name": "python-3.10.0", + "url": "https://www.python.org/ftp/python/3.10.0/python-3.10.0-amd64.exe" + } + ], + "environment_variables": { + } + }, + "io_domain": { + "input_subdomain": [ + { + "uri": { + "uri": "http://data.argosdb.org/ln2downloads/uniprot/v1.0/UP000009255_211044_DNA.fasta", + "filename": "UP000009255_211044_DNA.fasta" + } + } + ], + "output_subdomain": [ + { + "mediatype": "text/plain", + "uri": { + "uri": "http://data.argosdb.org/ln2data/uniprot/v1.0/UP000009255_211044_DNA.fasta", + "filename": "UP000009255_211044_DNA.fasta" + } + } + ] + }, + "parametric_domain": [ + + ], + "extension_domain": [ + { + "extension_schema": "http://www.w3id.org/biocompute/extension_domain/1.1.0/dataset/dataset_extension.json", + "dataset_extension": { + "additional_license": { + "data_license": "https://creativecommons.org/licenses/by/4.0/", + "script_license": "https://www.gnu.org/licenses/gpl-3.0.en.html" + }, + "dataset_categories": [ + { + "category_value": "Influenza A", + "category_name": "species" + }, + { + "category_value": "nucleotide", + "category_name": "molecule" + }, + { + "category_value": "Influenza A", + "category_name": "tag" + }, + { + "category_value": "fasta", + "category_name": "file_type" + }, + { + "category_value": "reviewed", + "category_name": "status" + }, + { + "category_value": "internal", + "category_name": "scope" + } + ] + } + } + ] + } + }, + { + "object_id": "http://127.0.0.1:8000/BCO_1234567/DRAFT", + "contents": { + + } + } + ] + } + self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) + response = self.client.post('/api/objects/drafts/permissions/', data=data, format='json') + self.assertEqual(response.status_code, 300) + + def test_read_bco_bad_request(self): + ##Gives 300 instead of 400 + data = { + "POST_api_objects_drafts_permissions": [ + { + # Provide invalid or missing data + "object_id": "Invalid_objectid", + "contents": { + + } + } + ] + } + self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) + response = self.client.post('/api/objects/drafts/permissions/', data=data, format='json') + self.assertEqual(response.status_code, 400) + + def test_read_bco_invalid_token(self): + data = { + "POST_api_objects_drafts_permissions": [ + { + "object_id": "http://127.0.0.1:8000/BCO_000000/DRAFT", + "contents": { + "object_id": "http://127.0.0.1:8000/BCO_000000/DRAFT", + "spec_version": "https://w3id.org/ieee/ieee-2791-schema/2791object.json", + "etag": "0275321b6011324035289a5624c635ce5490fbdec588aa5f3bcaf63b85369b4a", + "provenance_domain": { + "name": "Influenza A reference gene sequences", + "version": "1.1", + "created": "2021-12-01T15:20:13.614Z", + "modified": "2022-06-28T23:10:12.804Z", + "review": [ + + ], + "contributors": [ + { + "contribution": [ + "createdBy", + "authoredBy", + "curatedBy", + "importedBy", + "contributedBy" + ], + "name": "Stephanie Singleton", + "affiliation": "The George Washington University ", + "email": "ssingleton@gwu.edu" + }, + { + "contribution": [ + "createdBy" + ], + "name": "Jonathon Keeney", + "affiliation": "The George Washington University ", + "email": "keeneyjg@gwu.edu" + } + ], + "license": "MIT" + }, + "usability_domain": [ + "Influenza A (A/Puerto Rico/8/1934 H1N1) reference protein coding sequences.", + "Cross reference to genes was retrieved using mappings present in proteins that were retrieved using UniProt proteome ID (UniProt ID: UP000009255; strain A/Puerto Rico/8/1934 H1N1). This set was chosen based on UniProt curation emphasis and community use. The primary use case for this data set is to visualize how protein annotations related to drug resistance mutations, selection pressure and more map to gene sequences. " + ], + "description_domain": { + "keywords": [ + "Influenza A, Complete Genome, FASTA, Genes" + ], + "platform": [ + + ], + "pipeline_steps": [ + { + "step_number": 0, + "name": "Download files from UniProt", + "description": "Download all files associated with the Influenza A reference genome (influenza A, UP000009255) into the ARGOS Dev server Downloads folder. While logged into the server, execute the following commands: wget ftp://ftp.uniprot.org/pub/databases/uniprot/current_release/knowledgebase/reference_proteomes/Viruses/UP000009255/*. One of the files acquired through this step and necessary for generating a new data set is 'UP000009255_211044_DNA.fasta.gz'. Then execute 'gunzip *.gz' to unzip all the files in the downloads folder. The file name is then changed to 'UP000009255_211044_DNA.fasta' in the downloads folder.", + "prerequisite": [ + { + "name": "UniProt reference page ", + "uri": { + "uri": "ftp://ftp.uniprot.org/pub/databases/uniprot/current_release/knowledgebase/reference_proteomes/Viruses/UP000009255/", + "access_time": "2021-12-01T15:20:13.614Z" + } + } + ], + "input_list": [ + { + "uri": "ftp://argosdb-vm-dev/data/shared/argosdb/downloads/uniprot/v1.0/influenza_a/UP000009255_211044_DNA.fasta.gz", + "filename": "UP000009255_211044_DNA.fasta.gz", + "access_time": "2021-12-01T15:20:13.614Z" + } + ], + "output_list": [ + { + "uri": "ftp://argosdb-vm-dev/data/shared/argosdb/downloads/uniprot/v1.0/influenza_a/UP000009255_211044_DNA.fasta", + "filename": "UP000009255_211044_DNA.fasta", + "access_time": "2021-12-01T15:20:13.614Z" + } + ], + "version": "1.1" + }, + { + "step_number": 0, + "name": "Run the recipe created to process this fasta file, review the newly generated dataset, and change the name of the file for clarity", + "description": "This step will use a recipe and a python script to generate a new dataset. The recipe tells the python script how and what to construct. This dataset will then be then moved in the 'unreviewed' folder in the dev argosdb server, it will be manually reviewed, and then the name of the file will be changed for clarity and tracking purposes - this is prefered. \\nMake sure you are located in the correct folder to run the script (/software/argosdb/dataset-maker). Use the following command to run the recipe and the python script: ‘python3 make-dataset.py -i recipes/influenza_UP000009255_genome_sequences.json’. Next, go to the ‘unreviewed’ folder to review the newly generated dataset ‘UP000009255_211044_DNA.fasta’. Once reviewed and approved, move the file to the ‘reviewed’ folder. Lastly, once in the ‘reviewed’ folder, change the name of the file to: ‘ influenza_UP000009255_211044_DNA.fasta’", + "prerequisite": [ + { + "name": "Dataset-maker python script", + "uri": { + "uri": "ftp://argosdb-vm-dev/software/argosdb/make-dataset.py", + "filename": "make-dataset.py" + } + }, + { + "name": "Influenza genome FASTA recipe", + "uri": { + "uri": "ftp://argosdb-vm-dev/data/shared/argosdb/generated/datasets/recipes/Influenza/influenza_UP000009255_genome_sequences.json", + "filename": "influenza_UP000009255_genome_sequences.json" + } + } + ], + "input_list": [ + { + "uri": "ftp://argosdb-vm-dev/data/shared/argosdb/downloads/uniprot/v1.0/influenza_a/UP000009255_211044_DNA.fasta", + "filename": "UP000009255_211044_DNA.fasta", + "access_time": "2021-12-01T15:20:13.614Z" + } + ], + "output_list": [ + { + "uri": "ftp://argosdb-vm-dev/data/shared/argosdb/generated/datasets/reviewed/influenza_UP000009255_211044_DNA.fasta", + "filename": "influenza_UP000009255_211044_DNA.fasta", + "access_time": "2021-12-01T15:20:13.614Z" + } + ], + "version": "1.1" + } + ] + }, + "execution_domain": { + "script": [ + { + "uri": { + "uri": "ftp://argosdb-vm-dev/software/argosdb/make-dataset.py", + "filename": "make-dataset.py" + } + } + ], + "script_driver": "python3", + "software_prerequisites": [ + { + "name": "Python", + "version": "3", + "uri": { + "uri": "https://www.python.org/ftp/python/3.10.0/python-3.10.0-amd64.exe", + "filename": "" + } + } + ], + "external_data_endpoints": [ + { + "name": "python-3.10.0", + "url": "https://www.python.org/ftp/python/3.10.0/python-3.10.0-amd64.exe" + } + ], + "environment_variables": { + } + }, + "io_domain": { + "input_subdomain": [ + { + "uri": { + "uri": "http://data.argosdb.org/ln2downloads/uniprot/v1.0/UP000009255_211044_DNA.fasta", + "filename": "UP000009255_211044_DNA.fasta" + } + } + ], + "output_subdomain": [ + { + "mediatype": "text/plain", + "uri": { + "uri": "http://data.argosdb.org/ln2data/uniprot/v1.0/UP000009255_211044_DNA.fasta", + "filename": "UP000009255_211044_DNA.fasta" + } + } + ] + }, + "parametric_domain": [ + + ], + "extension_domain": [ + { + "extension_schema": "http://www.w3id.org/biocompute/extension_domain/1.1.0/dataset/dataset_extension.json", + "dataset_extension": { + "additional_license": { + "data_license": "https://creativecommons.org/licenses/by/4.0/", + "script_license": "https://www.gnu.org/licenses/gpl-3.0.en.html" + }, + "dataset_categories": [ + { + "category_value": "Influenza A", + "category_name": "species" + }, + { + "category_value": "nucleotide", + "category_name": "molecule" + }, + { + "category_value": "Influenza A", + "category_name": "tag" + }, + { + "category_value": "fasta", + "category_name": "file_type" + }, + { + "category_value": "reviewed", + "category_name": "status" + }, + { + "category_value": "internal", + "category_name": "scope" + } + ] + } + } + ] + } + } + ] + } + self.client.credentials(HTTP_AUTHORIZATION='Invalid token') + response = self.client.post('/api/objects/drafts/permissions/', data=data, format='json') + self.assertEqual(response.status_code, 403) diff --git a/tests/test_views/test_api_objects_drafts_read.py b/tests/test_views/test_api_objects_drafts_read.py new file mode 100644 index 00000000..3182d41e --- /dev/null +++ b/tests/test_views/test_api_objects_drafts_read.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 + +"""Test for reading a draft bco +Tests for Partial failure(300) and invalid token(403) + +Gives 300 instead of 200 and 400 +""" + +from django.test import TestCase +from rest_framework.test import APIClient +from rest_framework.authtoken.models import Token +from django.contrib.auth.models import User + +class ReadDraftBCOTestCase(TestCase): + fixtures = ['tests/fixtures/test_data'] + + def setUp(self): + + self.client = APIClient() + # Checking if the user 'bco_api_user' already exists + try: + self.user = User.objects.get(username='bco_api_user') + except User.DoesNotExist: + self.user = User.objects.create_user(username='bco_api_user') + + # Checking if user already has token, if not then creating one + if not Token.objects.filter(user=self.user).exists(): + self.token = Token.objects.create(user=self.user) + else: + self.token = Token.objects.get(user=self.user) + + def test_read_bco_success(self): + ##Gives 300 instead of 200 + data = { + "POST_api_objects_drafts_read": [ + { + "object_id": "http://127.0.0.1:8000/BCO_000000/DRAFT" + + } + ] + } + self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) + response = self.client.post('/api/objects/drafts/read/', data=data, format='json') + self.assertEqual(response.status_code, 200) + + def test_read_bco_partial_failure(self): + data = { + "POST_api_objects_drafts_read": [ + { + "object_id": "http://127.0.0.1:8000/BCO_000000/DRAFT" + }, + { + "object_id": "http://127.0.0.1:8000/BCO_1234567/DRAFT" #Invalid object id + } + ] + } + self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) + response = self.client.post('/api/objects/drafts/read/', data=data, format='json') + self.assertEqual(response.status_code, 300) + + def test_read_bco_bad_request(self): + ##Gives 300 instead of 400 + data = { + "POST_api_objects_drafts_read": [ + { + # Provide invalid or missing data + "object_id": "Invalid_objectid" + } + ] + } + self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) + response = self.client.post('/api/objects/drafts/read/', data=data, format='json') + self.assertEqual(response.status_code, 400) + + def test_read_bco_invalid_token(self): + data = { + "POST_api_objects_drafts_read": [ + { + "object_id": "http://127.0.0.1:8000/BCO_000000/DRAFT" + } + ] + } + self.client.credentials(HTTP_AUTHORIZATION='Invalid token') + response = self.client.post('/api/objects/drafts/read/', data=data, format='json') + self.assertEqual(response.status_code, 403) From c9e0347157e3065057f2f726b8793ddecf467ffe Mon Sep 17 00:00:00 2001 From: Reeya Gupta Date: Sun, 27 Aug 2023 23:48:12 -0400 Subject: [PATCH 17/20] branch- objects_drafts_permissions --- tests/test_views/test_api_objects_drafts_permissions.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_views/test_api_objects_drafts_permissions.py b/tests/test_views/test_api_objects_drafts_permissions.py index bc621c31..74a59e2d 100644 --- a/tests/test_views/test_api_objects_drafts_permissions.py +++ b/tests/test_views/test_api_objects_drafts_permissions.py @@ -5,6 +5,7 @@ Tests for Partial failure(300) and invalid token(403) Gives 300 instead of 200 and 400 + """ from django.test import TestCase From f1c5f4fb3d7c6be369343f9ade34577da4b7b61a Mon Sep 17 00:00:00 2001 From: Reeya Gupta Date: Sun, 27 Aug 2023 23:58:03 -0400 Subject: [PATCH 18/20] Update test_api_objects_drafts_permissions.py --- tests/test_views/test_api_objects_drafts_permissions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_views/test_api_objects_drafts_permissions.py b/tests/test_views/test_api_objects_drafts_permissions.py index 74a59e2d..1d00c4dc 100644 --- a/tests/test_views/test_api_objects_drafts_permissions.py +++ b/tests/test_views/test_api_objects_drafts_permissions.py @@ -472,7 +472,7 @@ def test_permission_bco_partial_failure(self): response = self.client.post('/api/objects/drafts/permissions/', data=data, format='json') self.assertEqual(response.status_code, 300) - def test_read_bco_bad_request(self): + def test_permission_bco_bad_request(self): ##Gives 300 instead of 400 data = { "POST_api_objects_drafts_permissions": [ @@ -489,7 +489,7 @@ def test_read_bco_bad_request(self): response = self.client.post('/api/objects/drafts/permissions/', data=data, format='json') self.assertEqual(response.status_code, 400) - def test_read_bco_invalid_token(self): + def test_permission_bco_invalid_token(self): data = { "POST_api_objects_drafts_permissions": [ { From a5b7c3e57602a2eeac937dee7d7970fbd4318d27 Mon Sep 17 00:00:00 2001 From: Reeya Gupta Date: Thu, 31 Aug 2023 12:57:44 -0400 Subject: [PATCH 19/20] Branch prefixes_delete --- tests/test_views/test_api_prefixes_delete.py | 85 ++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 tests/test_views/test_api_prefixes_delete.py diff --git a/tests/test_views/test_api_prefixes_delete.py b/tests/test_views/test_api_prefixes_delete.py new file mode 100644 index 00000000..9b191a0b --- /dev/null +++ b/tests/test_views/test_api_prefixes_delete.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 + +"""Test for Deleting a prefix + + Givesw 200 instead of 401,403,404 - Requires Debugging +""" + +from django.test import TestCase +from rest_framework.test import APIClient +from rest_framework.authtoken.models import Token +from django.contrib.auth.models import User + +class PrefixDeleteTestCase(TestCase): + fixtures = ['tests/fixtures/test_data'] + # Using wheel instead of bco_api_user because wheel is in group prefix_admins + + def setUp(self): + + self.client = APIClient() + # Checking if the user 'bco_api_user' already exists + try: + self.user = User.objects.get(username='wheel') + except User.DoesNotExist: + self.user = User.objects.create_user(username='wheel') + + # Checking if user already has token, if not then creating one + if not Token.objects.filter(user=self.user).exists(): + self.token = Token.objects.create(user=self.user) + else: + self.token = Token.objects.get(user=self.user) + + + #self.prefix_to_delete = "OTHER" + + def test_delete_prefix_success(self): + + data = { + "POST_api_prefixes_delete": [ + "OTHER", + "TESTR" + ] + } + self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) + response = self.client.post('/api/prefixes/delete/', data=data, format='json') + self.assertEqual(response.status_code, 200) + + def test_delete_prefix_unauthorized(self): + ##providing no authorization + #Gives 200 instead of 401 + data = { + "POST_api_prefixes_delete": { + "prefixes": ["OTHER"] + } + } + response = self.client.post('/api/prefixes/delete/', data=data, format='json') + self.assertEqual(response.status_code, 401) + + def test_delete_prefix_forbidden(self): + # Simulate a user without necessary permissions- Invalid token. + #Gives 200 instead of 403 + #self.user.groups.add('prefix_users') + + data = { + "POST_api_prefixes_delete": [ + "OTHER", + "TESTR" + ] + } + self.client.credentials(HTTP_AUTHORIZATION='Invalid token') + response = self.client.post('/api/prefixes/delete/', data=data, format='json') + self.assertEqual(response.status_code, 403) + + def test_delete_prefix_not_found(self): + #The prefix couldn't be found so therefore it could not be deleted. + #non_existent_prefix = "NONEXISTENT" + + ##Gives 200 instead of 404 + data = { + "POST_api_prefixes_delete": [ + "nonexsistent prefix" + ] + } + self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) + response = self.client.post('/api/prefixes/delete/', data=data, format='json') + self.assertEqual(response.status_code, 404) From 40c0b5f4b8c10dfcbff992eb36c99760a7e1cc1a Mon Sep 17 00:00:00 2001 From: Reeya Gupta Date: Thu, 31 Aug 2023 16:52:27 -0400 Subject: [PATCH 20/20] Branch - objects_drafts_permissions_set --- ...test_api_objects_drafts_permissions_set.py | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 tests/test_views/test_api_objects_drafts_permissions_set.py diff --git a/tests/test_views/test_api_objects_drafts_permissions_set.py b/tests/test_views/test_api_objects_drafts_permissions_set.py new file mode 100644 index 00000000..9ddd4698 --- /dev/null +++ b/tests/test_views/test_api_objects_drafts_permissions_set.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python3 + +"""Set permissions for a bco draft + + Tests for 200 and 403 + + Gives 200 instead of 400 and 300 +""" + +from django.test import TestCase +from rest_framework.test import APIClient +from rest_framework.authtoken.models import Token +from django.contrib.auth.models import User +from rest_framework.test import APITestCase + +class BCOPermissionsTestCase(APITestCase): + fixtures = ['tests/fixtures/test_data'] + + def setUp(self): + + self.client = APIClient() + # Checking if the user 'bco_api_user' already exists + try: + self.user = User.objects.get(username='bco_api_user') + except User.DoesNotExist: + self.user = User.objects.create_user(username='bco_api_user') + + # Checking if user already has token, if not then creating one + if not Token.objects.filter(user=self.user).exists(): + self.token = Token.objects.create(user=self.user) + else: + self.token = Token.objects.get(user=self.user) + def test_set_permissions_successful(self): + data = { + "POST_api_objects_drafts_permissions_set": [ + { + "object_id": "http://127.0.0.1:8000/BCO_000000/DRAFT", + "actions": { + "remove_permissions": "some_permissions_to_remove", + "full_permissions": "some_full_permissions", + "add_permissions": "some_permissions_to_add" + } + } + ] + } + self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) + response = self.client.post('/api/objects/drafts/permissions/set/', data=data, format='json') + self.assertEqual(response.status_code, 200) + + def test_some_requests_failed(self): + ##Partial failure + #Gives 200 instead of 300 + data = { + "POST_api_objects_drafts_permissions_set": [ + { + "object_id": "http://127.0.0.1:8000/BCO_000000/DRAFT", + "actions": { + "remove_permissions": "some_permissions_to_remove", + "full_permissions": "some_full_permissions", + "add_permissions": "some_permissions_to_add" + } + }, + { + "object_id": "Invalid", + "actions":{} + + } + ] + } + self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) + response = self.client.post('/api/objects/drafts/permissions/set/', data=data, format='json') + self.assertEqual(response.status_code, 300) + + def test_bad_request(self): + ##Bad request- Invalid data + #Gives 200 instead of 400 + data = { + + "POST_api_objects_drafts_permissions_set": [ + { + "object_id": "Invalid object id", + "actions": { + + } + } + ] + + + } # Invalid data + self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key) + response = self.client.post('/api/objects/drafts/permissions/set/', data=data, format='json') + self.assertEqual(response.status_code, 400) + + def test_invalid_token(self): + #Invalid token + data = { + "POST_api_objects_drafts_permissions_set": [ + { + "object_id": "http://127.0.0.1:8000/BCO_000000/DRAFT", + "actions": { + "remove_permissions": "some_permissions_to_remove", + "full_permissions": "some_full_permissions", + "add_permissions": "some_permissions_to_add" + } + } + ] + } + + + self.client.credentials(HTTP_AUTHORIZATION='Invalid token') + + response = self.client.post('/api/objects/drafts/permissions/set/', data=data, format='json') + self.assertEqual(response.status_code, 403)