Merge lp:~deryck/launchpad/better-testing-for-status-changes into lp:launchpad

Proposed by Deryck Hodge
Status: Merged
Approved by: Deryck Hodge
Approved revision: no longer in the source branch.
Merged at revision: 11754
Proposed branch: lp:~deryck/launchpad/better-testing-for-status-changes
Merge into: lp:launchpad
Diff against target: 534 lines (+366/-146)
2 files modified
lib/lp/bugs/doc/bugtask-status-changes.txt (+51/-131)
lib/lp/bugs/tests/test_bugtask_status.py (+315/-15)
To merge this branch: bzr merge lp:~deryck/launchpad/better-testing-for-status-changes
Reviewer Review Type Date Requested Status
Abel Deuring (community) code Approve
Review via email: mp+38552@code.launchpad.net

Commit message

Refactor doctest for bugtask status changes into separate unit test and documentation.

Description of the change

This branch is the first toward a fix for Bug #126516, or more specifically for a fix to limit transitioning away from Fix Released status. Before this branch the tests for bugtask status changes was a mix of a unit test and doctest, both living under lp.bugs.tests.

The branch refactors that mess, opting to do a complete unit test of BugTask.transitionToStatus and BugTask.canTransitionToStatus. The doctest is then made to be documentation and moved to lp.bugs.doc. Some example code is left in the doctest, though refactored to use factory generated data.

To test, run:

./bin/test -cvvt bugtask-status-changes
./bin/test -cvvt test_bugtask_status

Thanks for the review!

To post a comment you must log in.
Revision history for this message
Abel Deuring (adeuring) wrote :

(17:52:07) adeuring: deryck: I think it might make sense to change the test setup so that the product owner is not a member of the bug supervisor team; right now, the term "or user.inTeam(pillar.owner)" in canTransitionToStatus() is not executed
(17:52:53) deryck: adeuring, ok, that's a good idea. I can do that.
(17:53:07) adeuring: deryck: thanks! another suggestion, before you start ;)
(17:53:16) deryck: sure
(17:55:28) salgado heißt jetzt salgado-lunch
(17:55:30) adeuring: deryck: you don't test at all for celebrities.bug_watch_updater, celebrities.bug_importer, celebrities.janitor. You could add these tests quickly by definig a base class for tests of "extended permissions", where you do not define the user who is tested, then derive the "real" test classes for supervisor, owner and the celebrities.
(17:55:45) adeuring: That should make the tests a bit shorter and more comprehensive
(17:57:44) deryck: sure, I like that idea. I can do that, too.
(17:57:59) adeuring: deryck: cool, thanks!

Revision history for this message
Abel Deuring (adeuring) wrote :

Hi Deryck,

thanks for the refactoring. r=me.

Just a few nitpicks:

could you add TestCases for the celebrities bug_watch_updater,
bug_importer, janitor?

> +class TestBugTaskStatusTransitionForPrivilegedUserBase:
> + """Base class used to test privileged users and status transitions."""
> +
> + layer = LaunchpadFunctionalLayer
> +
> + def setUp(self):
> + super(TestBugTaskStatusTransitionForPrivilegedUserBase, self).setUp()
> + # Creation of task and target are deferred to subclasses.
> + self.task = None
> + self.person = None
> + self.makePersonAndTask()
> +
> + def makePersonAndTask(self):
> + """Create a bug task and privileged person for this task.
> +
> + This method is user by subclasses to correctly setup
> + each test.
> + """

I think this should be something like "is (overloaded|implemented) by
subclasses"

cheers
Abel

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== renamed file 'lib/lp/bugs/tests/test_bugtask_status.txt' => 'lib/lp/bugs/doc/bugtask-status-changes.txt'
--- lib/lp/bugs/tests/test_bugtask_status.txt 2010-10-09 16:36:22 +0000
+++ lib/lp/bugs/doc/bugtask-status-changes.txt 2010-10-19 13:36:54 +0000
@@ -1,137 +1,57 @@
1= Setting Bug Statuses =1Changing Bug Task Status
22========================
3 >>> from canonical.launchpad.interfaces import (3
4 ... CreateBugParams, IPersonSet, IProductSet)4Restrictions
5------------
6
7There are a few simple rules around who can change the status of a
8bug task. There are three statuses that can only be set by either
9the project registrant or the bug supervisor:
10
11 * Won't Fix
12 * Expired
13 * Triaged
14
15 >>> owner = factory.makePerson()
16 >>> product = factory.makeProduct(owner=owner)
17 >>> bugtask = factory.makeBugTask(target=product)
18 >>> user = factory.makePerson()
19
5 >>> from lp.bugs.interfaces.bugtask import BugTaskStatus20 >>> from lp.bugs.interfaces.bugtask import BugTaskStatus
621 >>> login_person(owner)
7 >>> firefox = getUtility(IProductSet).getByName('firefox')22 >>> bugtask.transitionToStatus(BugTaskStatus.WONTFIX, owner)
8 >>> nopriv_user = getUtility(IPersonSet).getByName('no-priv')23 >>> print bugtask.status.title
9 >>> login('foo.bar@canonical.com')24 Won't Fix
10 >>> firefox.setBugSupervisor(nopriv_user, nopriv_user)25
11 >>> login('no-priv@canonical.com')26Regular users of Launchpad cannot transition a bug task to any of
12 >>> bug_params = CreateBugParams(27these statuses.
13 ... nopriv_user, 'Test bug', 'Something')28
14 >>> firefox_bug = firefox.createBug(bug_params)29An additional restraint is added to Won't Fix. Only the product
1530registrant or bug supervisor can change from this status to any
16Bug Supervisors can transition bugs to the Won't Fix, Expired and31other status.
17Triaged statuses.32
1833 >>> login_person(user)
19 >>> [firefox_bugtask] = firefox_bug.bugtasks34 >>> bugtask.transitionToStatus(BugTaskStatus.CONFIRMED, user)
20 >>> firefox_bugtask.transitionToStatus(35 Traceback (most recent call last):
21 ... BugTaskStatus.WONTFIX, nopriv_user)36 ...
22 >>> print firefox_bugtask.status.title37 UserCannotEditBugTaskStatus...
23 Won't Fix38
2439This is fully tested in
25 >>> firefox_bugtask.transitionToStatus(40lp.bugs.tests.test_bugtask_status.TestBugTaskStatusSetting.
26 ... BugTaskStatus.EXPIRED, nopriv_user)41
27 >>> print firefox_bugtask.status.title42Testing for Permission
28 Expired43----------------------
29
30 >>> firefox_bugtask.transitionToStatus(
31 ... BugTaskStatus.TRIAGED, nopriv_user)
32 >>> print firefox_bugtask.status.title
33 Triaged
34
35The product registrant can transition to the Won't Fix, Expired and
36Triaged statuses too.
37
38 >>> firefox_bugtask.transitionToStatus(
39 ... BugTaskStatus.CONFIRMED, nopriv_user)
40 >>> print firefox_bugtask.status.title
41 Confirmed
42
43 >>> firefox.owner.inTeam(firefox.bug_supervisor)
44 False
45
46 >>> firefox_bugtask.transitionToStatus(
47 ... BugTaskStatus.WONTFIX, firefox.owner)
48 >>> print firefox_bugtask.status.title
49 Won't Fix
50
51 >>> firefox_bugtask.transitionToStatus(
52 ... BugTaskStatus.EXPIRED, firefox.owner)
53 >>> print firefox_bugtask.status.title
54 Expired
55
56 >>> firefox_bugtask.transitionToStatus(
57 ... BugTaskStatus.TRIAGED, firefox.owner)
58 >>> print firefox_bugtask.status.title
59 Triaged
60
61Users who are not bug supervisors or product registrants cannot
62transition the status to Won't Fix or Triaged. The option is not
63exposed in the UI, but we also enforce this rule at the database level
64to ensure that all call sites adhere to this.
65
66 >>> login('foo.bar@canonical.com')
67 >>> firefox.setBugSupervisor(None, None)
68
69 >>> login('no-priv@canonical.com')
70
71 >>> firefox_bugtask.transitionToStatus(
72 ... BugTaskStatus.WONTFIX, nopriv_user)
73 Traceback (most recent call last):
74 ...
75 UserCannotEditBugTaskStatus: Only Bug Supervisors may change status to Won't Fix.
76
77 >>> firefox_bugtask.transitionToStatus(
78 ... BugTaskStatus.EXPIRED, nopriv_user)
79 Traceback (most recent call last):
80 ...
81 UserCannotEditBugTaskStatus: Only Bug Supervisors may change status to Expired.
82
83 >>> firefox_bugtask.transitionToStatus(
84 ... BugTaskStatus.TRIAGED, nopriv_user)
85 Traceback (most recent call last):
86 ...
87 UserCannotEditBugTaskStatus: Only Bug Supervisors may change status to Triaged.
88
89Users who are not bug supervisors or product registrants cannot
90transition the status from Won't Fix to anything else.
91
92 >>> login('foo.bar@canonical.com')
93 >>> foo_bar = getUtility(ILaunchBag).user
94 >>> firefox.setBugSupervisor(foo_bar, foo_bar)
95 >>> firefox_bugtask.transitionToStatus(
96 ... BugTaskStatus.WONTFIX, foo_bar)
97
98 >>> login('no-priv@canonical.com')
99 >>> firefox_bugtask.transitionToStatus(
100 ... BugTaskStatus.NEW, nopriv_user)
101 Traceback (most recent call last):
102 ...
103 UserCannotEditBugTaskStatus: Only Bug Supervisors may change status to New.
10444
105The method IBugTask.canTransitionToStatus comes in handy here. It45The method IBugTask.canTransitionToStatus comes in handy here. It
106tells us if a transition to a status is permitted. It is *not* a46tells us if a transition to a status is permitted. It is *not* a
107dry-run of transitionToStatus, but is good enough and fast enough to47dry-run of IBugTask.transitionToStatus, but is good enough and fast
108be used by UI code, e.g. to display only those statuses to which a48enough to be used by UI code, e.g. to display only those statuses to
109user can transition a particular bugtask.49which a user can transition a particular bugtask.
11050
111 >>> login('foo.bar@canonical.com')51 >>> bugtask.canTransitionToStatus(BugTaskStatus.TRIAGED, owner)
112 >>> firefox_bugtask.transitionToStatus(
113 ... BugTaskStatus.TRIAGED, foo_bar)
114
115 >>> login('no-priv@canonical.com')
116
117 >>> firefox_bugtask.canTransitionToStatus(
118 ... BugTaskStatus.WONTFIX, nopriv_user)
119 False
120
121 >>> firefox_bugtask.canTransitionToStatus(
122 ... BugTaskStatus.TRIAGED, nopriv_user)
123 False
124
125 >>> firefox_bugtask.canTransitionToStatus(
126 ... BugTaskStatus.INCOMPLETE, nopriv_user)
127 True52 True
12853 >>> bugtask.canTransitionToStatus(BugTaskStatus.TRIAGED, user)
129 >>> login('foo.bar@canonical.com')
130 >>> firefox_bugtask.transitionToStatus(
131 ... BugTaskStatus.WONTFIX, getUtility(ILaunchBag).user)
132
133 >>> login('no-priv@canonical.com')
134
135 >>> firefox_bugtask.canTransitionToStatus(
136 ... BugTaskStatus.NEW, nopriv_user)
137 False54 False
55
56This method is fully tested in
57lp.bugs.tests.test_bugtask_status.TestCanTransitionToStatus.
13858
=== modified file 'lib/lp/bugs/tests/test_bugtask_status.py'
--- lib/lp/bugs/tests/test_bugtask_status.py 2010-10-04 19:50:45 +0000
+++ lib/lp/bugs/tests/test_bugtask_status.py 2010-10-19 13:36:54 +0000
@@ -1,22 +1,322 @@
1# Copyright 2009 Canonical Ltd. This software is licensed under the1# Copyright 2009 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).2# GNU Affero General Public License version 3 (see the file LICENSE).
33
4"""Test for choosing the request and publication."""4"""Tests for bug task status transitions."""
55
6__metaclass__ = type6__metaclass__ = type
77
8from canonical.launchpad.testing.systemdocs import (8from zope.component import getUtility
9 LayeredDocFileSuite,9from zope.security.proxy import removeSecurityProxy
10 setUp,10
11 tearDown,11from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
12from canonical.testing.layers import LaunchpadFunctionalLayer
13from lp.bugs.interfaces.bugtask import UserCannotEditBugTaskStatus
14from lp.bugs.model.bugtask import BugTaskStatus
15from lp.testing import (
16 person_logged_in,
17 TestCaseWithFactory,
12 )18 )
13from canonical.testing.layers import LaunchpadFunctionalLayer19
1420
1521class TestBugTaskStatusTransitionForUser(TestCaseWithFactory):
16def test_suite():22 """Test bugtask status transitions for a regular logged in user."""
17 suite = LayeredDocFileSuite(23
18 'test_bugtask_status.txt',24 layer = LaunchpadFunctionalLayer
19 layer=LaunchpadFunctionalLayer, setUp=setUp, tearDown=tearDown,25
20 )26 def setUp(self):
21 return suite27 super(TestBugTaskStatusTransitionForUser, self).setUp()
2228 self.user = self.factory.makePerson()
29 self.task = self.factory.makeBugTask()
30
31 def test_user_transition_all_statuses(self):
32 # A regular user should not be able to set statuses in
33 # BUG_SUPERVISOR_BUGTASK_STATUSES, but can set any
34 # other status.
35 self.assertEqual(self.task.status, BugTaskStatus.NEW)
36 with person_logged_in(self.user):
37 self.assertRaises(
38 UserCannotEditBugTaskStatus, self.task.transitionToStatus,
39 BugTaskStatus.WONTFIX, self.user)
40 self.assertRaises(
41 UserCannotEditBugTaskStatus, self.task.transitionToStatus,
42 BugTaskStatus.EXPIRED, self.user)
43 self.assertRaises(
44 UserCannotEditBugTaskStatus, self.task.transitionToStatus,
45 BugTaskStatus.TRIAGED, self.user)
46 self.task.transitionToStatus(BugTaskStatus.NEW, self.user)
47 self.assertEqual(self.task.status, BugTaskStatus.NEW)
48 self.task.transitionToStatus(
49 BugTaskStatus.INCOMPLETE, self.user)
50 self.assertEqual(self.task.status, BugTaskStatus.INCOMPLETE)
51 self.task.transitionToStatus(BugTaskStatus.OPINION, self.user)
52 self.assertEqual(self.task.status, BugTaskStatus.OPINION)
53 self.task.transitionToStatus(BugTaskStatus.INVALID, self.user)
54 self.assertEqual(self.task.status, BugTaskStatus.INVALID)
55 self.task.transitionToStatus(BugTaskStatus.CONFIRMED, self.user)
56 self.assertEqual(self.task.status, BugTaskStatus.CONFIRMED)
57 self.task.transitionToStatus(
58 BugTaskStatus.INPROGRESS, self.user)
59 self.assertEqual(self.task.status, BugTaskStatus.INPROGRESS)
60 self.task.transitionToStatus(
61 BugTaskStatus.FIXCOMMITTED, self.user)
62 self.assertEqual(self.task.status, BugTaskStatus.FIXCOMMITTED)
63 self.task.transitionToStatus(
64 BugTaskStatus.FIXRELEASED, self.user)
65 self.assertEqual(self.task.status, BugTaskStatus.FIXRELEASED)
66
67 def test_user_cannot_unset_wont_fix_status(self):
68 # A regular user should not be able to transition a bug away
69 # from Won't Fix.
70 removeSecurityProxy(self.task).status = BugTaskStatus.WONTFIX
71 with person_logged_in(self.user):
72 self.assertRaises(
73 UserCannotEditBugTaskStatus, self.task.transitionToStatus,
74 BugTaskStatus.CONFIRMED, self.user)
75
76 def test_user_canTransitionToStatus(self):
77 # Regular user cannot transition to BUG_SUPERVISOR_BUGTASK_STATUSES,
78 # but can transition to any other status.
79 self.assertEqual(
80 self.task.canTransitionToStatus(
81 BugTaskStatus.WONTFIX, self.user),
82 False)
83 self.assertEqual(
84 self.task.canTransitionToStatus(
85 BugTaskStatus.EXPIRED, self.user),
86 False)
87 self.assertEqual(
88 self.task.canTransitionToStatus(
89 BugTaskStatus.TRIAGED, self.user),
90 False)
91 self.assertEqual(
92 self.task.canTransitionToStatus(
93 BugTaskStatus.NEW, self.user),
94 True)
95 self.assertEqual(
96 self.task.canTransitionToStatus(
97 BugTaskStatus.INCOMPLETE, self.user), True)
98 self.assertEqual(
99 self.task.canTransitionToStatus(
100 BugTaskStatus.OPINION, self.user),
101 True)
102 self.assertEqual(
103 self.task.canTransitionToStatus(
104 BugTaskStatus.INVALID, self.user),
105 True)
106 self.assertEqual(
107 self.task.canTransitionToStatus(
108 BugTaskStatus.CONFIRMED, self.user),
109 True)
110 self.assertEqual(
111 self.task.canTransitionToStatus(
112 BugTaskStatus.INPROGRESS, self.user),
113 True)
114 self.assertEqual(
115 self.task.canTransitionToStatus(
116 BugTaskStatus.FIXCOMMITTED, self.user),
117 True)
118 self.assertEqual(
119 self.task.canTransitionToStatus(
120 BugTaskStatus.FIXRELEASED, self.user),
121 True)
122
123 def test_user_canTransitionToStatus_from_wontfix(self):
124 # A regular user cannot transition away from Won't Fix,
125 # so canTransitionToStatus should return False.
126 removeSecurityProxy(self.task).status = BugTaskStatus.WONTFIX
127 self.assertEqual(
128 self.task.canTransitionToStatus(
129 BugTaskStatus.NEW, self.user),
130 False)
131
132
133class TestBugTaskStatusTransitionForPrivilegedUserBase:
134 """Base class used to test privileged users and status transitions."""
135
136 layer = LaunchpadFunctionalLayer
137
138 def setUp(self):
139 super(TestBugTaskStatusTransitionForPrivilegedUserBase, self).setUp()
140 # Creation of task and target are deferred to subclasses.
141 self.task = None
142 self.person = None
143 self.makePersonAndTask()
144
145 def makePersonAndTask(self):
146 """Create a bug task and privileged person for this task.
147
148 This method is implemented by subclasses to correctly setup
149 each test.
150 """
151 raise NotImplementedError(self.makePersonAndTask)
152
153 def test_privileged_user_transition_any_status(self):
154 # Privileged users (like owner or bug supervisor) should
155 # be able to set any status.
156 with person_logged_in(self.person):
157 self.task.transitionToStatus(BugTaskStatus.WONTFIX, self.person)
158 self.assertEqual(self.task.status, BugTaskStatus.WONTFIX)
159 self.task.transitionToStatus(BugTaskStatus.EXPIRED, self.person)
160 self.assertEqual(self.task.status, BugTaskStatus.EXPIRED)
161 self.task.transitionToStatus(BugTaskStatus.TRIAGED, self.person)
162 self.assertEqual(self.task.status, BugTaskStatus.TRIAGED)
163 self.task.transitionToStatus(BugTaskStatus.NEW, self.person)
164 self.assertEqual(self.task.status, BugTaskStatus.NEW)
165 self.task.transitionToStatus(
166 BugTaskStatus.INCOMPLETE, self.person)
167 self.assertEqual(self.task.status, BugTaskStatus.INCOMPLETE)
168 self.task.transitionToStatus(BugTaskStatus.OPINION, self.person)
169 self.assertEqual(self.task.status, BugTaskStatus.OPINION)
170 self.task.transitionToStatus(BugTaskStatus.INVALID, self.person)
171 self.assertEqual(self.task.status, BugTaskStatus.INVALID)
172 self.task.transitionToStatus(BugTaskStatus.CONFIRMED, self.person)
173 self.assertEqual(self.task.status, BugTaskStatus.CONFIRMED)
174 self.task.transitionToStatus(
175 BugTaskStatus.INPROGRESS, self.person)
176 self.assertEqual(self.task.status, BugTaskStatus.INPROGRESS)
177 self.task.transitionToStatus(
178 BugTaskStatus.FIXCOMMITTED, self.person)
179 self.assertEqual(self.task.status, BugTaskStatus.FIXCOMMITTED)
180 self.task.transitionToStatus(
181 BugTaskStatus.FIXRELEASED, self.person)
182 self.assertEqual(self.task.status, BugTaskStatus.FIXRELEASED)
183
184 def test_privileged_user_can_unset_wont_fix_status(self):
185 # Privileged users can transition away from Won't Fix.
186 removeSecurityProxy(self.task).status = BugTaskStatus.WONTFIX
187 with person_logged_in(self.person):
188 self.task.transitionToStatus(BugTaskStatus.CONFIRMED, self.person)
189 self.assertEqual(self.task.status, BugTaskStatus.CONFIRMED)
190
191 def test_privileged_user_canTransitionToStatus(self):
192 # Privileged users (like owner or bug supervisor) should
193 # be able to set any status, so canTransitionToStatus should
194 # always return True.
195 self.assertEqual(
196 self.task.canTransitionToStatus(
197 BugTaskStatus.WONTFIX, self.person),
198 True)
199 self.assertEqual(
200 self.task.canTransitionToStatus(
201 BugTaskStatus.EXPIRED, self.person),
202 True)
203 self.assertEqual(
204 self.task.canTransitionToStatus(
205 BugTaskStatus.TRIAGED, self.person),
206 True)
207 self.assertEqual(
208 self.task.canTransitionToStatus(
209 BugTaskStatus.NEW, self.person),
210 True)
211 self.assertEqual(
212 self.task.canTransitionToStatus(
213 BugTaskStatus.INCOMPLETE, self.person),
214 True)
215 self.assertEqual(
216 self.task.canTransitionToStatus(
217 BugTaskStatus.OPINION, self.person),
218 True)
219 self.assertEqual(
220 self.task.canTransitionToStatus(
221 BugTaskStatus.INVALID, self.person),
222 True)
223 self.assertEqual(
224 self.task.canTransitionToStatus(
225 BugTaskStatus.CONFIRMED, self.person),
226 True)
227 self.assertEqual(
228 self.task.canTransitionToStatus(
229 BugTaskStatus.INPROGRESS, self.person),
230 True)
231 self.assertEqual(
232 self.task.canTransitionToStatus(
233 BugTaskStatus.FIXCOMMITTED, self.person),
234 True)
235 self.assertEqual(
236 self.task.canTransitionToStatus(
237 BugTaskStatus.FIXRELEASED, self.person),
238 True)
239
240 def test_privileged_user_canTransitionToStatus_from_wontfix(self):
241 # A privileged user can transition away from Won't Fix, so
242 # canTransitionToStatus should return True.
243 removeSecurityProxy(self.task).status = BugTaskStatus.WONTFIX
244 self.assertEqual(
245 self.task.canTransitionToStatus(
246 BugTaskStatus.NEW, self.person),
247 True)
248
249
250class TestBugTaskStatusTransitionOwnerPerson(
251 TestBugTaskStatusTransitionForPrivilegedUserBase, TestCaseWithFactory):
252 """Tests to ensure owner person can transition to any status.."""
253
254 def makePersonAndTask(self):
255 self.person = self.factory.makePerson()
256 self.product = self.factory.makeProduct(owner=self.person)
257 self.task = self.factory.makeBugTask(target=self.product)
258
259
260class TestBugTaskStatusTransitionOwnerTeam(
261 TestBugTaskStatusTransitionForPrivilegedUserBase, TestCaseWithFactory):
262 """Tests to ensure owner team can transition to any status.."""
263
264 def makePersonAndTask(self):
265 self.person = self.factory.makePerson()
266 self.team = self.factory.makeTeam(members=[self.person])
267 self.product = self.factory.makeProduct(owner=self.team)
268 self.task = self.factory.makeBugTask(target=self.product)
269
270
271class TestBugTaskStatusTransitionBugSupervisorPerson(
272 TestBugTaskStatusTransitionForPrivilegedUserBase, TestCaseWithFactory):
273 """Tests to ensure bug supervisor person can transition to any status."""
274
275 def makePersonAndTask(self):
276 self.owner = self.factory.makePerson()
277 self.person = self.factory.makePerson()
278 self.product = self.factory.makeProduct(owner=self.owner)
279 self.task = self.factory.makeBugTask(target=self.product)
280 with person_logged_in(self.owner):
281 self.product.setBugSupervisor(self.person, self.person)
282
283
284class TestBugTaskStatusTransitionBugSupervisorTeamMember(
285 TestBugTaskStatusTransitionForPrivilegedUserBase, TestCaseWithFactory):
286 """Tests to ensure bug supervisor team can transition to any status."""
287
288 def makePersonAndTask(self):
289 self.owner = self.factory.makePerson()
290 self.person = self.factory.makePerson()
291 self.team = self.factory.makeTeam(members=[self.person])
292 self.product = self.factory.makeProduct(owner=self.owner)
293 self.task = self.factory.makeBugTask(target=self.product)
294 with person_logged_in(self.owner):
295 self.product.setBugSupervisor(self.team, self.team)
296
297
298class TestBugTaskStatusTransitionBugWatchUpdater(
299 TestBugTaskStatusTransitionForPrivilegedUserBase, TestCaseWithFactory):
300 """Tests to ensure bug_watch_updater can transition to any status."""
301
302 def makePersonAndTask(self):
303 self.person = getUtility(ILaunchpadCelebrities).bug_watch_updater
304 self.task = self.factory.makeBugTask()
305
306
307class TestBugTaskStatusTransitionBugImporter(
308 TestBugTaskStatusTransitionForPrivilegedUserBase, TestCaseWithFactory):
309 """Tests to ensure bug_importer can transition to any status."""
310
311 def makePersonAndTask(self):
312 self.person = getUtility(ILaunchpadCelebrities).bug_importer
313 self.task = self.factory.makeBugTask()
314
315
316class TestBugTaskStatusTransitionJanitor(
317 TestBugTaskStatusTransitionForPrivilegedUserBase, TestCaseWithFactory):
318 """Tests to ensure lp janitor can transition to any status."""
319
320 def makePersonAndTask(self):
321 self.person = getUtility(ILaunchpadCelebrities).janitor
322 self.task = self.factory.makeBugTask()