launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #05573
[Merge] lp:~adeuring/launchpad/bug-sorting-3 into lp:launchpad
Abel Deuring has proposed merging lp:~adeuring/launchpad/bug-sorting-3 into lp:launchpad with lp:~adeuring/launchpad/bug-sorting-2 as a prerequisite.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~adeuring/launchpad/bug-sorting-3/+merge/82562
This branch allows to sort bugtask search results by bug tag and by linked blueprint. (see https://dev.launchpad.net/LEP/CustomBugListings)
"we want sorting by tag or blueprint" is a somewhat vague request: A bug may have more than one blueprint or more than one tag -- what exactly should we choose then for sorting? By all tags/blueprints, or just one?
After discussions with the Orange team I opted to sort by that tag/blueprint for a given bug that comes alpabetically first.
Joining the tables BugTag/Specification needs a somewhat convoluted ON clause to avoid that more than one column appears in the result set for one bugtask. It seems to me that expressing this condition as a raw SQL subquery seems is better readable than an equivalent Storm expression.
tests:
./bin/test bugs -vvt lp.bugs.tests.test_bugtask_search..*test_sort_by_linked_specification
./bin/test bugs -vvt lp.bugs.tests.test_bugtask_search..*test_sort_by_tag
no lint
--
https://code.launchpad.net/~adeuring/launchpad/bug-sorting-3/+merge/82562
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~adeuring/launchpad/bug-sorting-3 into lp:launchpad.
=== modified file 'lib/lp/bugs/model/bugtask.py'
--- lib/lp/bugs/model/bugtask.py 2011-11-17 16:55:35 +0000
+++ lib/lp/bugs/model/bugtask.py 2011-11-17 16:55:38 +0000
@@ -162,6 +162,7 @@
from lp.services import features
from lp.services.propertycache import get_property_cache
from lp.soyuz.enums import PackagePublishingStatus
+from lp.blueprints.model.specification import Specification
debbugsseveritymap = {
@@ -3163,7 +3164,10 @@
"""See `IBugTaskSet`."""
if BugTaskSet._ORDERBY_COLUMN is None:
# Avoid circular imports.
- from lp.bugs.model.bug import Bug
+ from lp.bugs.model.bug import (
+ Bug,
+ BugTag,
+ )
from lp.registry.model.milestone import Milestone
from lp.registry.model.person import Person
Assignee = ClassAlias(Person)
@@ -3205,6 +3209,44 @@
(Bug, Join(Bug, BugTask.bug == Bug.id)),
(Reporter, Join(Reporter, Bug.owner == Reporter.id))
]),
+ "tag": (
+ BugTag.tag,
+ [
+ (Bug, Join(Bug, BugTask.bug == Bug.id)),
+ (BugTag,
+ LeftJoin(
+ BugTag,
+ BugTag.bug == Bug.id and
+ # We want at most one tag per bug. Select the
+ # tag that comes first in alphabetic order.
+ BugTag.id == SQL("""
+ SELECT id FROM BugTag AS bt
+ WHERE bt.bug=bug.id ORDER BY bt.name LIMIT 1
+ """))),
+ ]
+ ),
+ "specification": (
+ Specification.name,
+ [
+ (Bug, Join(Bug, BugTask.bug == Bug.id)),
+ (Specification,
+ LeftJoin(
+ Specification,
+ # We want at most one specification per bug.
+ # Select the specification that comes first
+ # in alphabetic order.
+ Specification.id == SQL("""
+ SELECT Specification.id
+ FROM SpecificationBug
+ JOIN Specification
+ ON SpecificationBug.specification=
+ Specification.id
+ WHERE SpecificationBug.bug=Bug.id
+ ORDER BY Specification.name
+ LIMIT 1
+ """))),
+ ]
+ ),
}
return BugTaskSet._ORDERBY_COLUMN[col_name]
=== modified file 'lib/lp/bugs/tests/test_bugtask_search.py'
--- lib/lp/bugs/tests/test_bugtask_search.py 2011-11-17 16:55:35 +0000
+++ lib/lp/bugs/tests/test_bugtask_search.py 2011-11-17 16:55:38 +0000
@@ -639,6 +639,37 @@
params = self.getBugTaskSearchParams(user=None, orderby='-title')
self.assertSearchFinds(params, expected)
+ def test_sort_by_tag(self):
+ with person_logged_in(self.owner):
+ self.bugtasks[2].bug.tags = ['tag-a', 'tag-d']
+ self.bugtasks[1].bug.tags = ['tag-b', 'tag-c']
+ params = self.getBugTaskSearchParams(user=None, orderby='tag')
+ expected = [self.bugtasks[2], self.bugtasks[1], self.bugtasks[0]]
+ self.assertSearchFinds(params, expected)
+ expected.reverse()
+ params = self.getBugTaskSearchParams(user=None, orderby='-tag')
+ self.assertSearchFinds(params, expected)
+
+ def test_sort_by_linked_specification(self):
+ with person_logged_in(self.owner):
+ spec_1 = self.factory.makeSpecification(
+ name='spec-1', owner=self.owner)
+ spec_1.linkBug(self.bugtasks[2].bug)
+ spec_1_1 = self.factory.makeSpecification(
+ name='spec-1-1', owner=self.owner)
+ spec_1_1.linkBug(self.bugtasks[2].bug)
+ spec_2 = self.factory.makeSpecification(
+ name='spec-2', owner=self.owner)
+ spec_2.linkBug(self.bugtasks[1].bug)
+ params = self.getBugTaskSearchParams(
+ user=None, orderby='specification')
+ expected = [self.bugtasks[2], self.bugtasks[1], self.bugtasks[0]]
+ self.assertSearchFinds(params, expected)
+ expected.reverse()
+ params = self.getBugTaskSearchParams(
+ user=None, orderby='-specification')
+ self.assertSearchFinds(params, expected)
+
class DeactivatedProductBugTaskTestCase(TestCaseWithFactory):