Skip to content

Commit

Permalink
add can_delete to serializer
Browse files Browse the repository at this point in the history
  • Loading branch information
lastminutediorama committed Sep 1, 2024
1 parent e7efd3d commit beb6271
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 16 deletions.
12 changes: 12 additions & 0 deletions src/planscape/planning/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
ProjectAreaNotePermission,
)
from planning.models import PlanningArea, ProjectArea
from rest_framework.exceptions import ValidationError


class PlanningAreaViewPermission(PlanscapePermission):
Expand Down Expand Up @@ -55,6 +56,17 @@ def has_permission(self, request, view):
return False
project_area = ProjectArea.objects.get(id=project_area_id)
return ProjectAreaNotePermission.can_add(request.user, project_area)

case "list":
project_area_id = request.query_params.get("project_area_pk") or None
if not project_area_id:
raise ValidationError(f"Missing required project_area_pk")
project_area = ProjectArea.objects.select_related(
"scenario", "scenario__planning_area"
).get(id=project_area_id)
planning_area = project_area.scenario.planning_area
return PlanningAreaPermission.can_view(request.user, planning_area)

case _:
# TODO: review if this is necessary
return True
Expand Down
25 changes: 25 additions & 0 deletions src/planscape/planning/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -391,3 +391,28 @@ class Meta:
# "can_delete",
)
model = ProjectAreaNote


class ProjectAreaNoteListSerializer(serializers.ModelSerializer):
can_delete = serializers.SerializerMethodField()

def get_can_delete(self, obj):
user = self.context.get("user")
if user:
return (user == obj.user) or (
user == obj.project_area.scenario.planning_area.user
)
return False

class Meta:
fields = (
"id",
"created_at",
"updated_at",
"content",
"project_area",
"user_id",
"user_name",
"can_delete",
)
model = ProjectAreaNote
39 changes: 35 additions & 4 deletions src/planscape/planning/tests/test_v2_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -922,19 +922,19 @@ def test_create_note_without_permission(self):

def test_get_notes_for_project_area(self):
self.client.force_authenticate(self.user)
new_note1 = ProjectAreaNote.objects.create(
ProjectAreaNote.objects.create(
project_area=self.project_area, user=self.user, content="I am a note"
)
new_note2 = ProjectAreaNote.objects.create(
ProjectAreaNote.objects.create(
project_area=self.project_area, user=self.user, content="I am a second note"
)
new_note3 = ProjectAreaNote.objects.create(
ProjectAreaNote.objects.create(
project_area=self.project_area,
user=self.other_user,
content="I am a third note",
)
# creating a note for a separate project area, so it shouldnt be in results
new_note4 = ProjectAreaNote.objects.create(
ProjectAreaNote.objects.create(
project_area=self.other_project_area,
user=self.other_user,
content="I am a third note",
Expand All @@ -947,6 +947,37 @@ def test_get_notes_for_project_area(self):
response_data = response.json()
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response_data), 3)
for rec in response_data:
self.assertIn("can_delete", rec)

def test_get_notes_for_unauthorized_user(self):
self.client.force_authenticate(self.other_user)
ProjectAreaNote.objects.create(
project_area=self.project_area, user=self.user, content="I am a note"
)
ProjectAreaNote.objects.create(
project_area=self.project_area, user=self.user, content="I am a second note"
)
response = self.client.get(
reverse("api:planning:projectarea-notes-list"),
{"project_area_pk": self.project_area.pk},
content_type="application/json",
)
self.assertEqual(response.status_code, 403)

def test_get_notes_without_project_area(self):
self.client.force_authenticate(self.user)
ProjectAreaNote.objects.create(
project_area=self.project_area, user=self.user, content="I am a note"
)
ProjectAreaNote.objects.create(
project_area=self.project_area, user=self.user, content="I am a second note"
)
response = self.client.get(
reverse("api:planning:projectarea-notes-list"),
content_type="application/json",
)
self.assertEqual(response.status_code, 400)

def test_delete_note(self):
self.client.force_authenticate(self.user)
Expand Down
30 changes: 18 additions & 12 deletions src/planscape/planning/views_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
ListScenarioSerializer,
PlanningAreaSerializer,
ProjectAreaNoteSerializer,
ProjectAreaNoteListSerializer,
ProjectAreaSerializer,
ScenarioSerializer,
)
Expand Down Expand Up @@ -221,16 +222,21 @@ def create(self, request, *args, **kwargs):
headers=headers,
)

# TODO: get for projectarea using pk...
# ensure that user has projectarea / planningarea permission first
def get_queryset(self):
project_area_id = self.request.query_params.get("project_area_pk")
if project_area_id:
return (
super()
.get_queryset()
.filter(project_area_id=project_area_id)
.select_related("project_area__scenario__planning_area")
def list(self, request, *args, **kwargs):
# Get the project_area_pk from the request query parameters
project_area_pk = request.query_params.get("project_area_pk")

# If project_area_pk is provided, filter the queryset
if not project_area_pk:
return Response(
{"error": "projectarea.pk is a required attribute"},
status=status.HTTP_400_BAD_REQUEST,
)
else:
return super().get_queryset()
queryset = (
self.get_queryset()
.select_related("project_area__scenario__planning_area")
.filter(project_area__pk=project_area_pk)
)

serializer = ProjectAreaNoteListSerializer(queryset, many=True)
return Response(serializer.data)

0 comments on commit beb6271

Please sign in to comment.