Skip to content
Open
Show file tree
Hide file tree
Changes from 5 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
26 changes: 25 additions & 1 deletion care/emr/api/viewsets/favorites.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,19 @@ class EMRFavoritesMixin:
FAVORITE_RESOURCE = None

def retrieve_facility_obj(self, obj):
"""
Return the facility associated with the given object.
"""
return obj.facility

@action(detail=False, methods=["GET"])
def favorite_lists(self, request, *args, **kwargs):
"""
Return the list of favorite list names for the current user.

Ensures that on cache miss the computed favorite lists are returned
immediately instead of returning a null response.
"""
user = self.request.user

facility = kwargs.get("facility_external_id") or request.query_params.get(
Expand Down Expand Up @@ -56,10 +65,18 @@ def favorite_lists(self, request, *args, **kwargs):
favorite_lists_cache_key(user, self.FAVORITE_RESOURCE, facility),
favorite_list_obj,
)
favorite_lists = favorite_list_obj

return Response({"lists": favorite_lists})

@action(detail=True, methods=["POST"])
def add_favorite(self, request, *args, **kwargs):
"""
Add the current object to the user's favorite list.

Inserts the object at the beginning of the list, trims the list
to the maximum allowed size, and updates the cache accordingly.
"""
request_data = FavoriteRequest(**request.data)
favorite_list = request_data.favorite_list
obj = self.get_object()
Expand All @@ -71,7 +88,6 @@ def add_favorite(self, request, *args, **kwargs):
facility=self.retrieve_facility_obj(obj),
)
favorite_list_obj.favorites.insert(0, obj.id)
# trim favorites list to max allowed
favorite_list_obj.favorites = list(dict.fromkeys(favorite_list_obj.favorites))[
: settings.MAX_FAVORITES_PER_LIST
]
Expand All @@ -80,6 +96,12 @@ def add_favorite(self, request, *args, **kwargs):

@action(detail=True, methods=["POST"])
def remove_favorite(self, request, *args, **kwargs):
"""
Remove the current object from the user's favorite list.

Deletes the favorite list entirely when it becomes empty and
clears all related cache entries.
"""
request_data = FavoriteRequest(**request.data)
favorite_list = request_data.favorite_list
obj = self.get_object()
Expand All @@ -93,6 +115,7 @@ def remove_favorite(self, request, *args, **kwargs):
).first()
if not favorite_list_obj:
raise ValidationError("Favorite List not found")

favorite_list_obj_favorites = dict.fromkeys(favorite_list_obj.favorites)
favorite_list_obj_favorites.pop(obj.id, None)
if len(favorite_list_obj_favorites) == 0:
Expand All @@ -109,6 +132,7 @@ def remove_favorite(self, request, *args, **kwargs):
)
UserResourceFavorites.objects.filter(id=favorite_list_obj.id).delete()
return Response({})

favorite_list_obj.favorites = list(favorite_list_obj_favorites)
favorite_list_obj.save(update_fields=["favorites"])
return Response({})
10 changes: 10 additions & 0 deletions care/emr/tests/test_favorites_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,16 @@ def test_list_favorites_list(self):
"another_list",
)
)
def test_favorite_lists_returns_list_on_first_call(self):
# Ensure cache is empty
cache.delete(self.favorite_list_cache_key)

response = self.client.get(self.base_url + "favorite_lists/")

self.assertEqual(response.status_code, 200, response.content)
self.assertIn("lists", response.data)
self.assertIsNotNone(response.data["lists"])
self.assertIsInstance(response.data["lists"], list)

def test_list_ordered_by_favorites(self):
charge_item = self.create_charge_item_definition()
Expand Down
2 changes: 1 addition & 1 deletion care/users/api/viewsets/plug_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class PlugConfigViewset(
def list(self, request, *args, **kwargs):
# Cache data and return
response = cache.get(self.cache_key)
if not response:
if response is None: # cache miss; allow cached empty list
serializer = self.get_serializer(self.get_queryset(), many=True)
response = serializer.data
cache.set(self.cache_key, response)
Expand Down