Merge lp:~adeuring/launchpad/bug-532078 into lp:launchpad/db-devel

Proposed by Abel Deuring
Status: Merged
Approved by: Graham Binns
Approved revision: no longer in the source branch.
Merged at revision: not available
Proposed branch: lp:~adeuring/launchpad/bug-532078
Merge into: lp:launchpad/db-devel
Diff against target: 128 lines (+104/-2)
2 files modified
lib/lp/bugs/browser/bugtask.py (+2/-2)
lib/lp/bugs/browser/tests/test_bugtarget_patches_view.py (+102/-0)
To merge this branch: bzr merge lp:~adeuring/launchpad/bug-532078
Reviewer Review Type Date Requested Status
Graham Binns (community) code Approve
Review via email: mp+20727@code.launchpad.net

Description of the change

This branch fixes bug 532048: Count of bugs with patches is wrong, +patches shows different information

The cause is simple: While BugTarget.searchTasks() is used both by BugsStatsMixin.bugs_with_patches_count to retrive the number of bugs with patches and by BugsPatchesView.batchedPatchTasks() to retrieve the bugs to show, they pass different sets of bug tasks statuses to searchParams(): BugsStatsMixin.bugs_with_patches_count used all statused except UNKNOWN, while BugsPatchesView.batchedPatchTasks() excluded in addition WONTFIX and INVALID.

I added unit tests for BugsStatsMixin.bugs_with_patches_count and BugsPatchesView to ensure that they include the same sets of bugtasks.

test: ./bin/test -vv -t test_bugtarget_patches_view

= Launchpad lint =

Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.

Linting changed files:
  lib/lp/bugs/browser/bugtask.py
  lib/lp/bugs/browser/tests/test_bugtarget_patches_view.py

== Pylint notices ==

lib/lp/bugs/browser/bugtask.py
    78: [F0401] Unable to import 'lazr.delegates' (No module named delegates)
    79: [F0401] Unable to import 'lazr.enum' (No module named enum)
    81: [F0401] Unable to import 'lazr.lifecycle.event' (No module named lifecycle)
    82: [F0401] Unable to import 'lazr.lifecycle.snapshot' (No module named lifecycle)
    83: [F0401] Unable to import 'lazr.restful.interface' (No module named restful)
    84: [F0401] Unable to import 'lazr.restful.interfaces' (No module named restful)
    100: [F0401] Unable to import 'lazr.uri' (No module named uri)
    155: [F0401] Unable to import 'lazr.restful.interfaces' (No module named restful)

To post a comment you must log in.
Revision history for this message
Graham Binns (gmb) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/bugs/browser/bugtask.py'
2--- lib/lp/bugs/browser/bugtask.py 2010-03-01 11:28:05 +0000
3+++ lib/lp/bugs/browser/bugtask.py 2010-03-08 09:24:33 +0000
4@@ -114,7 +114,7 @@
5 INominationsReviewTableBatchNavigator, INullBugTask, IPersonBugTaskSearch,
6 IProductSeriesBugTask, IRemoveQuestionFromBugTaskForm, IUpstreamBugTask,
7 IUpstreamProductBugTaskSearch, UNRESOLVED_BUGTASK_STATUSES,
8- RESOLVED_BUGTASK_STATUSES)
9+ UNRESOLVED_PLUS_FIXRELEASED_BUGTASK_STATUSES)
10 from lp.bugs.interfaces.bugtracker import BugTrackerType
11 from lp.bugs.interfaces.cve import ICveSet
12 from lp.registry.interfaces.distribution import IDistribution
13@@ -1886,7 +1886,7 @@
14 """A count of unresolved bugs with patches."""
15 return self.context.searchTasks(
16 None, user=self.user,
17- status=(UNRESOLVED_BUGTASK_STATUSES + RESOLVED_BUGTASK_STATUSES),
18+ status=UNRESOLVED_PLUS_FIXRELEASED_BUGTASK_STATUSES,
19 omit_duplicates=True, has_patch=True).count()
20
21
22
23=== added file 'lib/lp/bugs/browser/tests/test_bugtarget_patches_view.py'
24--- lib/lp/bugs/browser/tests/test_bugtarget_patches_view.py 1970-01-01 00:00:00 +0000
25+++ lib/lp/bugs/browser/tests/test_bugtarget_patches_view.py 2010-03-08 09:24:33 +0000
26@@ -0,0 +1,102 @@
27+# Copyright 2010 Canonical Ltd. This software is licensed under the
28+# GNU Affero General Public License version 3 (see the file LICENSE).
29+
30+__metaclass__ = type
31+
32+
33+import unittest
34+
35+from canonical.launchpad.ftests import login
36+from canonical.launchpad.webapp.servers import LaunchpadTestRequest
37+from canonical.testing import LaunchpadFunctionalLayer
38+
39+from lp.bugs.browser.bugtarget import BugsPatchesView
40+from lp.bugs.browser.bugtask import BugListingPortletStatsView
41+from lp.bugs.interfaces.bugtask import BugTaskStatus
42+from lp.testing import TestCaseWithFactory
43+
44+
45+DISPLAY_BUG_STATUS_FOR_PATCHES = {
46+ BugTaskStatus.NEW: True,
47+ BugTaskStatus.INCOMPLETE: True,
48+ BugTaskStatus.INVALID: False,
49+ BugTaskStatus.WONTFIX: False,
50+ BugTaskStatus.CONFIRMED: True,
51+ BugTaskStatus.TRIAGED: True,
52+ BugTaskStatus.INPROGRESS: True,
53+ BugTaskStatus.FIXCOMMITTED: True,
54+ BugTaskStatus.FIXRELEASED: True,
55+ BugTaskStatus.UNKNOWN: False,
56+ }
57+
58+
59+class TestBugTargetPatchCountBase(TestCaseWithFactory):
60+
61+ layer = LaunchpadFunctionalLayer
62+
63+ def setUp(self):
64+ super(TestBugTargetPatchCountBase, self).setUp()
65+ login('foo.bar@canonical.com')
66+ self.product = self.factory.makeProduct()
67+
68+ def makeBugWithPatch(self, status):
69+ bug = self.factory.makeBug(
70+ product=self.product, owner=self.product.owner)
71+ self.factory.makeBugAttachment(bug=bug, is_patch=True)
72+ bug.default_bugtask.transitionToStatus(status, user=bug.owner)
73+
74+
75+class TestBugTargetPatchView(TestBugTargetPatchCountBase):
76+
77+ def setUp(self):
78+ super(TestBugTargetPatchView, self).setUp()
79+ self.view = BugsPatchesView(self.product, LaunchpadTestRequest())
80+
81+ def test_status_of_bugs_with_patches_shown(self):
82+ # Bugs with patches that have the status INVALID, WONTFIX,
83+ # UNKNOWN are not shown in the +patches view; all other
84+ # bugs are shown.
85+ number_of_bugs_shown = 0
86+ for bugtask_status in DISPLAY_BUG_STATUS_FOR_PATCHES:
87+ if DISPLAY_BUG_STATUS_FOR_PATCHES[bugtask_status]:
88+ number_of_bugs_shown += 1
89+ self.makeBugWithPatch(bugtask_status)
90+ batched_tasks = self.view.batchedPatchTasks()
91+ self.assertEqual(
92+ batched_tasks.batch.listlength, number_of_bugs_shown,
93+ "Unexpected number of bugs with patches displayed for status "
94+ "%s" % bugtask_status)
95+
96+
97+class TestBugListingPortletStatsView(TestBugTargetPatchCountBase):
98+
99+ def setUp(self):
100+ super(TestBugListingPortletStatsView, self).setUp()
101+ self.view = BugListingPortletStatsView(
102+ self.product, LaunchpadTestRequest())
103+
104+ def test_bugs_with_patches_count(self):
105+ # Bugs with patches that have the status INVALID, WONTFIX,
106+ # UNKNOWN are not counted in
107+ # BugListingPortletStatsView.bugs_with_patches_count, bugs
108+ # with all other statuses are counted.
109+ number_of_bugs_shown = 0
110+ for bugtask_status in DISPLAY_BUG_STATUS_FOR_PATCHES:
111+ if DISPLAY_BUG_STATUS_FOR_PATCHES[bugtask_status]:
112+ number_of_bugs_shown += 1
113+ self.makeBugWithPatch(bugtask_status)
114+ self.assertEqual(
115+ self.view.bugs_with_patches_count, number_of_bugs_shown,
116+ "Unexpected number of bugs with patches displayed for status "
117+ "%s" % bugtask_status)
118+
119+
120+def test_suite():
121+ suite = unittest.TestSuite()
122+ suite.addTest(unittest.makeSuite(TestBugTargetPatchView))
123+ suite.addTest(unittest.makeSuite(TestBugListingPortletStatsView))
124+ return suite
125+
126+
127+if __name__ == '__main__':
128+ unittest.TextTestRunner().run(test_suite())

Subscribers

People subscribed via source and target branches

to status/vote changes: