launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #01801
[Merge] lp:~adeuring/launchpad/bug-594247-unittests-for-searchtasks-4 into lp:launchpad/devel
Abel Deuring has proposed merging lp:~adeuring/launchpad/bug-594247-unittests-for-searchtasks-4 into lp:launchpad/devel.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
new attempt, hopefully without merge conflict and an overly huge diff...
This branch adds more unit tests for BugTaskSet.search() and for
BugTaskSet.searchBugIds(), leaving only a few parameters of
BugTaskSearchParams not covered.
Aside for these additional tests, I added a new method
assertSearchFinds() (suggested by Gavin in a previous review
of these tests), which makes reading the tests slightly less
boring and a bit more readable. Working on this change, I
noticed that one tests missed an assert...
Working on tests to find bugs being created or modified after a
given time, I noticed that it was possible to pass the parameters
created_since and modified_since to the constructor of
BugTaskSearchparams, but that the object properties created_since
and modified_since were always set to None. This is now fixed.
One test needed access to a product which is not the main
target of the current test; an already existing test modifies
the bug task of this "other target"
(changeStatusOfBugTaskForOtherProduct()). I moved the code to find
this "other bugtask" into a separate method
(findBugtaskForOtherProduct()). The implementation is less obsucre
ini comparison with the old implementation to find the "other
bugtask".
test: ./bin/test -vvt test_bugtask_search
no lint.
--
https://code.launchpad.net/~adeuring/launchpad/bug-594247-unittests-for-searchtasks-4/+merge/39991
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~adeuring/launchpad/bug-594247-unittests-for-searchtasks-4 into lp:launchpad/devel.
=== modified file 'lib/lp/bugs/interfaces/bugtask.py'
--- lib/lp/bugs/interfaces/bugtask.py 2010-11-03 14:31:33 +0000
+++ lib/lp/bugs/interfaces/bugtask.py 2010-11-03 16:52:47 +0000
@@ -1188,8 +1188,8 @@
self.hardware_is_linked_to_bug = hardware_is_linked_to_bug
self.linked_branches = linked_branches
self.structural_subscriber = structural_subscriber
- self.modified_since = None
- self.created_since = None
+ self.modified_since = modified_since
+ self.created_since = created_since
def setProduct(self, product):
"""Set the upstream context on which to filter the search."""
=== modified file 'lib/lp/bugs/tests/test_bugtask_search.py'
--- lib/lp/bugs/tests/test_bugtask_search.py 2010-10-29 13:00:57 +0000
+++ lib/lp/bugs/tests/test_bugtask_search.py 2010-11-03 16:52:47 +0000
@@ -25,6 +25,7 @@
from lp.bugs.interfaces.bugattachment import BugAttachmentType
from lp.bugs.interfaces.bugtask import (
+ BugBranchSearch,
BugTaskImportance,
BugTaskSearchParams,
BugTaskStatus,
@@ -53,29 +54,30 @@
super(SearchTestBase, self).setUp()
self.bugtask_set = getUtility(IBugTaskSet)
+ def assertSearchFinds(self, params, expected_bugtasks):
+ # Run a search for the given search parameters and check if
+ # the result matches the expected bugtasks.
+ search_result = self.runSearch(params)
+ expected = self.resultValuesForBugtasks(expected_bugtasks)
+ self.assertEqual(expected, search_result)
+
def test_search_all_bugtasks_for_target(self):
# BugTaskSet.search() returns all bug tasks for a given bug
# target, if only the bug target is passed as a search parameter.
params = self.getBugTaskSearchParams(user=None)
- search_result = self.runSearch(params)
- expected = self.resultValuesForBugtasks(self.bugtasks)
- self.assertEqual(expected, search_result)
+ self.assertSearchFinds(params, self.bugtasks)
def test_private_bug_in_search_result(self):
# Private bugs are not included in search results for anonymous users.
with person_logged_in(self.owner):
self.bugtasks[-1].bug.setPrivate(True, self.owner)
params = self.getBugTaskSearchParams(user=None)
- search_result = self.runSearch(params)
- expected = self.resultValuesForBugtasks(self.bugtasks)[:-1]
- self.assertEqual(expected, search_result)
+ self.assertSearchFinds(params, self.bugtasks[:-1])
# Private bugs are not included in search results for ordinary users.
user = self.factory.makePerson()
params = self.getBugTaskSearchParams(user=user)
- search_result = self.runSearch(params)
- expected = self.resultValuesForBugtasks(self.bugtasks)[:-1]
- self.assertEqual(expected, search_result)
+ self.assertSearchFinds(params, self.bugtasks[:-1])
# If the user is subscribed to the bug, it is included in the
# search result.
@@ -83,16 +85,12 @@
with person_logged_in(self.owner):
self.bugtasks[-1].bug.subscribe(user, self.owner)
params = self.getBugTaskSearchParams(user=user)
- search_result = self.runSearch(params)
- expected = self.resultValuesForBugtasks(self.bugtasks)
- self.assertEqual(expected, search_result)
+ self.assertSearchFinds(params, self.bugtasks)
# Private bugs are included in search results for admins.
admin = getUtility(IPersonSet).getByEmail('foo.bar@xxxxxxxxxxxxx')
params = self.getBugTaskSearchParams(user=admin)
- search_result = self.runSearch(params)
- expected = self.resultValuesForBugtasks(self.bugtasks)
- self.assertEqual(expected, search_result)
+ self.assertSearchFinds(params, self.bugtasks)
def test_search_by_bug_reporter(self):
# Search results can be limited to bugs filed by a given person.
@@ -100,9 +98,7 @@
reporter = bugtask.bug.owner
params = self.getBugTaskSearchParams(
user=None, bug_reporter=reporter)
- search_result = self.runSearch(params)
- expected = self.resultValuesForBugtasks([bugtask])
- self.assertEqual(expected, search_result)
+ self.assertSearchFinds(params, [bugtask])
def test_search_by_bug_commenter(self):
# Search results can be limited to bugs having a comment from a
@@ -118,9 +114,7 @@
expected.bug.newMessage(owner=commenter, content='a comment')
params = self.getBugTaskSearchParams(
user=None, bug_commenter=commenter)
- search_result = self.runSearch(params)
- expected = self.resultValuesForBugtasks([expected])
- self.assertEqual(expected, search_result)
+ self.assertSearchFinds(params, [expected])
def test_search_by_person_affected_by_bug(self):
# Search results can be limited to bugs which affect a given person.
@@ -130,9 +124,7 @@
expected.bug.markUserAffected(affected_user)
params = self.getBugTaskSearchParams(
user=None, affected_user=affected_user)
- search_result = self.runSearch(params)
- expected = self.resultValuesForBugtasks([expected])
- self.assertEqual(expected, search_result)
+ self.assertSearchFinds(params, [expected])
def test_search_by_bugtask_assignee(self):
# Search results can be limited to bugtask assigned to a given
@@ -142,9 +134,7 @@
with person_logged_in(assignee):
expected.transitionToAssignee(assignee)
params = self.getBugTaskSearchParams(user=None, assignee=assignee)
- search_result = self.runSearch(params)
- expected = self.resultValuesForBugtasks([expected])
- self.assertEqual(expected, search_result)
+ self.assertSearchFinds(params, [expected])
def test_search_by_bug_subscriber(self):
# Search results can be limited to bugs to which a given person
@@ -154,9 +144,69 @@
with person_logged_in(subscriber):
expected.bug.subscribe(subscriber, subscribed_by=subscriber)
params = self.getBugTaskSearchParams(user=None, subscriber=subscriber)
- search_result = self.runSearch(params)
- expected = self.resultValuesForBugtasks([expected])
- self.assertEqual(expected, search_result)
+ self.assertSearchFinds(params, [expected])
+
+ def subscribeToTarget(self, subscriber):
+ # Subscribe the given person to the search target.
+ with person_logged_in(subscriber):
+ self.searchtarget.addSubscription(
+ subscriber, subscribed_by=subscriber)
+
+ def _findBugtaskForOtherProduct(self, bugtask, main_product):
+ # Return the bugtask for the product that not related to the
+ # main bug target.
+ #
+ # The default bugtasks of this test suite are created by
+ # ObjectFactory.makeBugTask() as follows:
+ # - a new bug is created having a new product as the target.
+ # - another bugtask is created for self.searchtarget (or,
+ # when self.searchtarget is a milestone, for the product
+ # of the milestone)
+ # This method returns the bug task for the product that is not
+ # related to the main bug target.
+ bug = bugtask.bug
+ for other_task in bug.bugtasks:
+ other_target = other_task.target
+ if (IProduct.providedBy(other_target)
+ and other_target != main_product):
+ return other_task
+ self.fail(
+ 'No bug task found for a product that is not the target of '
+ 'the main test bugtask.')
+
+ def findBugtaskForOtherProduct(self, bugtask):
+ # Return the bugtask for the product that not related to the
+ # main bug target.
+ #
+ # This method must ober overridden for product related tests.
+ return self._findBugtaskForOtherProduct(bugtask, None)
+
+ def test_search_by_structural_subscriber(self):
+ # Search results can be limited to bugs with a bug target to which
+ # a given person has a structural subscription.
+ subscriber = self.factory.makePerson()
+ # If the given person is not subscribed, no bugtasks are returned.
+ params = self.getBugTaskSearchParams(
+ user=None, structural_subscriber=subscriber)
+ self.assertSearchFinds(params, [])
+ # When the person is subscribed, all bugtasks are returned.
+ self.subscribeToTarget(subscriber)
+ params = self.getBugTaskSearchParams(
+ user=None, structural_subscriber=subscriber)
+ self.assertSearchFinds(params, self.bugtasks)
+
+ # Searching for a structural subscriber does not return a bugtask,
+ # if the person is subscribed to another target than the main
+ # bug target.
+ other_subscriber = self.factory.makePerson()
+ other_bugtask = self.findBugtaskForOtherProduct(self.bugtasks[0])
+ other_target = other_bugtask.target
+ with person_logged_in(other_subscriber):
+ other_target.addSubscription(
+ other_subscriber, subscribed_by=other_subscriber)
+ params = self.getBugTaskSearchParams(
+ user=None, structural_subscriber=other_subscriber)
+ self.assertSearchFinds(params, [])
def test_search_by_bug_attachment(self):
# Search results can be limited to bugs having attachments of
@@ -171,23 +221,17 @@
# We can search for bugs with non-patch attachments...
params = self.getBugTaskSearchParams(
user=None, attachmenttype=BugAttachmentType.UNSPECIFIED)
- search_result = self.runSearch(params)
- expected = self.resultValuesForBugtasks(self.bugtasks[:1])
- self.assertEqual(expected, search_result)
+ self.assertSearchFinds(params, self.bugtasks[:1])
# ... for bugs with patches...
params = self.getBugTaskSearchParams(
user=None, attachmenttype=BugAttachmentType.PATCH)
- search_result = self.runSearch(params)
- expected = self.resultValuesForBugtasks(self.bugtasks[1:2])
- self.assertEqual(expected, search_result)
+ self.assertSearchFinds(params, self.bugtasks[1:2])
# and for bugs with patches or attachments
params = self.getBugTaskSearchParams(
user=None, attachmenttype=any(
BugAttachmentType.PATCH,
BugAttachmentType.UNSPECIFIED))
- search_result = self.runSearch(params)
- expected = self.resultValuesForBugtasks(self.bugtasks[:2])
- self.assertEqual(expected, search_result)
+ self.assertSearchFinds(params, self.bugtasks[:2])
def setUpFullTextSearchTests(self):
# Set text fields indexed by Bug.fti, BugTask.fti or
@@ -205,40 +249,30 @@
self.setUpFullTextSearchTests()
params = self.getBugTaskSearchParams(
user=None, searchtext='one title')
- search_result = self.runSearch(params)
- expected = self.resultValuesForBugtasks(self.bugtasks[:1])
- self.assertEqual(expected, search_result)
+ self.assertSearchFinds(params, self.bugtasks[:1])
# ... by BugTask.fti ...
params = self.getBugTaskSearchParams(
user=None, searchtext='two explanation')
- search_result = self.runSearch(params)
- expected = self.resultValuesForBugtasks(self.bugtasks[1:2])
- self.assertEqual(expected, search_result)
+ self.assertSearchFinds(params, self.bugtasks[1:2])
# ...and by MessageChunk.fti
params = self.getBugTaskSearchParams(
user=None, searchtext='three comment')
- search_result = self.runSearch(params)
- expected = self.resultValuesForBugtasks(self.bugtasks[2:3])
- self.assertEqual(expected, search_result)
+ self.assertSearchFinds(params, self.bugtasks[2:3])
def test_fast_fulltext_search(self):
# Fast full text searches find text indexed by Bug.fti...
self.setUpFullTextSearchTests()
params = self.getBugTaskSearchParams(
user=None, fast_searchtext='one title')
- search_result = self.runSearch(params)
- expected = self.resultValuesForBugtasks(self.bugtasks[:1])
- self.assertEqual(expected, search_result)
+ self.assertSearchFinds(params, self.bugtasks[:1])
# ... but not text indexed by BugTask.fti ...
params = self.getBugTaskSearchParams(
user=None, fast_searchtext='two explanation')
- search_result = self.runSearch(params)
- self.assertEqual([], search_result)
+ self.assertSearchFinds(params, [])
# ..or by MessageChunk.fti
params = self.getBugTaskSearchParams(
user=None, fast_searchtext='three comment')
- search_result = self.runSearch(params)
- self.assertEqual([], search_result)
+ self.assertSearchFinds(params, [])
def test_has_no_upstream_bugtask(self):
# Search results can be limited to bugtasks of bugs that do
@@ -258,13 +292,13 @@
IDistributionSourcePackage.providedBy(self.searchtarget)):
if IDistribution.providedBy(self.searchtarget):
bug = self.factory.makeBug(distribution=self.searchtarget)
- expected = self.resultValuesForBugtasks([bug.default_bugtask])
+ expected = [bug.default_bugtask]
else:
bug = self.factory.makeBug(
distribution=self.searchtarget.distribution)
bugtask = self.factory.makeBugTask(
bug=bug, target=self.searchtarget)
- expected = self.resultValuesForBugtasks([bugtask])
+ expected = [bugtask]
else:
# Bugs without distribution related bugtasks have always at
# least one product related bugtask, hence a
@@ -273,23 +307,14 @@
expected = []
params = self.getBugTaskSearchParams(
user=None, has_no_upstream_bugtask=True)
- search_result = self.runSearch(params)
- self.assertEqual(expected, search_result)
+ self.assertSearchFinds(params, expected)
def changeStatusOfBugTaskForOtherProduct(self, bugtask, new_status):
# Change the status of another bugtask of the same bug to the
# given status.
- bug = bugtask.bug
- for other_task in bug.bugtasks:
- other_target = other_task.target
- if other_task != bugtask and IProduct.providedBy(other_target):
- with person_logged_in(other_target.owner):
- other_task.transitionToStatus(
- new_status, other_target.owner)
- return
- self.fail(
- 'No bug task found for a product that is not the target of '
- 'the main test bugtask.')
+ other_task = self.findBugtaskForOtherProduct(bugtask)
+ with person_logged_in(other_task.target.owner):
+ other_task.transitionToStatus(new_status, other_task.target.owner)
def test_upstream_status(self):
# Search results can be filtered by the status of an upstream
@@ -299,14 +324,11 @@
# with status NEW for the "other" product, hence all bug tasks
# will be returned in a search for bugs that are open upstream.
params = self.getBugTaskSearchParams(user=None, open_upstream=True)
- search_result = self.runSearch(params)
- expected = self.resultValuesForBugtasks(self.bugtasks)
- self.assertEqual(expected, search_result)
+ self.assertSearchFinds(params, self.bugtasks)
# A search for tasks resolved upstream does not yield any bugtask.
params = self.getBugTaskSearchParams(
user=None, resolved_upstream=True)
- search_result = self.runSearch(params)
- self.assertEqual([], search_result)
+ self.assertSearchFinds(params, [])
# But if we set upstream bug tasks to "fix committed" or "fix
# released", the related bug tasks for our test target appear in
# the search result.
@@ -314,14 +336,11 @@
self.bugtasks[0], BugTaskStatus.FIXCOMMITTED)
self.changeStatusOfBugTaskForOtherProduct(
self.bugtasks[1], BugTaskStatus.FIXRELEASED)
- search_result = self.runSearch(params)
- expected = self.resultValuesForBugtasks(self.bugtasks[:2])
- self.assertEqual(expected, search_result)
+ self.assertSearchFinds(params, self.bugtasks[:2])
# A search for bug tasks open upstream now returns only one
# test task.
params = self.getBugTaskSearchParams(user=None, open_upstream=True)
- search_result = self.runSearch(params)
- expected = self.resultValuesForBugtasks(self.bugtasks[2:])
+ self.assertSearchFinds(params, self.bugtasks[2:])
def test_tags(self):
# Search results can be limited to bugs having given tags.
@@ -330,44 +349,31 @@
self.bugtasks[1].bug.tags = ['tag1', 'tag3']
params = self.getBugTaskSearchParams(
user=None, tag=any('tag2', 'tag3'))
- search_result = self.runSearch(params)
- expected = self.resultValuesForBugtasks(self.bugtasks[:2])
- self.assertEqual(expected, search_result)
+ self.assertSearchFinds(params, self.bugtasks[:2])
params = self.getBugTaskSearchParams(
user=None, tag=all('tag2', 'tag3'))
- search_result = self.runSearch(params)
- self.assertEqual([], search_result)
+ self.assertSearchFinds(params, [])
params = self.getBugTaskSearchParams(
user=None, tag=all('tag1', 'tag3'))
- search_result = self.runSearch(params)
- expected = self.resultValuesForBugtasks(self.bugtasks[1:2])
- self.assertEqual(expected, search_result)
+ self.assertSearchFinds(params, self.bugtasks[1:2])
params = self.getBugTaskSearchParams(
user=None, tag=all('tag1', '-tag3'))
- search_result = self.runSearch(params)
- expected = self.resultValuesForBugtasks(self.bugtasks[:1])
- self.assertEqual(expected, search_result)
+ self.assertSearchFinds(params, self.bugtasks[:1])
params = self.getBugTaskSearchParams(
user=None, tag=all('-tag1'))
- search_result = self.runSearch(params)
- expected = self.resultValuesForBugtasks(self.bugtasks[2:])
- self.assertEqual(expected, search_result)
+ self.assertSearchFinds(params, self.bugtasks[2:])
params = self.getBugTaskSearchParams(
user=None, tag=all('*'))
- search_result = self.runSearch(params)
- expected = self.resultValuesForBugtasks(self.bugtasks[:2])
- self.assertEqual(expected, search_result)
+ self.assertSearchFinds(params, self.bugtasks[:2])
params = self.getBugTaskSearchParams(
user=None, tag=all('-*'))
- search_result = self.runSearch(params)
- expected = self.resultValuesForBugtasks(self.bugtasks[2:])
- self.assertEqual(expected, search_result)
+ self.assertSearchFinds(params, self.bugtasks[2:])
def test_date_closed(self):
# Search results can be filtered by the date_closed time
@@ -379,13 +385,106 @@
self.assertTrue(utc_now >= self.bugtasks[2].date_closed)
params = self.getBugTaskSearchParams(
user=None, date_closed=greater_than(utc_now-timedelta(days=1)))
- search_result = self.runSearch(params)
- expected = self.resultValuesForBugtasks(self.bugtasks[2:])
- self.assertEqual(expected, search_result)
+ self.assertSearchFinds(params, self.bugtasks[2:])
params = self.getBugTaskSearchParams(
user=None, date_closed=greater_than(utc_now+timedelta(days=1)))
- search_result = self.runSearch(params)
- self.assertEqual([], search_result)
+ self.assertSearchFinds(params, [])
+
+ def test_created_since(self):
+ # Search results can be limited to bugtasks created after a
+ # given time.
+ one_day_ago = self.bugtasks[0].datecreated - timedelta(days=1)
+ two_days_ago = self.bugtasks[0].datecreated - timedelta(days=2)
+ with person_logged_in(self.owner):
+ self.bugtasks[0].datecreated = two_days_ago
+ params = self.getBugTaskSearchParams(
+ user=None, created_since=one_day_ago)
+ self.assertSearchFinds(params, self.bugtasks[1:])
+
+ def test_modified_since(self):
+ # Search results can be limited to bugs modified after a
+ # given time.
+ one_day_ago = (
+ self.bugtasks[0].bug.date_last_updated - timedelta(days=1))
+ two_days_ago = (
+ self.bugtasks[0].bug.date_last_updated - timedelta(days=2))
+ with person_logged_in(self.owner):
+ self.bugtasks[0].bug.date_last_updated = two_days_ago
+ params = self.getBugTaskSearchParams(
+ user=None, modified_since=one_day_ago)
+ self.assertSearchFinds(params, self.bugtasks[1:])
+
+ def test_branches_linked(self):
+ # Search results can be limited to bugs with or without linked
+ # branches.
+ with person_logged_in(self.owner):
+ branch = self.factory.makeBranch()
+ self.bugtasks[0].bug.linkBranch(branch, self.owner)
+ params = self.getBugTaskSearchParams(
+ user=None, linked_branches=BugBranchSearch.BUGS_WITH_BRANCHES)
+ self.assertSearchFinds(params, self.bugtasks[:1])
+ params = self.getBugTaskSearchParams(
+ user=None, linked_branches=BugBranchSearch.BUGS_WITHOUT_BRANCHES)
+ self.assertSearchFinds(params, self.bugtasks[1:])
+
+ def test_limit_search_to_one_bug(self):
+ # Search results can be limited to a given bug.
+ params = self.getBugTaskSearchParams(
+ user=None, bug=self.bugtasks[0].bug)
+ self.assertSearchFinds(params, self.bugtasks[:1])
+ other_bug = self.factory.makeBug()
+ params = self.getBugTaskSearchParams(user=None, bug=other_bug)
+ self.assertSearchFinds(params, [])
+
+ def test_filter_by_status(self):
+ # Search results can be limited to bug tasks with a given status.
+ params = self.getBugTaskSearchParams(
+ user=None, status=BugTaskStatus.FIXCOMMITTED)
+ self.assertSearchFinds(params, self.bugtasks[2:])
+ params = self.getBugTaskSearchParams(
+ user=None, status=any(BugTaskStatus.NEW, BugTaskStatus.TRIAGED))
+ self.assertSearchFinds(params, self.bugtasks[:2])
+ params = self.getBugTaskSearchParams(
+ user=None, status=BugTaskStatus.WONTFIX)
+ self.assertSearchFinds(params, [])
+
+ def test_filter_by_importance(self):
+ # Search results can be limited to bug tasks with a given importance.
+ params = self.getBugTaskSearchParams(
+ user=None, importance=BugTaskImportance.HIGH)
+ self.assertSearchFinds(params, self.bugtasks[:1])
+ params = self.getBugTaskSearchParams(
+ user=None,
+ importance=any(BugTaskImportance.HIGH, BugTaskImportance.LOW))
+ self.assertSearchFinds(params, self.bugtasks[:2])
+ params = self.getBugTaskSearchParams(
+ user=None, importance=BugTaskImportance.MEDIUM)
+ self.assertSearchFinds(params, [])
+
+ def test_omit_duplicate_bugs(self):
+ # Duplicate bugs can optionally be excluded from search results.
+ # The default behaviour is to include duplicates.
+ duplicate_bug = self.bugtasks[0].bug
+ master_bug = self.bugtasks[1].bug
+ with person_logged_in(self.owner):
+ duplicate_bug.markAsDuplicate(master_bug)
+ params = self.getBugTaskSearchParams(user=None)
+ self.assertSearchFinds(params, self.bugtasks)
+ # If we explicitly pass the parameter omit_duplicates=False, we get
+ # the same result.
+ params = self.getBugTaskSearchParams(user=None, omit_dupes=False)
+ self.assertSearchFinds(params, self.bugtasks)
+ # If omit_duplicates is set to True, the first task bug is omitted.
+ params = self.getBugTaskSearchParams(user=None, omit_dupes=True)
+ self.assertSearchFinds(params, self.bugtasks[1:])
+
+ def test_has_cve(self):
+ # Search results can be limited to bugs linked to a CVE.
+ with person_logged_in(self.owner):
+ cve = self.factory.makeCVE('2010-0123')
+ self.bugtasks[0].bug.linkCVE(cve, self.owner)
+ params = self.getBugTaskSearchParams(user=None, has_cve=True)
+ self.assertSearchFinds(params, self.bugtasks[:1])
class ProductAndDistributionTests:
@@ -405,9 +504,7 @@
self.bugtasks[0].bug.addNomination(nominator, series1)
self.bugtasks[1].bug.addNomination(nominator, series2)
params = self.getBugTaskSearchParams(user=None, nominated_for=series1)
- search_result = self.runSearch(params)
- expected = self.resultValuesForBugtasks(self.bugtasks[:1])
- self.assertEqual(expected, search_result)
+ self.assertSearchFinds(params, self.bugtasks[:1])
class BugTargetTestBase:
@@ -445,15 +542,12 @@
supervisor = self.factory.makeTeam(owner=self.owner)
params = self.getBugTaskSearchParams(
user=None, bug_supervisor=supervisor)
- search_result = self.runSearch(params)
- self.assertEqual([], search_result)
+ self.assertSearchFinds(params, [])
# If we appoint a bug supervisor, searching for bug tasks
# by supervisor will return all bugs for our test target.
self.setSupervisor(supervisor)
- search_result = self.runSearch(params)
- expected = self.resultValuesForBugtasks(self.bugtasks)
- self.assertEqual(expected, search_result)
+ self.assertSearchFinds(params, self.bugtasks)
def setSupervisor(self, supervisor):
"""Set the bug supervisor for the bug task target."""
@@ -484,6 +578,11 @@
"""See `ProductAndDistributionTests`."""
return self.factory.makeProductSeries(product=self.searchtarget)
+ def findBugtaskForOtherProduct(self, bugtask):
+ # Return the bugtask for the product that not related to the
+ # main bug target.
+ return self._findBugtaskForOtherProduct(bugtask, self.searchtarget)
+
class ProductSeriesTarget(BugTargetTestBase):
"""Use a product series as the bug target."""
@@ -503,6 +602,31 @@
params.setProductSeries(self.searchtarget)
return params
+ def changeStatusOfBugTaskForOtherProduct(self, bugtask, new_status):
+ # Change the status of another bugtask of the same bug to the
+ # given status.
+ #
+ # This method is called by SearchTestBase.test_upstream_status().
+ # A search for bugs which are open or closed upstream has an
+ # odd behaviour when the search target is a product series: In
+ # this case, all bugs with an open or closed bug task for _any_
+ # product are returned, including bug tasks for the main product
+ # of the series. Hence we must set the status for all products
+ # in order to avoid a failure of test_upstream_status().
+ bug = bugtask.bug
+ for other_task in bug.bugtasks:
+ other_target = other_task.target
+ if IProduct.providedBy(other_target):
+ with person_logged_in(other_target.owner):
+ other_task.transitionToStatus(
+ new_status, other_target.owner)
+
+ def findBugtaskForOtherProduct(self, bugtask):
+ # Return the bugtask for the product that not related to the
+ # main bug target.
+ return self._findBugtaskForOtherProduct(
+ bugtask, self.searchtarget.product)
+
class ProjectGroupTarget(BugTargetTestBase, BugTargetWithBugSuperVisor):
"""Use a project group as the bug target."""
@@ -525,8 +649,10 @@
def makeBugTasks(self):
"""Create bug tasks for the search target."""
self.bugtasks = []
+ self.products = []
with person_logged_in(self.owner):
product = self.factory.makeProduct(owner=self.owner)
+ self.products.append(product)
product.project = self.searchtarget
self.bugtasks.append(
self.factory.makeBugTask(target=product))
@@ -535,6 +661,7 @@
BugTaskStatus.TRIAGED, self.owner)
product = self.factory.makeProduct(owner=self.owner)
+ self.products.append(product)
product.project = self.searchtarget
self.bugtasks.append(
self.factory.makeBugTask(target=product))
@@ -543,6 +670,7 @@
BugTaskStatus.NEW, self.owner)
product = self.factory.makeProduct(owner=self.owner)
+ self.products.append(product)
product.project = self.searchtarget
self.bugtasks.append(
self.factory.makeBugTask(target=product))
@@ -557,6 +685,19 @@
for bugtask in self.bugtasks:
bugtask.target.setBugSupervisor(supervisor, self.owner)
+ def findBugtaskForOtherProduct(self, bugtask):
+ # Return the bugtask for the product that not related to the
+ # main bug target.
+ bug = bugtask.bug
+ for other_task in bug.bugtasks:
+ other_target = other_task.target
+ if (IProduct.providedBy(other_target)
+ and other_target not in self.products):
+ return other_task
+ self.fail(
+ 'No bug task found for a product that is not the target of '
+ 'the main test bugtask.')
+
class MilestoneTarget(BugTargetTestBase):
"""Use a milestone as the bug target."""
@@ -583,6 +724,11 @@
for bugtask in self.bugtasks:
bugtask.transitionToMilestone(self.searchtarget, self.owner)
+ def findBugtaskForOtherProduct(self, bugtask):
+ # Return the bugtask for the product that not related to the
+ # main bug target.
+ return self._findBugtaskForOtherProduct(bugtask, self.product)
+
class DistributionTarget(BugTargetTestBase, ProductAndDistributionTests,
BugTargetWithBugSuperVisor):
@@ -645,6 +791,14 @@
params.setSourcePackage(self.searchtarget)
return params
+ def subscribeToTarget(self, subscriber):
+ # Subscribe the given person to the search target.
+ # Source packages do not support structural subscriptions,
+ # so we subscribe to the distro series instead.
+ with person_logged_in(subscriber):
+ self.searchtarget.distroseries.addSubscription(
+ subscriber, subscribed_by=subscriber)
+
class DistributionSourcePackageTarget(BugTargetTestBase,
BugTargetWithBugSuperVisor):
=== modified file 'lib/lp/testing/factory.py'
--- lib/lp/testing/factory.py 2010-11-03 10:35:12 +0000
+++ lib/lp/testing/factory.py 2010-11-03 16:52:47 +0000
@@ -111,6 +111,10 @@
IBugTrackerSet,
)
from lp.bugs.interfaces.bugwatch import IBugWatchSet
+from lp.bugs.interfaces.cve import (
+ CveStatus,
+ ICveSet,
+ )
from lp.buildmaster.enums import (
BuildFarmJobType,
BuildStatus,
@@ -3227,6 +3231,13 @@
consumer, reviewed_by=owner, access_level=access_level)
return request_token.createAccessToken()
+ def makeCVE(self, sequence, description=None,
+ cvestate=CveStatus.CANDIDATE):
+ """Create a new CVE record."""
+ if description is None:
+ description = self.getUniqueString()
+ return getUtility(ICveSet).new(sequence, description, cvestate)
+
# Some factory methods return simple Python types. We don't add
# security wrappers for them, as well as for objects created by