launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #31920
[Merge] ~alvarocs/launchpad:fix-bug-summary-field into launchpad:master
Alvaro Crespo Serrano has proposed merging ~alvarocs/launchpad:fix-bug-summary-field into launchpad:master.
Commit message:
Add character limit to bug titles summary field.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~alvarocs/launchpad/+git/launchpad/+merge/477422
Fix for the bug reported in https://bugs.launchpad.net/launchpad/+bug/2086655. Launchpad did not have character limit for bug titles. This could make the send-bug-notifications get stuck and block bug notifications from being sent.
- Implemented a character limit of 200 for bug title "summary" field in class IBugView & class IBugAddForm for when adding or editing a bug.
- Validator checks in class FileBugViewBase.
- Corresponding unit tests.
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~alvarocs/launchpad:fix-bug-summary-field into launchpad:master.
diff --git a/lib/lp/bugs/browser/bugtarget.py b/lib/lp/bugs/browser/bugtarget.py
index cb8c16d..199309d 100644
--- a/lib/lp/bugs/browser/bugtarget.py
+++ b/lib/lp/bugs/browser/bugtarget.py
@@ -410,16 +410,32 @@ class FileBugViewBase(LaunchpadFormView):
# The comment field is only required if filing a new bug.
if self.submit_bug_action.submitted():
comment = data.get("comment")
+ title = data.get("title", "").strip()
# The widget only exposes the error message. The private
# attr contains the real error.
- widget_error = self.widgets.get("comment")._error
- if widget_error and isinstance(widget_error.errors, TooLong):
+ widget_error_title = self.widgets.get("title")._error
+ widget_error_comment = self.widgets.get("comment")._error
+ if widget_error_title and isinstance(
+ widget_error_title.errors, TooLong
+ ):
+ self.setFieldError(
+ "title",
+ "The summary is too long. Please, provide a one-line "
+ "summary of the problem.",
+ )
+ elif not title or widget_error_title is not None:
+ self.setFieldError(
+ "title", "Provide a one-line summary of the problem."
+ )
+ if widget_error_comment and isinstance(
+ widget_error_comment.errors, TooLong
+ ):
self.setFieldError(
"comment",
"The description is too long. If you have lots of "
"text to add, attach a file to the bug instead.",
)
- elif not comment or widget_error is not None:
+ elif not comment or widget_error_comment is not None:
self.setFieldError(
"comment", "Provide details about the issue."
)
diff --git a/lib/lp/bugs/browser/tests/test_bugtarget_filebug.py b/lib/lp/bugs/browser/tests/test_bugtarget_filebug.py
index d6f0013..769e610 100644
--- a/lib/lp/bugs/browser/tests/test_bugtarget_filebug.py
+++ b/lib/lp/bugs/browser/tests/test_bugtarget_filebug.py
@@ -8,7 +8,7 @@ from lazr.restful.interfaces import IJSONRequestCache
from testscenarios import WithScenarios, load_tests_apply_scenarios
from zope.component import getUtility
from zope.publisher.interfaces import NotFound
-from zope.schema.interfaces import TooLong, TooShort
+from zope.schema.interfaces import RequiredMissing, TooLong, TooShort
from zope.security.proxy import removeSecurityProxy
from lp.app.enums import PUBLIC_INFORMATION_TYPES, InformationType
@@ -338,6 +338,44 @@ class FileBugViewMixin:
class TestFileBugViewBase(FileBugViewMixin, TestCaseWithFactory):
layer = DatabaseFunctionalLayer
+ def test_submit_title_empty_error(self):
+ # The title cannot be an empty string.
+ form = self.get_form(title="")
+ view = self.create_initialized_view(form=form)
+ self.assertEqual(2, len(view.errors))
+ self.assertEqual(
+ "Provide a one-line summary of the problem.",
+ view.getFieldError("title"),
+ )
+
+ def test_submit_title_withespace_only_error(self):
+ # The title cannot be a whitespace only string.
+ form = self.get_form(title=" ")
+ view = self.create_initialized_view(form=form)
+ self.assertEqual(2, len(view.errors))
+ self.assertIsInstance(view.errors[0].errors, RequiredMissing)
+ self.assertEqual(
+ "Provide a one-line summary of the problem.", view.errors[1]
+ )
+
+ def test_submit_title_too_large_error(self):
+ # The title cannot exceed the max length of 200.
+ title = "x" * 201
+ form = self.get_form(title=title)
+ view = self.create_initialized_view(form=form)
+ self.assertEqual(2, len(view.errors))
+ self.assertIsInstance(view.errors[0].errors, TooLong)
+ message_start = "The summary is too long. Please, provide a "
+ "one-line summary of the problem."
+ self.assertTrue(view.getFieldError("title").startswith(message_start))
+
+ def test_submit_title_max(self):
+ # The title can be as large as 200.
+ form = self.get_form(title="x" * 200)
+ view = self.create_initialized_view(form=form)
+ self.assertEqual(0, len(view.errors))
+ self.assertTrue(view.added_bug is not None)
+
def test_submit_comment_empty_error(self):
# The comment cannot be an empty string.
form = self.get_form(comment="")
diff --git a/lib/lp/bugs/interfaces/bug.py b/lib/lp/bugs/interfaces/bug.py
index 0f31c6a..5135dee 100644
--- a/lib/lp/bugs/interfaces/bug.py
+++ b/lib/lp/bugs/interfaces/bug.py
@@ -224,6 +224,8 @@ class IBugView(Interface):
title=_("Summary"),
required=True,
description=_("""A one-line summary of the problem."""),
+ min_length=1,
+ max_length=200,
)
)
description = exported(
@@ -1437,7 +1439,9 @@ class IBugAddForm(IBug):
),
vocabulary="BinaryAndSourcePackageName",
)
- title = Title(title=_("Summary"), required=True)
+ title = Title(
+ title=_("Summary"), min_length=1, max_length=200, required=True
+ )
distribution = Choice(
title=_("Linux Distribution"),
required=True,
diff --git a/lib/lp/bugs/stories/guided-filebug/xx-product-guided-filebug.rst b/lib/lp/bugs/stories/guided-filebug/xx-product-guided-filebug.rst
index 2af51fd..d06f46c 100644
--- a/lib/lp/bugs/stories/guided-filebug/xx-product-guided-filebug.rst
+++ b/lib/lp/bugs/stories/guided-filebug/xx-product-guided-filebug.rst
@@ -71,7 +71,7 @@ will be displayed as well.
... print(message.decode_contents())
...
There is 1 error.
- Required input is missing.
+ Provide a one-line summary of the problem.
With both values set, the bug is created.
Follow ups