Coverage for src/wishlists/views.py: 40%

50 statements  

« prev     ^ index     » next       coverage.py v7.9.2, created at 2025-08-04 12:59 +0300

1from django.contrib.contenttypes.models import ContentType 

2 

3from rest_framework import viewsets, status 

4from rest_framework.decorators import action 

5from rest_framework.response import Response 

6from rest_framework.exceptions import ValidationError 

7 

8from src.wishlists.models import Wishlist 

9from src.wishlists.serializers import WishlistSerializer 

10from src.wishlists.services import WishlistService 

11from src.wishlists.constants import WishlistErrorMessages 

12 

13 

14class WishlistViewSet(viewsets.ModelViewSet): 

15 

16 # Use WishlistSerializer for data serialization 

17 serializer_class = WishlistSerializer 

18 

19 def get_queryset(self): 

20 try: 

21 # Get user identification filters 

22 user_filters = WishlistService.get_user_identifier(self.request) 

23 

24 # Filter wishlist items by user and optimize with select_related 

25 return Wishlist.objects.filter(**user_filters).select_related( 

26 'content_type', 

27 'user', 

28 ) 

29 except ValidationError: 

30 # Return empty queryset if user identification fails 

31 return Wishlist.objects.none() 

32 

33 def create(self, request, *args, **kwargs): 

34 """ 

35 This method adds a new item to the user's wishlist after validating 

36 the request data and ensuring the item doesn't already exist. 

37 """ 

38 try: 

39 # Get user identification filters 

40 user_filters = WishlistService.get_user_identifier(request) 

41 

42 # Validate request data 

43 serializer = self.get_serializer(data=request.data) 

44 serializer.is_valid(raise_exception=True) 

45 

46 # Extract validated data 

47 content_type = serializer.validated_data['content_type'] 

48 object_id = serializer.validated_data['object_id'] 

49 

50 # Create wishlist item using service 

51 wishlist_item = WishlistService.create_wishlist_item( 

52 user_filters, content_type, object_id 

53 ) 

54 

55 # Serialize and return response 

56 response_serializer = self.get_serializer(wishlist_item) 

57 return Response( 

58 response_serializer.data, 

59 status=status.HTTP_201_CREATED, 

60 ) 

61 except ValidationError as e: 

62 # Return validation error details 

63 return Response( 

64 e.detail, 

65 status=status.HTTP_400_BAD_REQUEST, 

66 ) 

67 

68 @action( 

69 detail=False, 

70 methods=['delete'], 

71 url_path='remove/(?P<content_type_name>[^/.]+)/(?P<object_id>[^/.]+)', 

72 ) 

73 def remove_item(self, request, content_type_name=None, object_id=None): 

74 """ 

75 This custom action removes a specific wishlist item based on 

76 content type name and object ID. It validates the parameters 

77 and handles various error cases. 

78 """ 

79 try: 

80 # Get user identification filters 

81 user_filters = WishlistService.get_user_identifier(request) 

82 

83 try: 

84 # Convert content_type_name to ContentType object 

85 content_type = ContentType.objects.get(model=content_type_name) 

86 

87 # Convert object_id string to integer 

88 object_id_int = int(object_id) if object_id is not None else 0 

89 except (ContentType.DoesNotExist, ValueError): 

90 # Handle invalid content type or object ID 

91 return Response( 

92 { 

93 'detail': WishlistErrorMessages.ERROR_INVALID_CONTENT_TYPE_OR_ID 

94 }, 

95 status=status.HTTP_400_BAD_REQUEST, 

96 ) 

97 

98 # Delete the wishlist item using service 

99 WishlistService.delete_wishlist_item( 

100 user_filters, content_type, object_id_int 

101 ) 

102 

103 # Return success response with no content 

104 return Response(status=status.HTTP_204_NO_CONTENT) 

105 

106 except ValidationError as e: 

107 # Return validation error details 

108 return Response( 

109 e.detail, 

110 status=status.HTTP_400_BAD_REQUEST, 

111 ) 

112 

113 @action(detail=False, methods=['get'], url_path='count') 

114 def get_wishlist_count(self, request): 

115 """ 

116 This custom action returns the number of items in the user's 

117 wishlist, useful for displaying wishlist count in the UI. 

118 """ 

119 try: 

120 # Get user identification filters 

121 user_filters = WishlistService.get_user_identifier(request) 

122 

123 # Count wishlist items for the user 

124 count = Wishlist.objects.filter(**user_filters).count() 

125 

126 # Return count in response 

127 return Response( 

128 {'count': count}, 

129 status=status.HTTP_200_OK, 

130 ) 

131 

132 except ValidationError as e: 

133 # Return validation error details 

134 return Response( 

135 e.detail, 

136 status=status.HTTP_400_BAD_REQUEST, 

137 )