Skip to content
This repository was archived by the owner on Mar 23, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 0 additions & 18 deletions authentication/migrations/0002_user_profile_image.py

This file was deleted.

This file was deleted.

16 changes: 16 additions & 0 deletions authentication/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
from .utils import send_otp_email
from FD import settings

from notifications.consumers import NotificationConsumer


class UserService:
VALID_LEVELS = ['A1', 'A2', 'B1', 'B2', 'C1', 'C2', 'a1', 'a2', 'b1', 'b2', 'c1', 'c2']
Expand Down Expand Up @@ -180,5 +182,19 @@ def confirm_reset_password(uidb64, token, new_password):
user.save()

return user

@classmethod
def delete_account(cls, user):
for group in user.owned_groups.all():
for member in group.members.all():
NotificationConsumer.send_notification(member, f"{group.title} has been deleted")
group.delete()

if user.profile_image:
cls.delete_s3_object(user.profile_image.name)

user.delete()




35 changes: 26 additions & 9 deletions authentication/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from rest_framework.test import APIClient
from rest_framework import status
from authentication.models import User
from groups.models import Group

class AuthenticationAPITests(TestCase):

Expand Down Expand Up @@ -39,19 +40,35 @@ def test_retrieve_user(self):
self.assertEqual(response.data['username'], 'testuser')
self.assertEqual(response.data['email'], 'testuser@example.com')

def test_delete_user(self):
url = reverse('user-delete')
data = {'password': 'testpassword'}
response = self.client.delete(url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data, "user deleted successfully")
self.assertFalse(User.objects.filter(username='testuser').exists())

def test_update_user(self):
url = reverse('user-update')
data = {'username': 'newuser'}
response = self.client.patch(url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data, "user updated successfully")
self.user.refresh_from_db()
self.assertEqual(self.user.username, 'newuser')
self.assertEqual(self.user.username, 'newuser')

def test_delete_account(self):
test_group = Group.objects.create(title='testgroup', owner=self.user)
other_user = User.objects.create_user(
username='otheruser',
email='otheruser@example.com',
password='otherpassword'
)

test_group.add_member(other_user)

url = reverse('delete-account')
response = self.client.delete(url)


self.assertEqual(response.data, "account deleted successfully")
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(other_user.groups.count(), 0)
test_group.delete()
other_user.delete()

def cleanup(self):
self.user.delete()

2 changes: 1 addition & 1 deletion authentication/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
path('change-password/', ChangePasswordView.as_view(), name='change-password'),

path('users/retrieve/', UserRetriveView.as_view(), name='user-retrieve'),
path('users/delete/', UserDeleteView.as_view(), name='user-delete'),
path('users/delete/', DeleteAccountView.as_view(), name='delete-account'),
path('users/update/', UserUpdateView.as_view(), name='user-update'),

path('token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
Expand Down
34 changes: 13 additions & 21 deletions authentication/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,27 +98,7 @@ def get(self, request):

serializer = self.serializer_class(user)

return Response(serializer.data, status=status.HTTP_200_OK)


class UserDeleteView(APIView):
permission_classes = [IsAuthenticated]
serializer_class= UserDeleteSerializer

@silk_profile(name='user-delete')
def delete(self, request):

user = request.user
serializer = self.serializer_class(data = request.data)

serializer.is_valid(raise_exception=True)

if not user.check_password(serializer.validated_data.get('password')):
return Response("invalid password", status=status.HTTP_400_BAD_REQUEST)

user.delete()
return Response("user deleted successfully", status=status.HTTP_200_OK)

return Response(serializer.data, status=status.HTTP_200_OK)

class UserUpdateView(APIView):
permission_classes = [IsAuthenticated]
Expand Down Expand Up @@ -158,3 +138,15 @@ def patch(self, request):
return Response(e.detail.get('detail'), status=e.detail.get('status'))

return Response("password changed successfully", status=status.HTTP_200_OK)


class DeleteAccountView(APIView):
permission_classes = [IsAuthenticated]

@silk_profile(name='delete-account')
def delete(self, request):
try:
UserService.delete_account(request.user)
return Response("account deleted successfully", status=status.HTTP_200_OK)
except:
return Response("account not deleted", status=status.HTTP_500_INTERNAL_SERVER_ERROR)
9 changes: 7 additions & 2 deletions groups/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,16 @@ def update_group(title, data):

group.save()

@staticmethod
def delete_group(title):
@classmethod
def delete_group(cls, title):
if not Group.objects.filter(title=title).exists():
raise ValidationError({'detail': 'Group not found', 'status': status.HTTP_404_NOT_FOUND})
group = Group.objects.get(title=title)
for member in group.members.all():
NotificationConsumer.send_notification(member, f"{group.title} has been deleted")
if group.image:
cls.delete_s3_object(group.image.name)

group.delete()

@staticmethod
Expand Down
22 changes: 21 additions & 1 deletion groups/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def test_retrieve_group_api(self):
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data['title'], group.title)
group.delete()

def test_update_group_api(self):
group = GroupService.create_group(self.user, self.group_data)
Expand All @@ -56,11 +57,13 @@ def test_update_group_api(self):
group.refresh_from_db()
self.assertEqual(group.description, "Updated description")
self.assertEqual(group.level, "B1")
group.delete()

def test_delete_group_api(self):
group = GroupService.create_group(self.user, self.group_data)
url = reverse('delete-group', kwargs={'title': group.title})
response = self.client.delete(url)
self.assertEqual(self.user.groups.count(), 0)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(Group.objects.count(), 0)

Expand All @@ -87,6 +90,8 @@ def test_join_request_api(self):
response = self.client.post(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertTrue(group.pending_members.filter(username="other_user").exists())
other_user.delete()
group.delete()

def test_cancel_request_api(self):
group = GroupService.create_group(self.user, self.group_data)
Expand All @@ -103,6 +108,8 @@ def test_cancel_request_api(self):
response = self.client.post(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertFalse(group.pending_members.filter(username="other_user").exists())
other_user.delete()
group.delete()

def test_leave_group_api(self):
group = GroupService.create_group(self.user, self.group_data)
Expand All @@ -111,13 +118,15 @@ def test_leave_group_api(self):
response = self.client.post(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertFalse(group.members.filter(username=self.user.username).exists())
group.delete()

def test_member_list_api(self):
group = GroupService.create_group(self.user, self.group_data)
url = reverse('retrieve-members', kwargs={'title': group.title})
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data['count'], group.members.count())
group.delete()

def test_pending_member_list_api(self):
group = GroupService.create_group(self.user, self.group_data)
Expand All @@ -131,6 +140,8 @@ def test_pending_member_list_api(self):
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data['count'], group.pending_members.count())
other_user.delete()
group.delete()

def test_accept_request_api(self):
group = GroupService.create_group(self.user, self.group_data)
Expand All @@ -152,6 +163,8 @@ def test_accept_request_api(self):
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertTrue(group.members.filter(username="other_user").exists())
self.assertFalse(group.pending_members.filter(username="other_user").exists())
other_user.delete()
group.delete()

def test_decline_request_api(self):
group = GroupService.create_group(self.user, self.group_data)
Expand All @@ -171,6 +184,8 @@ def test_decline_request_api(self):
response = self.client.post(url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertFalse(group.pending_members.filter(username="other_user").exists())
other_user.delete()
group.delete()

def test_kick_member_api(self):
group = GroupService.create_group(self.user, self.group_data)
Expand All @@ -190,4 +205,9 @@ def test_kick_member_api(self):
url = reverse('kick-member', kwargs={'title': group.title})
response = self.client.post(url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertFalse(group.members.filter(username="other_user").exists())
self.assertFalse(group.members.filter(username="other_user").exists())
other_user.delete()
group.delete()

def cleanup(self):
self.user.delete()