~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/bugs/doc/bug-set-status.txt

[r=sinzui][bug=855670] Add additional checks to the private team
        launchpad.LimitedView security adaptor so more users in defined
        roles can see the team.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
= Setting the status of a bug =
 
2
 
 
3
If you have a bug and a target, there's method which makes it easier to
 
4
change the bug's status for that specific target. It expects the user
 
5
changing the status, the target, and the new status.
 
6
 
 
7
    >>> from lp.testing.dbuser import lp_dbuser
 
8
    >>> from lp.registry.interfaces.person import IPersonSet
 
9
    >>> from lp.bugs.interfaces.bug import CreateBugParams
 
10
    >>> from lp.bugs.interfaces.bugtask import BugTaskStatus
 
11
    >>> from lp.registry.interfaces.product import IProductSet
 
12
 
 
13
    >>> with lp_dbuser():
 
14
    ...     login('no-priv@canonical.com')
 
15
    ...     no_priv = getUtility(IPersonSet).getByName('no-priv')
 
16
    ...     bug_params = CreateBugParams(
 
17
    ...         owner=no_priv, title='Sample bug', comment='This is a sample bug.')
 
18
    ...     firefox = getUtility(IProductSet).getByName('firefox')
 
19
    ...     bug = firefox.createBug(bug_params)
 
20
    ...     bug_id = bug.id
 
21
    ...     # Set a milestone to ensure that the current db user has enough
 
22
    ...     # privileges to access it.
 
23
    ...     [firefox_task] = bug.bugtasks
 
24
    ...     firefox_task.milestone = firefox.getMilestone('1.0')
 
25
 
 
26
    >>> from lp.bugs.interfaces.bug import IBugSet
 
27
    >>> bug = getUtility(IBugSet).get(bug_id)
 
28
    >>> no_priv = getUtility(IPersonSet).getByName('no-priv')
 
29
    >>> firefox = getUtility(IProductSet).getByName('firefox')
 
30
    >>> firefox_bugtask = bug.setStatus(
 
31
    ...     firefox, BugTaskStatus.CONFIRMED, no_priv)
 
32
 
 
33
It returns the edited bugtask.
 
34
 
 
35
    >>> firefox_bugtask.target.name
 
36
    u'firefox'
 
37
    >>> firefox_bugtask.status.name
 
38
    'CONFIRMED'
 
39
 
 
40
It also emits an ObjectModifiedEvent so that BugNotification and
 
41
BugActivity records are created.
 
42
 
 
43
    >>> from lp.bugs.model.bugnotification import BugNotification
 
44
    >>> latest_notification = BugNotification.selectFirst(orderBy='-id')
 
45
    >>> print latest_notification.message.owner.displayname
 
46
    No Privileges Person
 
47
    >>> print latest_notification.message.text_contents
 
48
    ** Changed in: firefox
 
49
           Status: New => Confirmed
 
50
 
 
51
    >>> from lp.bugs.model.bugactivity import BugActivity
 
52
    >>> latest_activity = BugActivity.selectFirst(orderBy='-id')
 
53
    >>> latest_activity.whatchanged
 
54
    u'firefox: status'
 
55
    >>> latest_activity.oldvalue
 
56
    u'New'
 
57
    >>> latest_activity.newvalue
 
58
    u'Confirmed'
 
59
 
 
60
The edited bugtask is only returned if it's actually edited. If the
 
61
bugtask already has the specified status, None is returned.
 
62
 
 
63
    >>> firefox_bugtask.status.name
 
64
    'CONFIRMED'
 
65
    >>> print bug.setStatus(firefox, BugTaskStatus.CONFIRMED, no_priv)
 
66
    None
 
67
 
 
68
=== Product series ===
 
69
 
 
70
If a product series is specified, but the bug is target only to the
 
71
product, not the product series, the product bugtask is edited.
 
72
 
 
73
    >>> firefox_trunk = firefox.getSeries('trunk')
 
74
    >>> bug.getBugTask(firefox_trunk) is None
 
75
    True
 
76
    >>> firefox_bugtask = bug.setStatus(
 
77
    ...     firefox_trunk, BugTaskStatus.NEW, no_priv)
 
78
    >>> firefox_bugtask.target.name
 
79
    u'firefox'
 
80
    >>> firefox_bugtask.status.name
 
81
    'NEW'
 
82
 
 
83
If the bug is targeted to the product series, the product series bugtask
 
84
is edited.
 
85
 
 
86
    >>> from lp.bugs.interfaces.bugtask import IBugTaskSet
 
87
    >>> with lp_dbuser():
 
88
    ...     bug = getUtility(IBugSet).get(bug_id)
 
89
    ...     no_priv = getUtility(IPersonSet).getByName('no-priv')
 
90
    ...     firefox = getUtility(IProductSet).getByName('firefox')
 
91
    ...     firefox_trunk = firefox.getSeries('trunk')
 
92
    ...     ignore = getUtility(IBugTaskSet).createTask(
 
93
    ...         bug, no_priv, firefox_trunk)
 
94
 
 
95
    >>> bug = getUtility(IBugSet).get(bug_id)
 
96
    >>> no_priv = getUtility(IPersonSet).getByName('no-priv')
 
97
    >>> firefox = getUtility(IProductSet).getByName('firefox')
 
98
    >>> firefox_trunk = firefox.getSeries('trunk')
 
99
    >>> firefox_trunk_bugtask = bug.setStatus(
 
100
    ...     firefox_trunk, BugTaskStatus.INCOMPLETE, no_priv)
 
101
 
 
102
    >>> firefox_trunk_bugtask.target.name
 
103
    u'trunk'
 
104
    >>> firefox_trunk_bugtask.status.name
 
105
    'INCOMPLETE'
 
106
 
 
107
If the target bugtask has a conjoined master bugtask, the conjoined
 
108
master will be edited and returned. The conjoined slave is of course
 
109
updated automatically.
 
110
 
 
111
    >>> firefox_bugtask = firefox_trunk_bugtask.conjoined_slave
 
112
    >>> firefox_bugtask.target.name
 
113
    u'firefox'
 
114
    >>> firefox_bugtask.conjoined_master is not None
 
115
    True
 
116
    >>> firefox_bugtask.status.name
 
117
    'INCOMPLETE'
 
118
    >>> firefox_trunk_bugtask = bug.setStatus(
 
119
    ...     firefox_bugtask.target, BugTaskStatus.CONFIRMED, no_priv)
 
120
    >>> firefox_trunk_bugtask.target.name
 
121
    u'trunk'
 
122
    >>> firefox_trunk_bugtask.status.name
 
123
    'CONFIRMED'
 
124
    >>> firefox_bugtask.status.name
 
125
    'CONFIRMED'
 
126
 
 
127
=== Distributions and packages ===
 
128
 
 
129
Setting the status of a distribution or package bugtask work the same as
 
130
for product tasks.
 
131
 
 
132
    >>> from lp.registry.interfaces.distribution import IDistributionSet
 
133
    >>> with lp_dbuser():
 
134
    ...     ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
 
135
    ...     # Set a milestone to ensure that the current db user has enough
 
136
    ...     # privileges to access it.
 
137
    ...     ubuntu_hoary = ubuntu.getSeries('hoary')
 
138
    ...     # Only owners, experts, or admins can create a milestone.
 
139
    ...     login('foo.bar@canonical.com')
 
140
    ...     feature_freeze = ubuntu_hoary.newMilestone('feature-freeze')
 
141
    ...     login('no-priv@canonical.com')
 
142
    ...     bug = ubuntu.createBug(bug_params)
 
143
    ...     [ubuntu_bugtask] = bug.bugtasks
 
144
    ...     ubuntu_bugtask.milestone = feature_freeze
 
145
    ...     bug_id = bug.id
 
146
 
 
147
    >>> bug = getUtility(IBugSet).get(bug_id)
 
148
    >>> no_priv = getUtility(IPersonSet).getByName('no-priv')
 
149
    >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
 
150
    >>> ubuntu_bugtask = bug.setStatus(
 
151
    ...     ubuntu, BugTaskStatus.CONFIRMED, no_priv)
 
152
    >>> ubuntu_bugtask.target.name
 
153
    u'ubuntu'
 
154
    >>> ubuntu_bugtask.status.name
 
155
    'CONFIRMED'
 
156
 
 
157
If a source package is given, but no such package exists, no bugtask
 
158
will be edited.
 
159
 
 
160
    >>> ubuntu_firefox = ubuntu.getSourcePackage('mozilla-firefox')
 
161
    >>> bug.setStatus(ubuntu_firefox, BugTaskStatus.CONFIRMED, no_priv) is None
 
162
    True
 
163
 
 
164
If the bug is targeted to a source package, that bugtask is of course
 
165
edited.
 
166
 
 
167
    >>> ubuntu_bugtask.transitionToTarget(ubuntu_firefox)
 
168
    >>> ubuntu_firefox_task = bug.setStatus(
 
169
    ...     ubuntu_firefox, BugTaskStatus.INCOMPLETE, no_priv)
 
170
    >>> ubuntu_firefox_task.target.displayname
 
171
    u'mozilla-firefox in Ubuntu'
 
172
    >>> ubuntu_firefox_task.status.name
 
173
    'INCOMPLETE'
 
174
 
 
175
If a distro series is given, but the bug is only targeted to the
 
176
distribution and not to the distro series, the distribution task is
 
177
edited.
 
178
 
 
179
    >>> ubuntu_warty = ubuntu.getSeries('warty')
 
180
    >>> warty_firefox = ubuntu_warty.getSourcePackage('mozilla-firefox')
 
181
    >>> ubuntu_firefox_task = bug.setStatus(
 
182
    ...     warty_firefox, BugTaskStatus.CONFIRMED, no_priv)
 
183
    >>> ubuntu_firefox_task.target.displayname
 
184
    u'mozilla-firefox in Ubuntu'
 
185
    >>> ubuntu_firefox_task.status.name
 
186
    'CONFIRMED'
 
187
 
 
188
    >>> ubuntu_hoary = ubuntu.getSeries('hoary')
 
189
    >>> hoary_firefox = ubuntu_hoary.getSourcePackage('mozilla-firefox')
 
190
    >>> ubuntu_firefox_task = bug.setStatus(
 
191
    ...     hoary_firefox, BugTaskStatus.NEW, no_priv)
 
192
    >>> ubuntu_firefox_task.target.displayname
 
193
    u'mozilla-firefox in Ubuntu'
 
194
    >>> ubuntu_firefox_task.status.name
 
195
    'NEW'
 
196
 
 
197
However, if the bug is targeted to the current series, passing a
 
198
non-current series won't modify any bugtask, unless the bug is already
 
199
targeted to the non-current series of course.
 
200
 
 
201
    >>> ubuntu.currentseries.name
 
202
    u'hoary'
 
203
 
 
204
    # Need to be privileged user to target the bug to a series.
 
205
    >>> login('foo.bar@canonical.com')
 
206
    >>> with lp_dbuser():
 
207
    ...     bug = getUtility(IBugSet).get(bug_id)
 
208
    ...     ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
 
209
    ...     ubuntu_hoary = ubuntu.getSeries('hoary')
 
210
    ...     nomination = bug.addNomination(
 
211
    ...         getUtility(ILaunchBag).user, ubuntu_hoary)
 
212
    ...     nomination.approve(getUtility(ILaunchBag).user)
 
213
    >>> login('no-priv@canonical.com')
 
214
 
 
215
    >>> bug = getUtility(IBugSet).get(bug_id)
 
216
    >>> no_priv = getUtility(IPersonSet).getByName('no-priv')
 
217
    >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
 
218
    >>> ubuntu_warty = ubuntu.getSeries('warty')
 
219
    >>> warty_firefox = ubuntu_warty.getSourcePackage('mozilla-firefox')
 
220
    >>> bug.setStatus(warty_firefox, BugTaskStatus.INCOMPLETE, no_priv) is None
 
221
    True
 
222
 
 
223
    >>> login('foo.bar@canonical.com')
 
224
    >>> with lp_dbuser():
 
225
    ...     bug = getUtility(IBugSet).get(bug_id)
 
226
    ...     ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
 
227
    ...     ubuntu_warty = ubuntu.getSeries('warty')
 
228
    ...     nomination = bug.addNomination(
 
229
    ...         getUtility(ILaunchBag).user, ubuntu_warty)
 
230
    ...     nomination.approve(getUtility(ILaunchBag).user)
 
231
    >>> login('no-priv@canonical.com')
 
232
 
 
233
    >>> bug = getUtility(IBugSet).get(bug_id)
 
234
    >>> no_priv = getUtility(IPersonSet).getByName('no-priv')
 
235
    >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
 
236
    >>> ubuntu_warty = ubuntu.getSeries('warty')
 
237
    >>> warty_firefox = ubuntu_warty.getSourcePackage('mozilla-firefox')
 
238
    >>> ubuntu_firefox_task = bug.setStatus(
 
239
    ...     warty_firefox, BugTaskStatus.INCOMPLETE, no_priv)
 
240
    >>> ubuntu_firefox_task.target.displayname
 
241
    u'mozilla-firefox in Ubuntu Warty'
 
242
    >>> ubuntu_firefox_task.status.name
 
243
    'INCOMPLETE'