From 299e37be292bde20987417a031d0271563369221 Mon Sep 17 00:00:00 2001 From: hakanaktas0 <104701041+hakanaktas0@users.noreply.github.com> Date: Fri, 24 Nov 2023 00:31:36 +0300 Subject: [PATCH 1/5] Bugs are all fixed --- project/backend/api/urls.py | 1 + project/backend/api/views.py | 218 +++++++++++++++++++++++------ project/backend/database/models.py | 4 +- 3 files changed, 182 insertions(+), 41 deletions(-) diff --git a/project/backend/api/urls.py b/project/backend/api/urls.py index 5cb5f0aa..9f379413 100644 --- a/project/backend/api/urls.py +++ b/project/backend/api/urls.py @@ -17,6 +17,7 @@ path('get_cont/', get_contributor_from_id, name='get_cont'), path('get_user_workspaces/',get_workspaces,name='get_user_workspaces'), path('get_workspace/',get_workspace_from_id,name='get_workspace'), + path('edit_entry/', edit_entry, name='edit_entry'), path('delete_entry/',delete_entry,name='delete_entry'), path('add_entry/',add_entry,name='add_entry'), path('get_random_node_id/',get_random_node_id,name='get_random_node_id'), diff --git a/project/backend/api/views.py b/project/backend/api/views.py index 879a81d4..99e60e84 100644 --- a/project/backend/api/views.py +++ b/project/backend/api/views.py @@ -1,4 +1,5 @@ from django.shortcuts import get_object_or_404 +from django.views.decorators.csrf import csrf_exempt from rest_framework.views import APIView from rest_framework.decorators import api_view, permission_classes from rest_framework.response import Response @@ -351,83 +352,222 @@ def get_workspace_from_id(request): 'references':references, 'created_at':workspace.created_at, }, status=200) +@csrf_exempt def delete_entry(request): - id = int(request.GET.get("entry_id")) - entry = Entry.objects.filter(entry_id=id) + entry_id = request.POST.get("entry_id") + workspace_id = request.POST.get("workspace_id") + if entry_id == None or entry_id == '': + return JsonResponse({'message': 'entry_id field can not be empty'}, status=400) + try: + entry_id = int(entry_id) + except: + return JsonResponse({'message': 'entry_id field has to be a integer'}, status=400) + if workspace_id == None or workspace_id == '': + return JsonResponse({'message': 'workspace_id field can not be empty'}, status=400) + try: + workspace_id = int(workspace_id) + except: + return JsonResponse({'message': 'workspace_id field has to be a integer'}, status=400) + entry = Entry.objects.filter(entry_id=entry_id) if entry.count() == 0: return JsonResponse({'message': 'There is no entry with this id.'}, status=404) - entry.delete() + workspace = Workspace.objects.filter(workspace_id=workspace_id) + if workspace.count() == 0: + return JsonResponse({'message': 'There is no workspace with this id.'}, status=404) + workspace = Workspace.objects.get(workspace_id=workspace_id) + if entry[0] not in workspace.entries.all(): + return JsonResponse({'message': 'There is no entry with this id in this workspace.'}, status=404) + workspace.entries.remove(entry[0]) + workspace.save() + return JsonResponse({'message': 'Entry with this id has been deleted from this workspace successfully.'}, status=200) + +@csrf_exempt def edit_entry(request): - id = int(request.GET.get("entry_id")) - entry = Entry.objects.filter(entry_id=id) - content = (request.GET.get("content")) + entry_id = request.POST.get("entry_id") + content = request.POST.get("content") + if entry_id == None or entry_id == '': + return JsonResponse({'message': 'entry_id field can not be empty'}, status=400) + try: + entry_id = int(entry_id) + except: + return JsonResponse({'message': 'entry_id field has to be a integer'}, status=400) + if content == None: + content = '' + entry = Entry.objects.filter(entry_id=entry_id) + if entry.count() == 0: + return JsonResponse({'message': 'there is no entry with this id'}, status=404) + entry = Entry.objects.get(entry_id=entry_id) entry.content = content + entry.save(update_fields=["content"]) + return JsonResponse({'message': 'entry content is updated successfully'}, status=200) +@csrf_exempt def delete_workspace(request): - id = int(request.GET.get("workspace_id")) - workspace = Workspace.objects.filter(workspace_id=id) + workspace_id = request.POST.get("workspace_id") + contributor_id = request.POST.get("contributor_id") + if workspace_id == None or workspace_id == '': + return JsonResponse({'message': 'workspace_id field can not be empty'}, status=400) + if contributor_id == None or contributor_id == '': + return JsonResponse({'message': 'node_id field can not be empty'}, status=400) + try: + workspace_id = int(workspace_id) + contributor_id = int(contributor_id) + except: + return JsonResponse({'message': 'workspace_id and contributor_id fields have to be a integer'}, status=400) + workspace = Workspace.objects.filter(workspace_id=workspace_id) if workspace.count() == 0: return JsonResponse({'message': 'There is no workspace with this id.'}, status=404) - workspace.delete() - + contributor = Contributor.objects.filter(id=contributor_id) + if contributor.count() == 0: + return JsonResponse({'message': 'There is no contributor with this id.'}, status=404) + if workspace[0] not in contributor[0].workspaces.all(): + return JsonResponse({'message': 'there is no contributor with this id in this workspace.'}, status=404) + contributor[0].workspaces.remove(workspace[0]) + contributor[0].save() + # if workspace[0].contributor_set.all().count() == 0: + # workspace[0].delete() + return JsonResponse({'message': 'workspace deleted successfully.'}, status=200) + +@csrf_exempt def delete_contributor(request): - id = int(request.GET.get("contributor_id")) - workspace_id = int(request.GET.get("workspace_id")) + contributor_id = request.POST.get("contributor_id") + workspace_id = request.POST.get("workspace_id") + if workspace_id == None or workspace_id == '': + return JsonResponse({'message': 'workspace_id field can not be empty'}, status=400) + if contributor_id == None or contributor_id == '': + return JsonResponse({'message': 'node_id field can not be empty'}, status=400) + try: + workspace_id = int(workspace_id) + contributor_id = int(contributor_id) + except: + return JsonResponse({'message': 'workspace_id and contributor_id fields have to be a integer'}, status=400) workspace = Workspace.objects.filter(workspace_id=workspace_id) - contributor = Contributor.objects.filter(contributor_id=id) + contributor = Contributor.objects.filter(id=contributor_id) if contributor.count() == 0: return JsonResponse({'message': 'There is no contributor with this id.'}, status=404) if workspace.count() == 0: return JsonResponse({'message': 'There is no workspace with this id.'}, status=404) - contributor[0].workspaces.delete(workspace_id = workspace_id) - contributor.save() + if workspace[0] not in contributor[0].workspaces.all(): + return JsonResponse({'message': 'there is no contributor with this id in this workspace.'}, status=404) + contributor[0].workspaces.remove(workspace[0]) + contributor[0].save() + return JsonResponse({'message': 'Contributor from workspace deleted successfully.'}, status=200) + +@csrf_exempt def delete_reference(request): - id = int(request.GET.get("workspace_id")) - node = int(request.GET.get("node_id")) - workspace = Workspace.objects.filter(workspace_id=id) + workspace_id = request.POST.get("workspace_id") + node_id = request.POST.get("node_id") + if workspace_id == None or workspace_id == '': + return JsonResponse({'message': 'workspace_id field can not be empty'}, status=400) + if node_id == None or node_id == '': + return JsonResponse({'message': 'node_id field can not be empty'}, status=400) + try: + workspace_id = int(workspace_id) + node_id = int(node_id) + except: + return JsonResponse({'message': 'workspace_id and node_id fields have to be a integer'}, status=400) + workspace = Workspace.objects.filter(workspace_id=workspace_id) if workspace.count() == 0: return JsonResponse({'message': 'There is no workspace with this id.'}, status=404) + if workspace[0].is_finalized == True: + return JsonResponse({'message': ' workspace already finalized'}, status=400) workspace = workspace[0] - reference = workspace.references.all(node = node) - if workspace.count() == 0: - return JsonResponse({'message': 'There is no reference with this id.'}, status=404) - reference.delete() + reference = workspace.references.filter(node_id = node_id) + if reference.count() == 0: + return JsonResponse({'message': 'There is no reference with this id in this workspace.'}, status=404) + workspace.references.remove(reference[0]) + return JsonResponse({'message': 'reference deleted successfully.'}, status=200) + +@csrf_exempt def finalize_workspace(request): - id = int(request.GET.get("workspace_id")) - workspace = Workspace.objects.filter(workspace_id=id) + workspace_id = request.POST.get("workspace_id") + if workspace_id == None or workspace_id == '': + return JsonResponse({'message': 'workspace_id field can not be empty'}, status=400) + try: + workspace_id = int(workspace_id) + except: + return JsonResponse({'message': 'workspace_id field has to be a integer'}, status=400) + workspace = Workspace.objects.filter(workspace_id=workspace_id) if workspace.count() == 0: return JsonResponse({'message': 'There is no workspace with this id.'}, status=404) + if workspace[0].is_finalized == True: + return JsonResponse({'message': ' workspace already finalized'}, status=400) + workspace = workspace[0] workspace.is_finalized = True workspace.is_in_review = False + workspace.save() + return JsonResponse({'message': 'workspace successfully finalized'}, status=200) +@csrf_exempt def add_entry(request): - id = int(request.GET.get("workspace_id")) - content = request.GET.get("entry_content") - workspace = Workspace.objects.filter(workspace_id=id) + workspace_id = request.POST.get("workspace_id") + content = request.POST.get("entry_content") + if workspace_id == None or workspace_id == '': + return JsonResponse({'message': 'workspace_id field can not be empty'}, status=400) + try: + workspace_id = int(workspace_id) + except: + return JsonResponse({'message': 'workspace_id field has to be a integer'}, status=400) + if content == None: + content = '' + workspace = Workspace.objects.filter(workspace_id=workspace_id) if workspace.count() == 0: return JsonResponse({'message': 'There is no workspace with this id.'}, status=404) - entry = Entry.objects.create(content=content) - workspace.entries.add(entry[0]) ## - workspace.save() - + if workspace[0].is_finalized == True: + return JsonResponse({'message': ' workspace already finalized'}, status=400) + entry = Entry.objects.create(content=content,entry_index=0, entry_number=0) # TODO WILL BE PROVIDED IN THE FUTURE + workspace[0].entries.add(entry) ## + workspace[0].save() + return JsonResponse({'message': 'Entry successfully added to workspace', + 'entry_id': entry.entry_id}, status=200) +@csrf_exempt def add_reference(request): - id = int(request.GET.get("workspace_id")) - node_id = int(request.GET.get("node_id")) - workspace = Workspace.objects.filter(workspace_id=id) + workspace_id = request.POST.get("workspace_id") + node_id = request.POST.get("node_id") + if workspace_id == None or workspace_id == '': + return JsonResponse({'message': 'workspace_id field can not be empty'}, status=400) + if node_id == None or node_id == '': + return JsonResponse({'message': 'node_id field can not be empty'}, status=400) + try: + workspace_id = int(workspace_id) + node_id = int(node_id) + except: + return JsonResponse({'message': 'workspace_id and node_id fields have to be a integer'}, status=400) + workspace = Workspace.objects.filter(workspace_id=workspace_id) + if workspace[0].is_finalized == True: + return JsonResponse({'message': ' workspace already finalized'}, status=400) node = Node.objects.filter(node_id=node_id) if workspace.count() == 0: return JsonResponse({'message': 'There is no workspace with this id.'}, status=404) if node.count() == 0: return JsonResponse({'message': 'There is no node with this id.'}, status=404) - workspace.references.add(node[0]) - workspace.save() - + if node[0] in workspace[0].references.all(): + return JsonResponse({'message': 'this reference already exists in this workspace.'}, status=400) + workspace[0].references.add(node[0]) + workspace[0].save() + return JsonResponse({'message': 'reference added to the workspace successfully.'}, status=200) +@csrf_exempt def create_workspace(request): - title = request.GET.get("workspace_title") + title = request.POST.get("workspace_title") + user_id = request.POST.get("user_id") + if title == '' or title == None: + return JsonResponse({'message': 'workspace_title field can not be empty'}, status=400) + if user_id == '' or user_id == None: + return JsonResponse({'message': 'user_id field can not be empty'}, status=400) + try: + creator = int(user_id) + except: + return JsonResponse({'message': 'user_id has to be a integer'}, status=400) + cont = Contributor.objects.filter(id=user_id) + if cont.count() == 0: + return JsonResponse({'message': 'there is no contributor with this user_id'}, status=400) workspace = Workspace.objects.create(workspace_title=title) workspace.save() - + cont[0].workspaces.add(workspace) + return JsonResponse({'message': 'Workspace with title ' + title + ' has been added successfully' , + 'workspace_id' : workspace.workspace_id}, status=200) +@csrf_exempt def get_random_node_id(request): count = int(request.GET.get("count")) node_ids = Node.node_id.all() diff --git a/project/backend/database/models.py b/project/backend/database/models.py index 0743d0d1..3f39767f 100644 --- a/project/backend/database/models.py +++ b/project/backend/database/models.py @@ -58,7 +58,7 @@ class Entry(models.Model): entry_index = models.IntegerField() #workspace_id = models.ForeignKey(Workspace,null=False, blank = False, on_delete=models.CASCADE,related_name='WorkspaceID') content = models.TextField(null=False) - entry_date = models.DateField() + entry_date = models.DateField(auto_now_add=True) is_theorem_entry = models.BooleanField(default=False) is_final_entry = models.BooleanField(default=False) is_proof_entry = models.BooleanField(default=False) @@ -71,7 +71,7 @@ def set_as_final(self): def set_as_theorem(self): self.is_theorem_entry = True def set_entry_content(self,cont): - self.content += cont + self.content = cont # Create your models here. class Workspace(models.Model): #Node and Review Requests may be added later workspace_id = models.AutoField(primary_key=True) From 29b0c415e653025052c55965a233c44514822aed Mon Sep 17 00:00:00 2001 From: hakanaktas0 <104701041+hakanaktas0@users.noreply.github.com> Date: Fri, 24 Nov 2023 00:33:35 +0300 Subject: [PATCH 2/5] Update views.py --- project/backend/api/views.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/project/backend/api/views.py b/project/backend/api/views.py index 99e60e84..36eb034f 100644 --- a/project/backend/api/views.py +++ b/project/backend/api/views.py @@ -300,10 +300,8 @@ def get_workspace_from_id(request): 'entry_number':entry.entry_number,}) semantic_tags = [] for tag in workspace.semantic_tags.all(): - semantic_tags.append({'label':tag.label, - 'desc':tag.desc, - 'parent_tag':tag.parent_tag, - 'created_at':tag.created_at}) + semantic_tags.append({'wid':tag.wid, + 'label':tag.label,}) contributors = [] for cont in Contributor.objects.filter(workspaces=workspace): user = User.objects.get(id=cont.user_id) From 0500b8d45e5077396597573e44650a741a30f806 Mon Sep 17 00:00:00 2001 From: hakanaktas0 <104701041+hakanaktas0@users.noreply.github.com> Date: Fri, 24 Nov 2023 00:44:49 +0300 Subject: [PATCH 3/5] Update tests.py --- project/backend/database/tests.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/project/backend/database/tests.py b/project/backend/database/tests.py index 6ebc8bc0..354c32c8 100644 --- a/project/backend/database/tests.py +++ b/project/backend/database/tests.py @@ -398,14 +398,13 @@ def test_entry_model(self): entry_id = 1, entry_index = 1, content = "This is an entry.", - entry_date = "2023-11-11", is_theorem_entry = True, entry_number = 1, ) self.assertEqual(entry.entry_id, 1) self.assertEqual(entry.entry_number, 1) self.assertEqual(entry.content, "This is an entry.") - self.assertEqual(entry.entry_date, "2023-11-11") + # self.assertEqual(entry.entry_date, "2023-11-11") self.assertEqual(entry.is_theorem_entry, True) # self.assertEqual(entry.is_final_entry,False) From 73cc1943438fb2da45710b0e3095dc090b5fcf4f Mon Sep 17 00:00:00 2001 From: Simurgan Date: Sat, 25 Nov 2023 21:04:44 +0300 Subject: [PATCH 4/5] implement workspace post api --- project/backend/api/urls.py | 1 + project/backend/api/views.py | 26 ++++++++++- project/backend/database/models.py | 5 +- project/backend/database/serializers.py | 61 +++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 3 deletions(-) diff --git a/project/backend/api/urls.py b/project/backend/api/urls.py index 9f379413..2e1f76b3 100644 --- a/project/backend/api/urls.py +++ b/project/backend/api/urls.py @@ -22,6 +22,7 @@ path('add_entry/',add_entry,name='add_entry'), path('get_random_node_id/',get_random_node_id,name='get_random_node_id'), path('create_workspace/',create_workspace,name='create_workspace'), + path('workspace_post/', WorkspacePostAPIView.as_view(), name='workspace_post'), path('add_reference/',add_reference,name='add_reference'), path('finalize_workspace/',finalize_workspace,name='finalize_workspace'), path('delete_contributor/',delete_contributor,name='delete_contributor'), diff --git a/project/backend/api/views.py b/project/backend/api/views.py index 36eb034f..6c5eaf97 100644 --- a/project/backend/api/views.py +++ b/project/backend/api/views.py @@ -3,7 +3,7 @@ from rest_framework.views import APIView from rest_framework.decorators import api_view, permission_classes from rest_framework.response import Response -from rest_framework.permissions import IsAuthenticated, AllowAny +from rest_framework.permissions import IsAuthenticated, AllowAny, BasePermission from database.serializers import * from django.contrib.auth import update_session_auth_hash from django.contrib.auth.models import User @@ -72,6 +72,30 @@ def get(self, request): serializer = NodeSerializer(node) return Response(serializer.data) +class IsContributorAndWorkspace(BasePermission): + def has_permission(self, request, view): + workspace_id = request.data.get('workspace_id') + if not request.user.is_authenticated: + return False + if not Contributor.objects.filter(pk=request.user.basicuser.pk).exists(): + return False + if workspace_id is not None: + return request.user.basicuser.contributor.workspaces.filter(workspace_id=workspace_id).exists() + return True + +class WorkspacePostAPIView(APIView): + authentication_classes = (TokenAuthentication,) + permission_classes = (IsAuthenticated, IsContributorAndWorkspace) + + def post(self, request): + serializer = WorkspaceSerializer(data=request.data, context={'request': request}) + if serializer.is_valid(): + serializer.save() + return Response(serializer.data, status=201) + return Response( + serializer.errors, status=400 + ) + def search(request): search = request.GET.get("query") search_type = request.GET.get("type") diff --git a/project/backend/database/models.py b/project/backend/database/models.py index 3f39767f..55a3a2b8 100644 --- a/project/backend/database/models.py +++ b/project/backend/database/models.py @@ -51,7 +51,7 @@ def existing_search_results(cls, keyword): return existings def __str__(self): - return self.label + " - " + self.wid + return str(self.pk) + " " + self.label + " - " + self.wid class Entry(models.Model): entry_id = models.AutoField(primary_key=True) @@ -72,6 +72,7 @@ def set_as_theorem(self): self.is_theorem_entry = True def set_entry_content(self,cont): self.content = cont + # Create your models here. class Workspace(models.Model): #Node and Review Requests may be added later workspace_id = models.AutoField(primary_key=True) @@ -112,7 +113,7 @@ def __str__(self): class Contributor(BasicUser): - workspaces = models.ManyToManyField(Workspace) + workspaces = models.ManyToManyField(Workspace, blank=True) def __str__(self): return self.user.first_name + " " + self.user.last_name diff --git a/project/backend/database/serializers.py b/project/backend/database/serializers.py index a882e220..92c64e2a 100644 --- a/project/backend/database/serializers.py +++ b/project/backend/database/serializers.py @@ -7,6 +7,67 @@ from .models import * +class WorkspaceSerializer(serializers.ModelSerializer): + semantic_tags = serializers.PrimaryKeyRelatedField(many=True, queryset=SemanticTag.objects.all(), required=False) + workspace_id = serializers.IntegerField(required=False) + workspace_title = serializers.CharField(required=False) + + class Meta: + model = Workspace + fields = [ + 'workspace_id', + 'workspace_title', + 'semantic_tags' + ] + + def validate(self, data): + workspace_id = data.get('workspace_id') + workspace_title = data.get('workspace_title') + tags = data.get('semantic_tags') + + if workspace_id is None and workspace_title is None: + raise serializers.ValidationError("Both workspace_id and workspace_title cannot be empty.") + + if tags is None and workspace_title is None: + raise serializers.ValidationError("Both workspace_title and semantic_tags cannot be empty.") + + return data + + def create(self, validated_data): + workspace_id = validated_data.get('workspace_id', None) + title = validated_data.get('workspace_title', None) + + if workspace_id is not None: + workspace = Workspace.objects.get(workspace_id=workspace_id) + created = False + else: + workspace = Workspace.objects.create(workspace_title=title) + created = True + + if created: + self.context['request'].user.basicuser.contributor.workspaces.add(workspace) + tags = validated_data.get('semantic_tags', None) + if tags is not None: + workspace.semantic_tags.add(*tags) + + else: + if title: + workspace.workspace_title = title + workspace.save() + + tags = validated_data.get('semantic_tags', None) + if tags is not None: + for tag in workspace.semantic_tags.all(): + if tag not in tags: + workspace.semantic_tags.remove(tag) + + for tag in tags: + if tag not in workspace.semantic_tags.all(): + workspace.semantic_tags.add(tag) + + return workspace + + # Serializer to change password class ChangePasswordSerializer(serializers.ModelSerializer): old_password = serializers.CharField(write_only=True, required=True) From 16e97bd8a320cd83f549ce91411161d4b130bc24 Mon Sep 17 00:00:00 2001 From: Simurgan Date: Sat, 25 Nov 2023 22:05:32 +0300 Subject: [PATCH 5/5] implement unit tests of workspace post api --- project/backend/api/tests.py | 89 +++++++++++++++++++++++++++++++++++- 1 file changed, 87 insertions(+), 2 deletions(-) diff --git a/project/backend/api/tests.py b/project/backend/api/tests.py index a1e61861..d9c78a1d 100644 --- a/project/backend/api/tests.py +++ b/project/backend/api/tests.py @@ -7,8 +7,95 @@ from database.serializers import RegisterSerializer, UserSerializer from database.models import * import datetime + # Create your tests here for each class or API call. +class WorkspacePOSTAPITestCase(TestCase): + def setUp(self): + self.client = APIClient() + + self.user_for_basic = User.objects.create_user(id=1, email= 'basic_user@example.com', username='basic_user@example.com', first_name='Basic User', last_name='Test1') + self.user_for_contributor1 = User.objects.create_user(id=2, email= 'cont1@example.com', username='cont1@example.com', first_name='Contributor User 2', last_name='Test2') + self.user_for_contributor2 = User.objects.create_user(id=3, email= 'cont2@example.com', username='cont2@example.com', first_name='Contributor User 3', last_name='Test3') + + self.basic_user = BasicUser.objects.create(user=self.user_for_basic, bio="I am a basic user") + self.contributor1 = Contributor.objects.create(user=self.user_for_contributor1, bio="I am the first contributor") + self.contributor2 = Contributor.objects.create(user=self.user_for_contributor2, bio="I am the second contributor") + + self.basic_user_token = Token.objects.create(user=self.user_for_basic) + self.contributor1_token = Token.objects.create(user=self.user_for_contributor1) + self.contributor2_token = Token.objects.create(user=self.user_for_contributor2) + + self.semantic_tag1 = SemanticTag.objects.create(wid="Q1", label="Semantic Tag 1") + self.semantic_tag2 = SemanticTag.objects.create(wid="Q2", label="Semantic Tag 2") + + def tearDown(self): + User.objects.all().delete() + BasicUser.objects.all().delete() + Contributor.objects.all().delete() + Token.objects.all().delete() + Workspace.objects.all().delete() + SemanticTag.objects.all().delete() + + print("All tests for the Workspace POST API are completed!") + + def test_create_workspace(self): + # Testing the POST method for basic user tries to create workspace + self.client.credentials(HTTP_AUTHORIZATION=f"Token {self.basic_user_token.key}") + data = { + "workspace_title": "Basic User Workspace", + "semantic_tags": [self.semantic_tag1.pk] + } + + response = self.client.post(reverse("workspace_post"), data, format="json") + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN, "Test failed: Basic user shouldnot be able to create a workspace") + + # Testing the POST method for creating without title + self.client.credentials(HTTP_AUTHORIZATION=f"Token {self.contributor1_token.key}") + + data = { + "semantic_tags": [self.semantic_tag1.pk] + } + response = self.client.post(reverse("workspace_post"), data, format="json") + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST, "Test failed: Workspace cannot be created without a title") + + # Testing the POST method for creating without semantic tags + data = { + "workspace_title": "Contributor1 Workspace" + } + response = self.client.post(reverse("workspace_post"), data, format="json") + self.assertEqual(response.status_code, status.HTTP_201_CREATED, "Test failed: Workspace can be created without semantic tags") + + workspaces = self.contributor1.workspaces.all() + self.assertEqual(workspaces.count(), 1, "Test failed: Workspace could not be created") + + # Testing the POST method for updating workspace + if workspaces.count() > 0: + workspace = workspaces[0] + + data = { + "workspace_id": workspace.workspace_id, + "workspace_title": "Contributor1 Workspace Updated", + "semantic_tags": [self.semantic_tag2.pk] + } + response = self.client.post(reverse("workspace_post"), data, format="json") + + workspace = Workspace.objects.get(workspace_id=workspace.workspace_id) + self.assertEqual(response.status_code, status.HTTP_201_CREATED, "Update failure") + self.assertEqual(workspace.semantic_tags.count(), 1, "Update failure for semantic tags count") + self.assertEqual(workspace.semantic_tags.all()[0].wid, self.semantic_tag2.wid, "Update failure for semantic tag") + self.assertEqual(workspace.workspace_title, "Contributor1 Workspace Updated", "Update failure for title") + + # Try to update workspace of a different contributor + self.client.credentials(HTTP_AUTHORIZATION=f"Token {self.contributor2_token.key}") + data = { + "workspace_id": workspace.workspace_id, + "workspace_title": "Contributor2 Workspace Updated", + "semantic_tags": [self.semantic_tag1.pk] + } + response = self.client.post(reverse("workspace_post"), data, format="json") + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN, "Test failed: Contributor2 shouldnot be able to update Contributor1's workspace") + class SignUpAPIViewTestCase(TestCase): def setUp(self): @@ -458,7 +545,6 @@ def setUp(self): def test_get_workspaces_of_user(self): response = self.client.get(self.url, {'user_id': self.cont.id}) - print(response) self.assertEqual(response.status_code, 200) self.assertEqual(response.json()['workspaces'][0]['workspace_id'],self.workspace.workspace_id) @@ -478,7 +564,6 @@ def setUp(self): def test_get_workspace_from_id(self): response = self.client.get(self.url, {'workspace_id': self.workspace.workspace_id}) - print(response) self.assertEqual(response.status_code, 200) self.assertEqual(response.json()['workspace_id'],self.workspace.workspace_id) self.assertEqual(response.json()['workspace_id'], self.workspace.workspace_id)