Skip to content
Open
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
13 changes: 10 additions & 3 deletions apps/api/plane/api/views/intake.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@ def get(self, request, slug, project_id):
return self.paginate(
request=request,
queryset=(issue_queryset),
on_results=lambda intake_issues: IntakeIssueSerializer(
intake_issues, many=True, fields=self.fields, expand=self.expand
).data,
on_results=lambda intake_issues: (
IntakeIssueSerializer(intake_issues, many=True, fields=self.fields, expand=self.expand).data
),
)

@intake_docs(
Expand Down Expand Up @@ -149,6 +149,13 @@ def post(self, request, slug, project_id):
if not request.data.get("issue", {}).get("name", False):
return Response({"error": "Name is required"}, status=status.HTTP_400_BAD_REQUEST)

name_max_length = Issue._meta.get_field("name").max_length
if len(str(request.data["issue"]["name"])) > name_max_length:
return Response(
{"error": f"Name must be at most {name_max_length} characters"},
status=status.HTTP_400_BAD_REQUEST,
)

intake = Intake.objects.filter(workspace__slug=slug, project_id=project_id).first()

project = Project.objects.get(workspace__slug=slug, pk=project_id)
Expand Down
46 changes: 46 additions & 0 deletions apps/api/plane/tests/contract/api/test_intake_name_length.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Copyright (c) 2023-present Plane Software, Inc. and contributors
# SPDX-License-Identifier: AGPL-3.0-only
# See the LICENSE file for details.

"""POST /api/v1/.../intake-issues/ with an over-long name.

The name went straight into ``Issue.objects.create`` and Postgres raised
``DataError: value too long for type character varying(255)`` (HTTP 500).
"""

from unittest import mock

import pytest
from rest_framework import status

from plane.db.models import Intake, Issue, Project, ProjectMember


@pytest.fixture
def project(db, workspace, create_user):
project = Project.objects.create(name="P", identifier="P", workspace=workspace, created_by=create_user)
ProjectMember.objects.create(project=project, member=create_user, role=20, is_active=True)
Intake.objects.create(name="Intake", project=project, workspace=workspace)
return project


def url(workspace, project):
return f"/api/v1/workspaces/{workspace.slug}/projects/{project.id}/intake-issues/"


@pytest.mark.contract
@pytest.mark.django_db
def test_name_over_limit_is_400(api_key_client, workspace, project):
response = api_key_client.post(url(workspace, project), {"issue": {"name": "x" * 256}}, format="json")

assert response.status_code == status.HTTP_400_BAD_REQUEST
assert not Issue.objects.filter(project=project).exists()


@pytest.mark.contract
@pytest.mark.django_db
@mock.patch("plane.api.views.intake.issue_activity")
def test_name_at_limit_is_created(activity, api_key_client, workspace, project):
response = api_key_client.post(url(workspace, project), {"issue": {"name": "x" * 255}}, format="json")

assert response.status_code == status.HTTP_201_CREATED
Loading