~launchpad-pqm/launchpad/devel

7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
1
========================
2
Launchpad Answer Tracker
3
========================
2396 by Canonical.com Patch Queue Manager
[r=spiv] launchpad support tracker
4
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
5
Launchpad includes an Answer Tracker where users can post questions, usually
6
about problems they encounter with projects, and other people can answer them.
7
Questions are created and accessed using the IQuestionTarget interface.  This
8
interface is available on Products, Distributions and
9
DistributionSourcePackages.
2685.1.2 by Bjorn Tillenius
test that products works in accordance to ITicketTarget.
10
3691.197.109 by Francis J. Lacoste
- Add launchpad.Owner permission.
11
    >>> login('test@canonical.com')
3691.110.34 by Francis J. Lacoste
ITicketTarget requires authentication
12
14600.2.2 by Curtis Hovey
Moved webapp to lp.services.
13
    >>> from lp.services.webapp.testing import verifyObject
11716.1.12 by Curtis Hovey
Sorted imports in doctests.
14
    >>> from lp.answers.interfaces.questiontarget import IQuestionTarget
15
    >>> from lp.registry.interfaces.distribution import IDistributionSet
10409.5.38 by Curtis Hovey
Removed glob imports for answers.
16
    >>> from lp.registry.interfaces.person import IPersonSet
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
17
    >>> from lp.registry.interfaces.product import IProductSet
3691.110.7 by Francis J. Lacoste
Added more documentation and removed tests that are redundant with test_tickettarget.py
18
2685.1.2 by Bjorn Tillenius
test that products works in accordance to ITicketTarget.
19
    >>> firefox = getUtility(IProductSet)['firefox']
3691.398.18 by Francis J. Lacoste
Rename interfaces.
20
    >>> verifyObject(IQuestionTarget, firefox)
2685.1.2 by Bjorn Tillenius
test that products works in accordance to ITicketTarget.
21
    True
3691.110.7 by Francis J. Lacoste
Added more documentation and removed tests that are redundant with test_tickettarget.py
22
    >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
3691.398.18 by Francis J. Lacoste
Rename interfaces.
23
    >>> verifyObject(IQuestionTarget, ubuntu)
3691.110.7 by Francis J. Lacoste
Added more documentation and removed tests that are redundant with test_tickettarget.py
24
    True
25
4050.3.19 by Curtis Hovey
Revised test per review.
26
    >>> evolution_in_ubuntu = ubuntu.getSourcePackage('evolution')
27
    >>> verifyObject(IQuestionTarget, evolution_in_ubuntu)
3691.110.7 by Francis J. Lacoste
Added more documentation and removed tests that are redundant with test_tickettarget.py
28
    True
29
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
30
Although distribution series do not implement the IQuestionTarget interface,
31
it is possible to adapt one to it.  The adapter is actually the distroseries's
32
distribution.
3791.1.1 by Francis J. Lacoste
Add an adapter from IDistroRelease to ITicketTarget.
33
4285.2.1 by Mark Shuttleworth
Massive renaming of distrorelease to distroseries
34
    >>> ubuntu_warty = ubuntu.getSeries('warty')
3691.398.18 by Francis J. Lacoste
Rename interfaces.
35
    >>> IQuestionTarget.providedBy(ubuntu_warty)
3791.1.1 by Francis J. Lacoste
Add an adapter from IDistroRelease to ITicketTarget.
36
    False
3691.398.21 by Francis J. Lacoste
Rename all attributes and variables.
37
    >>> questiontarget = IQuestionTarget(ubuntu_warty)
38
    >>> verifyObject(IQuestionTarget, questiontarget)
3791.1.1 by Francis J. Lacoste
Add an adapter from IDistroRelease to ITicketTarget.
39
    True
40
3851.5.4 by Francis J. Lacoste
Add adapter from ISourcePackageRelease to IQuestionTarget.
41
Similarly, it is possible to adapt an ISourcePackageRelease into an
42
IQuestionTarget.
43
44
    >>> firefox_in_warty = ubuntu_warty.getSourcePackage('mozilla-firefox')
45
    >>> firefox_release_in_warty = firefox_in_warty.currentrelease
46
47
    >>> questiontarget = IQuestionTarget(firefox_release_in_warty)
48
    >>> verifyObject(IQuestionTarget, questiontarget)
49
    True
50
13014.2.4 by Curtis Hovey
Added sourcepackage_to_questiontarget to preserve code that is working with
51
SourcePackages are can be adapted to QuestionTargets.
4050.3.19 by Curtis Hovey
Revised test per review.
52
11235.5.4 by Curtis Hovey
hush lint.
53
    >>> evolution_in_hoary = ubuntu.currentseries.getSourcePackage(
54
    ...     'evolution')
4050.3.19 by Curtis Hovey
Revised test per review.
55
    >>> questiontarget = IQuestionTarget(evolution_in_hoary)
56
    >>> verifyObject(IQuestionTarget, questiontarget)
57
    True
4215.2.23 by Curtis Hovey
Removed trailing whitespace.
58
3691.398.21 by Francis J. Lacoste
Rename all attributes and variables.
59
You create a new question by calling the newQuestion() method of an
3691.398.18 by Francis J. Lacoste
Rename interfaces.
60
IQuestionTarget attribute.
2685.1.2 by Bjorn Tillenius
test that products works in accordance to ITicketTarget.
61
11235.5.4 by Curtis Hovey
hush lint.
62
    >>> sample_person = getUtility(IPersonSet).getByEmail(
63
    ...     'test@canonical.com')
3691.398.21 by Francis J. Lacoste
Rename all attributes and variables.
64
    >>> firefox_question = firefox.newQuestion(
65
    ...     sample_person, "Firefox question", "Unable to use Firefox")
3691.110.7 by Francis J. Lacoste
Added more documentation and removed tests that are redundant with test_tickettarget.py
66
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
67
The complete IQuestionTarget interface is documented in questiontarget.txt.
68
69
70
Official usage
71
==============
72
73
A product or distribution may be officially supported by the community using
11483.3.4 by j.c.sackett
Updated all doctest style files to use answers_usage.
74
the Answer Tracker.  This status is set by the answers_usage attribute on
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
75
the IProduct and IDistribution.
3960.2.2 by Curtis Hovey
Added official_answers to model.
76
11483.3.7 by j.c.sackett
Changed some wants and source in doctest style pages.
77
    >>> print ubuntu.answers_usage.name
78
    LAUNCHPAD
79
    >>> print firefox.answers_usage.name
80
    LAUNCHPAD
4215.2.23 by Curtis Hovey
Removed trailing whitespace.
81
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
82
83
IQuestion interface
84
===================
85
86
Questions are manipulated through the IQuestion interface.
87
11716.1.12 by Curtis Hovey
Sorted imports in doctests.
88
    >>> from zope.security.proxy import removeSecurityProxy
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
89
    >>> from lp.answers.interfaces.question import IQuestion
3691.197.109 by Francis J. Lacoste
- Add launchpad.Owner permission.
90
91
    # The complete interface is not necessarily available to the
92
    # logged in user.
3691.398.21 by Francis J. Lacoste
Rename all attributes and variables.
93
    >>> verifyObject(IQuestion, removeSecurityProxy(firefox_question))
94
    True
95
96
The person who submitted the question is available in the owner field.
97
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
98
    >>> firefox_question.owner
99
    <Person at ... name12 (Sample Person)>
3691.398.21 by Francis J. Lacoste
Rename all attributes and variables.
100
101
When the question is created, the owner is added to the question's
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
102
subscribers.
103
104
    >>> from operator import attrgetter
105
    >>> def print_subscribers(question):
106
    ...     people = [subscription.person
107
    ...               for subscription in question.subscriptions]
108
    ...     for person in sorted(people, key=attrgetter('name')):
109
    ...         print person.displayname
110
    >>> print_subscribers(firefox_question)
111
    Sample Person
112
113
The question status is 'Open'.
114
115
    >>> print firefox_question.status.title
116
    Open
117
118
The question has a creation time.
3691.110.7 by Francis J. Lacoste
Added more documentation and removed tests that are redundant with test_tickettarget.py
119
120
    >>> from datetime import datetime, timedelta
121
    >>> from pytz import UTC
122
    >>> now = datetime.now(UTC)
3691.398.21 by Francis J. Lacoste
Rename all attributes and variables.
123
    >>> now - firefox_question.datecreated < timedelta(seconds=5)
3691.110.7 by Francis J. Lacoste
Added more documentation and removed tests that are redundant with test_tickettarget.py
124
    True
125
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
126
The target onto which the question was created is also available.
3691.110.14 by Francis J. Lacoste
Folded the section on ITicketTarget to the interface test
127
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
128
    >>> print firefox_question.target.displayname
129
    Mozilla Firefox
3691.110.14 by Francis J. Lacoste
Folded the section on ITicketTarget to the interface test
130
3691.398.21 by Francis J. Lacoste
Rename all attributes and variables.
131
It is also possible to adapt a question to its IQuestionTarget.
3691.254.21 by Francis J. Lacoste
Add adapter from ITicket to ITicketTarget.
132
3691.398.21 by Francis J. Lacoste
Rename all attributes and variables.
133
    >>> target = IQuestionTarget(firefox_question)
3691.398.18 by Francis J. Lacoste
Rename interfaces.
134
    >>> verifyObject(IQuestionTarget, target)
3691.254.21 by Francis J. Lacoste
Add adapter from ITicket to ITicketTarget.
135
    True
4215.2.23 by Curtis Hovey
Removed trailing whitespace.
136
4050.3.14 by Curtis Hovey
Made revision per review.
137
The question can be assigned to a new IQuestionTarget.
4050.3.1 by Curtis Hovey
Added doc test, Interface, and DB for transfer question to another target.
138
139
    >>> thunderbird = getUtility(IProductSet)['thunderbird']
4050.3.14 by Curtis Hovey
Made revision per review.
140
    >>> firefox_question.target = thunderbird
4050.3.19 by Curtis Hovey
Revised test per review.
141
    >>> print firefox_question.target.displayname
4050.3.10 by Curtis Hovey
Updated pagetest to use the new form. Revised the code per the styleguide.
142
    Mozilla Thunderbird
4215.2.23 by Curtis Hovey
Removed trailing whitespace.
143
144
When a question is reassigned, its product, distribution and
4050.3.14 by Curtis Hovey
Made revision per review.
145
sourcepackagename attributes are reconciled with the IQuestionTarget.
4215.2.23 by Curtis Hovey
Removed trailing whitespace.
146
4050.3.14 by Curtis Hovey
Made revision per review.
147
    >>> firefox_question.target = ubuntu
4050.3.10 by Curtis Hovey
Updated pagetest to use the new form. Revised the code per the styleguide.
148
    >>> print firefox_question.target.displayname
149
    Ubuntu
4050.3.19 by Curtis Hovey
Revised test per review.
150
    >>> print firefox_question.distribution.name
4050.3.14 by Curtis Hovey
Made revision per review.
151
    ubuntu
152
    >>> print firefox_question.sourcepackagename
153
    None
154
    >>> print firefox_question.product
155
    None
4215.2.23 by Curtis Hovey
Removed trailing whitespace.
156
4050.3.19 by Curtis Hovey
Revised test per review.
157
    >>> firefox_question.target = evolution_in_ubuntu
4050.3.10 by Curtis Hovey
Updated pagetest to use the new form. Revised the code per the styleguide.
158
    >>> print firefox_question.target.displayname
12617.2.12 by Curtis Hovey
Fixed DSP displayname in tests.
159
    evolution in Ubuntu
4050.3.19 by Curtis Hovey
Revised test per review.
160
    >>> print firefox_question.distribution.name
4050.3.14 by Curtis Hovey
Made revision per review.
161
    ubuntu
4050.3.19 by Curtis Hovey
Revised test per review.
162
    >>> print firefox_question.sourcepackagename.name
4050.3.14 by Curtis Hovey
Made revision per review.
163
    evolution
164
    >>> print firefox_question.product
165
    None
4215.2.23 by Curtis Hovey
Removed trailing whitespace.
166
4050.3.8 by Curtis Hovey
Reverting questions-index.pt to RF.
167
    >>> firefox_question.target = firefox
4050.3.14 by Curtis Hovey
Made revision per review.
168
    >>> print firefox_question.target.displayname
169
    Mozilla Firefox
170
    >>> print firefox_question.distribution
171
    None
172
    >>> print firefox_question.sourcepackagename
173
    None
4050.3.19 by Curtis Hovey
Revised test per review.
174
    >>> print firefox_question.product.name
4050.3.14 by Curtis Hovey
Made revision per review.
175
    firefox
4215.2.23 by Curtis Hovey
Removed trailing whitespace.
176
177
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
178
Subscriptions and notifications
179
===============================
3691.121.3 by Francis J. Lacoste
* Do not subscribe support contacts to new tickets.
180
3691.398.21 by Francis J. Lacoste
Rename all attributes and variables.
181
Whenever a question is created or changed, email notifications will be
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
182
sent.  To receive such notification, one can subscribe to the bug using
3691.121.3 by Francis J. Lacoste
* Do not subscribe support contacts to new tickets.
183
the subscribe() method.
184
185
    >>> no_priv = getUtility(IPersonSet).getByName('no-priv')
3691.398.21 by Francis J. Lacoste
Rename all attributes and variables.
186
    >>> subscription = firefox_question.subscribe(no_priv)
3691.121.3 by Francis J. Lacoste
* Do not subscribe support contacts to new tickets.
187
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
188
The subscribers include the owner and the newly subscribed person.
3691.121.3 by Francis J. Lacoste
* Do not subscribe support contacts to new tickets.
189
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
190
    >>> print_subscribers(firefox_question)
191
    Sample Person
192
    No Privileges Person
3691.121.3 by Francis J. Lacoste
* Do not subscribe support contacts to new tickets.
193
7703.1.2 by Curtis Hovey
Backed out the QuestionSubscribersView. Renamed question get(*)Subscribers()
194
The getDirectSubscribers() method returns a sorted list of subscribers.
195
This method iterates like the NotificationRecipientSet returned by the
12906.3.8 by Curtis Hovey
Give properties proper names
196
direct_recipients method.
7703.1.2 by Curtis Hovey
Backed out the QuestionSubscribersView. Renamed question get(*)Subscribers()
197
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
198
    >>> for person in firefox_question.getDirectSubscribers():
199
    ...     print person.displayname
200
    No Privileges Person
201
    Sample Person
7703.1.2 by Curtis Hovey
Backed out the QuestionSubscribersView. Renamed question get(*)Subscribers()
202
3691.121.3 by Francis J. Lacoste
* Do not subscribe support contacts to new tickets.
203
To remove a person from the subscriptions list, we use the unsubscribe()
204
method.
205
13487.1.1 by Ian Booth
Add support for IQuestion.canBeUnsubscribedBy plus tests
206
    >>> firefox_question.unsubscribe(no_priv, no_priv)
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
207
    >>> print_subscribers(firefox_question)
208
    Sample Person
3691.121.3 by Francis J. Lacoste
* Do not subscribe support contacts to new tickets.
209
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
210
The people on the subscription list are said to be directly subscribed to the
211
question.  They explicitly chose to get notifications about that particular
12906.3.8 by Curtis Hovey
Give properties proper names
212
question.  This list of people is available through the direct_recipients
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
213
method.
3691.121.3 by Francis J. Lacoste
* Do not subscribe support contacts to new tickets.
214
12906.3.8 by Curtis Hovey
Give properties proper names
215
    >>> subscribers = firefox_question.direct_recipients
4231.1.4 by Francis J. Lacoste
Make getSubscribers(), getDirectSusbcribers() and getIndirectSubscribers() return INotificationRecipients.
216
217
That method returns an INotificationRecipientSet, containing the direct
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
218
subscribers along with the rationale for contacting them.
4231.1.4 by Francis J. Lacoste
Make getSubscribers(), getDirectSusbcribers() and getIndirectSubscribers() return INotificationRecipients.
219
14557.1.18 by Curtis Hovey
Extracted INotificationRecipientSet and UnknownRecipientError to lp.services.mail.
220
    >>> from lp.services.mail.interfaces import INotificationRecipientSet
4231.1.4 by Francis J. Lacoste
Make getSubscribers(), getDirectSusbcribers() and getIndirectSubscribers() return INotificationRecipients.
221
    >>> verifyObject(INotificationRecipientSet, subscribers)
222
    True
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
223
    >>> def print_reason(subscribers):
224
    ...     for person in subscribers:
225
    ...         text, header = subscribers.getReason(person)
226
    ...         print header, person.displayname, text
227
    >>> print_reason(subscribers)
12906.3.5 by Curtis Hovey
Explain the the question owner that he is the "asker".
228
    Asker Sample Person
229
    You received this question notification because you asked the question.
3691.121.3 by Francis J. Lacoste
* Do not subscribe support contacts to new tickets.
230
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
231
There is also a list of 'indirect' subscribers to the question.  These are
232
people that didn't explicitly subscribe to the question, but that will receive
233
notifications for other reasons.  Answer contacts for the question target are
234
part of the indirect subscribers list.
3691.121.3 by Francis J. Lacoste
* Do not subscribe support contacts to new tickets.
235
3881.1.1 by Francis J. Lacoste
Renamed reference to support tracker in doctests.
236
    # There are no answer contacts on the firefox product.
12906.3.8 by Curtis Hovey
Give properties proper names
237
    >>> list(firefox_question.indirect_recipients)
3691.121.3 by Francis J. Lacoste
* Do not subscribe support contacts to new tickets.
238
    []
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
239
240
    >>> from lp.services.worlddata.interfaces.language import ILanguageSet
4215.2.15 by Curtis Hovey
Added English to Lp. Rvised tests; removing old rules and added new rule. Translation tests probably fail. This branch needs some cleaning too.
241
    >>> english = getUtility(ILanguageSet)['en']
242
    >>> no_priv.addLanguage(english)
12959.4.21 by Curtis Hovey
Alway pass the subscribed_by argument to addAnswerContact.
243
    >>> firefox.addAnswerContact(no_priv, no_priv)
3691.121.3 by Francis J. Lacoste
* Do not subscribe support contacts to new tickets.
244
    True
4231.1.4 by Francis J. Lacoste
Make getSubscribers(), getDirectSusbcribers() and getIndirectSubscribers() return INotificationRecipients.
245
12906.3.1 by Curtis Hovey
Convert question recipient methods into cached properties.
246
    >>> from lp.services.propertycache import get_property_cache
12906.3.8 by Curtis Hovey
Give properties proper names
247
    >>> del get_property_cache(firefox_question).indirect_recipients
248
    >>> indirect_subscribers = firefox_question.indirect_recipients
4231.1.4 by Francis J. Lacoste
Make getSubscribers(), getDirectSusbcribers() and getIndirectSubscribers() return INotificationRecipients.
249
    >>> verifyObject(INotificationRecipientSet, indirect_subscribers)
250
    True
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
251
    >>> print_reason(indirect_subscribers)
252
    Answer Contact (Mozilla Firefox) No Privileges Person
253
    You received this question notification because you are an answer
254
    contact for Mozilla Firefox.
3691.121.3 by Francis J. Lacoste
* Do not subscribe support contacts to new tickets.
255
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
256
There is a special case for when the question is associated with a source
257
package.  The answer contacts for both the distribution and the source package
258
are part of the indirect subscribers list.
3691.121.3 by Francis J. Lacoste
* Do not subscribe support contacts to new tickets.
259
3881.1.1 by Francis J. Lacoste
Renamed reference to support tracker in doctests.
260
    # Let's register some answer contacts for the distribution and
3691.247.5 by Francis J. Lacoste
Sort subscribers by displayname.
261
    # the package.
3691.398.20 by Francis J. Lacoste
Rename all methods.
262
    >>> list(ubuntu.answer_contacts)
3691.121.3 by Francis J. Lacoste
* Do not subscribe support contacts to new tickets.
263
    []
4050.3.19 by Curtis Hovey
Revised test per review.
264
    >>> list(evolution_in_ubuntu.answer_contacts)
3691.121.3 by Francis J. Lacoste
* Do not subscribe support contacts to new tickets.
265
    []
266
    >>> ubuntu_team = getUtility(IPersonSet).getByName('ubuntu-team')
4215.2.15 by Curtis Hovey
Added English to Lp. Rvised tests; removing old rules and added new rule. Translation tests probably fail. This branch needs some cleaning too.
267
    >>> ubuntu_team.addLanguage(english)
12959.4.21 by Curtis Hovey
Alway pass the subscribed_by argument to addAnswerContact.
268
    >>> ubuntu.addAnswerContact(ubuntu_team, ubuntu_team.teamowner)
3691.398.20 by Francis J. Lacoste
Rename all methods.
269
    True
12959.4.21 by Curtis Hovey
Alway pass the subscribed_by argument to addAnswerContact.
270
    >>> evolution_in_ubuntu.addAnswerContact(no_priv, no_priv)
3691.398.20 by Francis J. Lacoste
Rename all methods.
271
    True
4050.3.19 by Curtis Hovey
Revised test per review.
272
    >>> package_question = evolution_in_ubuntu.newQuestion(
3943.2.1 by Curtis Hovey
Added Answer Contacts to sample data.
273
    ...     sample_person, 'Upgrading to Evolution 1.4 breaks plug-ins',
274
    ...     "The FnordsHighlighter plug-in doesn't work after upgrade.")
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
275
276
    >>> print_subscribers(package_question)
277
    Sample Person
278
12906.3.8 by Curtis Hovey
Give properties proper names
279
    >>> del get_property_cache(firefox_question).indirect_recipients
280
    >>> indirect_subscribers = package_question.indirect_recipients
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
281
    >>> for person in indirect_subscribers:
282
    ...     print person.displayname
283
    No Privileges Person
284
    Ubuntu Team
285
286
    >>> text, header = indirect_subscribers.getReason(ubuntu_team)
287
    >>> print header, text
288
    Answer Contact (ubuntu) @ubuntu-team
289
    You received this question notification because you are a member of
290
    Ubuntu Team, which is an answer contact for Ubuntu.
3691.121.3 by Francis J. Lacoste
* Do not subscribe support contacts to new tickets.
291
3691.398.21 by Francis J. Lacoste
Rename all attributes and variables.
292
The question's assignee is also part of the indirect subscription list:
3691.247.1 by Francis J. Lacoste
Add assignee to indirect subscription list.
293
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
294
    >>> login('admin@canonical.com')
3691.398.21 by Francis J. Lacoste
Rename all attributes and variables.
295
    >>> package_question.assignee = getUtility(IPersonSet).getByName('name16')
12906.3.8 by Curtis Hovey
Give properties proper names
296
    >>> del get_property_cache(package_question).indirect_recipients
297
    >>> indirect_subscribers = package_question.indirect_recipients
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
298
    >>> for person in indirect_subscribers:
299
    ...     print person.displayname
300
    Foo Bar
301
    No Privileges Person
302
    Ubuntu Team
303
304
    >>> text, header = indirect_subscribers.getReason(
305
    ...     package_question.assignee)
306
    >>> print header, text
307
    Assignee
308
    You received this question notification because you are the assignee for
309
    this question.
3691.247.1 by Francis J. Lacoste
Add assignee to indirect subscription list.
310
12906.3.8 by Curtis Hovey
Give properties proper names
311
The getIndirectSubscribers() method iterates like the indirect_recipients
7703.1.2 by Curtis Hovey
Backed out the QuestionSubscribersView. Renamed question get(*)Subscribers()
312
method, but it returns a sorted list instead of a NotificationRecipientSet.
313
It too contains the question assignee.
314
315
    >>> indirect_subscribers = package_question.getIndirectSubscribers()
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
316
    >>> for person in indirect_subscribers:
317
    ...     print person.displayname
318
    Foo Bar
319
    No Privileges Person
320
    Ubuntu Team
7703.1.2 by Curtis Hovey
Backed out the QuestionSubscribersView. Renamed question get(*)Subscribers()
321
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
322
Notifications are sent to the list of direct and indirect subscribers.  The
323
notification recipients list can be obtained by using the getRecipients()
324
method.
3691.121.3 by Francis J. Lacoste
* Do not subscribe support contacts to new tickets.
325
3691.247.1 by Francis J. Lacoste
Add assignee to indirect subscription list.
326
    >>> login('no-priv@canonical.com')
7703.1.2 by Curtis Hovey
Backed out the QuestionSubscribersView. Renamed question get(*)Subscribers()
327
    >>> subscribers = firefox_question.getRecipients()
4231.1.4 by Francis J. Lacoste
Make getSubscribers(), getDirectSusbcribers() and getIndirectSubscribers() return INotificationRecipients.
328
    >>> verifyObject(INotificationRecipientSet, subscribers)
329
    True
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
330
    >>> for person in subscribers:
331
    ...     print person.displayname
332
    No Privileges Person
333
    Sample Person
334
335
More documentation on the question notifications can be found in
336
`answer-tracker-notifications.txt`.
337
338
339
Workflow
340
========
3691.197.11 by Francis J. Lacoste
Move workflow tests to support-tracker-workflow.txt
341
3691.398.21 by Francis J. Lacoste
Rename all attributes and variables.
342
A question status should not be manipulated directly but through the
3691.197.11 by Francis J. Lacoste
Move workflow tests to support-tracker-workflow.txt
343
workflow methods.
344
3691.398.21 by Francis J. Lacoste
Rename all attributes and variables.
345
The complete question workflow is documented in
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
346
`answer-tracker-workflow.txt`.
347
348
349
Bug linking
350
===========
3691.109.7 by Francis J. Lacoste
Add tests for special requirements of linkBug and unlinkBug in Ticket implementation
351
3691.398.19 by Francis J. Lacoste
Rename most remaining classes (views, database, authorizations, notifications, scripts.)
352
Question implements the IBugLinkTarget interface which makes it possible
3691.398.21 by Francis J. Lacoste
Rename all attributes and variables.
353
to link bug report to question.
3691.109.7 by Francis J. Lacoste
Add tests for special requirements of linkBug and unlinkBug in Ticket implementation
354
10409.5.14 by Curtis Hovey
Removed glob imports for lp.bugs.
355
    >>> from lp.bugs.interfaces.buglink import IBugLinkTarget
3691.398.21 by Francis J. Lacoste
Rename all attributes and variables.
356
    >>> verifyObject(IBugLinkTarget, firefox_question)
3691.109.7 by Francis J. Lacoste
Add tests for special requirements of linkBug and unlinkBug in Ticket implementation
357
    True
358
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
359
See ../../bugs/tests/buglinktarget.txt for the documentation and test of the
360
IBugLinkTarget interface.
361
362
When a bug is linked to a question, the question's owner is subscribed to the
363
bug.
364
365
    >>> from lp.bugs.interfaces.bug import IBugSet
3691.109.7 by Francis J. Lacoste
Add tests for special requirements of linkBug and unlinkBug in Ticket implementation
366
    >>> bug7 = getUtility(IBugSet).get(7)
3691.398.21 by Francis J. Lacoste
Rename all attributes and variables.
367
    >>> bug7.isSubscribed(firefox_question.owner)
3691.109.7 by Francis J. Lacoste
Add tests for special requirements of linkBug and unlinkBug in Ticket implementation
368
    False
3691.398.21 by Francis J. Lacoste
Rename all attributes and variables.
369
    >>> firefox_question.linkBug(bug7)
3691.398.19 by Francis J. Lacoste
Rename most remaining classes (views, database, authorizations, notifications, scripts.)
370
    <QuestionBug...>
3691.398.21 by Francis J. Lacoste
Rename all attributes and variables.
371
    >>> bug7.isSubscribed(firefox_question.owner)
3691.109.7 by Francis J. Lacoste
Add tests for special requirements of linkBug and unlinkBug in Ticket implementation
372
    True
373
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
374
When the link is removed, the owner is unsubscribed.
3691.109.7 by Francis J. Lacoste
Add tests for special requirements of linkBug and unlinkBug in Ticket implementation
375
3691.398.21 by Francis J. Lacoste
Rename all attributes and variables.
376
    >>> firefox_question.unlinkBug(bug7)
3691.398.19 by Francis J. Lacoste
Rename most remaining classes (views, database, authorizations, notifications, scripts.)
377
    <QuestionBug...>
3691.398.21 by Francis J. Lacoste
Rename all attributes and variables.
378
    >>> bug7.isSubscribed(firefox_question.owner)
3691.109.7 by Francis J. Lacoste
Add tests for special requirements of linkBug and unlinkBug in Ticket implementation
379
    False
4004.4.9 by Curtis Hovey
Revised reconciled tests and code for Unsupported Questions.
380
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
381
382
Unsupported questions
383
=====================
384
385
While a Person may ask questions in his language of choice, that does not mean
386
that indirect subscribers (Answer Contacts) to an IQuestionTarget speak that
387
language.  IQuestionTarget can return a list Questions in languages that are
388
not supported.
4004.4.1 by Curtis Hovey
Added doc test for Unsupported Questions.
389
4004.4.23 by Curtis Hovey
Switched QT implementers searchQuestions to use unsupported=False. Switched QT.SearchQuestions to use unsupported=None; implementer may pass self. Removed unreachable product list from QuestionSearch.getTargetConstraints.
390
    >>> unsupported_questions = firefox.searchQuestions(unsupported=True)
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
391
    >>> sorted(question.title for question in unsupported_questions)
4004.4.2 by Curtis Hovey
Added interfaces and implementation for Unsupported Questions.
392
    [u'Problemas de Impress\xe3o no Firefox']
4215.2.23 by Curtis Hovey
Removed trailing whitespace.
393
4050.3.23 by Curtis Hovey
Revised test after variable name change.
394
    >>> unsupported_questions = evolution_in_ubuntu.searchQuestions(
4004.4.22 by Curtis Hovey
Changed unsupported to a boolean value in QuestionTargetSearch.
395
    ...     unsupported=True)
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
396
    >>> sorted(question.title for question in unsupported_questions)
4004.4.2 by Curtis Hovey
Added interfaces and implementation for Unsupported Questions.
397
    []
398
399
    >>> warty_question_target = IQuestionTarget(ubuntu_warty)
4004.4.9 by Curtis Hovey
Revised reconciled tests and code for Unsupported Questions.
400
    >>> unsupported_questions = warty_question_target.searchQuestions(
4004.4.23 by Curtis Hovey
Switched QT implementers searchQuestions to use unsupported=False. Switched QT.SearchQuestions to use unsupported=None; implementer may pass self. Removed unreachable product list from QuestionSearch.getTargetConstraints.
401
    ...     unsupported=True)
7675.518.1 by Barry Warsaw
Reformat the questions.txt doctest to our preferred style.
402
    >>> sorted(question.title for question in unsupported_questions)
4443.1.6 by Curtis Hovey
Added an arabic question and a test that it displays right-to-left.
403
    [u'Problema al recompilar kernel con soporte smp (doble-n\xfacleo)',
404
     u'\u0639\u0643\u0633 \u0627\u0644\u062a\u063a\u064a\u064a\u0631...]