7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
1 |
======================= |
2 |
Answer tracker workflow |
|
3 |
======================= |
|
4 |
||
5 |
The state of a question is tracked through its status, which model a |
|
6 |
question's lifecycle. These are defined in the QuestionStatus enumeration. |
|
7 |
||
12915.5.1
by Curtis Hovey
Rename questionenums.py to the new standard or enums.py |
8 |
>>> from lp.answers.enums import QuestionStatus |
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
9 |
>>> for status in QuestionStatus.items: |
10 |
... print status.name |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
11 |
OPEN |
12 |
NEEDSINFO |
|
13 |
ANSWERED |
|
3691.197.22
by Francis J. Lacoste
Rename ANSWERED_CONFIRMED to SOLVED |
14 |
SOLVED |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
15 |
EXPIRED |
16 |
INVALID |
|
17 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
18 |
Status change occurs as a consequence of a user's action. The possible |
3691.398.17
by Francis J. Lacoste
Rename dbschemas. |
19 |
actions are defined in the QuestionAction enumeration. |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
20 |
|
12915.5.1
by Curtis Hovey
Rename questionenums.py to the new standard or enums.py |
21 |
>>> from lp.answers.enums import QuestionAction |
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
22 |
>>> for status in QuestionAction.items: |
23 |
... print status.name |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
24 |
REQUESTINFO |
25 |
GIVEINFO |
|
26 |
COMMENT |
|
27 |
ANSWER |
|
28 |
CONFIRM |
|
29 |
REJECT |
|
30 |
EXPIRE |
|
31 |
REOPEN |
|
3691.197.16
by Francis J. Lacoste
- Add setStatus() and addComment() methods. |
32 |
SETSTATUS |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
33 |
|
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
34 |
Each defined action can be executed. |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
35 |
|
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
36 |
No Privileges Person is the submitter of questions. Sample Person is an |
37 |
answer contact for the Ubuntu distribution. Marilize Coetze is another user |
|
38 |
providing support. Stub is a Launchpad administrator that isn't also in the |
|
39 |
Ubuntu Team owning the distribution. |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
40 |
|
41 |
>>> login('no-priv@canonical.com') |
|
42 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
43 |
>>> from lp.registry.interfaces.distribution import IDistributionSet |
44 |
>>> from lp.registry.interfaces.person import IPersonSet |
|
45 |
>>> from lp.services.worlddata.interfaces.language import ILanguageSet |
|
3691.197.61
by Francis J. Lacoste
Add sanity check for admin not being an ubuntu Team member |
46 |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
47 |
>>> personset = getUtility(IPersonSet) |
48 |
>>> sample_person = personset.getByEmail('test@canonical.com') |
|
49 |
>>> no_priv = personset.getByEmail('no-priv@canonical.com') |
|
50 |
>>> marilize = personset.getByEmail('marilize@hbd.com') |
|
3691.197.16
by Francis J. Lacoste
- Add setStatus() and addComment() methods. |
51 |
>>> stub = personset.getByName('stub') |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
52 |
|
53 |
>>> ubuntu = getUtility(IDistributionSet)['ubuntu'] |
|
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. |
54 |
>>> english = getUtility(ILanguageSet)['en'] |
55 |
>>> sample_person.addLanguage(english) |
|
12959.4.21
by Curtis Hovey
Alway pass the subscribed_by argument to addAnswerContact. |
56 |
>>> ubuntu.addAnswerContact(sample_person, sample_person) |
3691.197.11
by Francis J. Lacoste
Move workflow tests to support-tracker-workflow.txt |
57 |
True |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
58 |
|
3691.259.2
by Francis J. Lacoste
Convert to Moin-style headers, convert () comments to regular python comments. |
59 |
# Sanity check: the admin isn't in the team owning the distribution. |
3691.197.61
by Francis J. Lacoste
Add sanity check for admin not being an ubuntu Team member |
60 |
>>> stub.inTeam(ubuntu.owner) |
61 |
False |
|
62 |
||
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
63 |
A question starts its lifecycle in the Open state. |
3691.197.11
by Francis J. Lacoste
Move workflow tests to support-tracker-workflow.txt |
64 |
|
65 |
>>> from datetime import datetime, timedelta |
|
66 |
>>> from pytz import UTC |
|
67 |
>>> now = datetime.now(UTC) |
|
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
68 |
>>> new_question_args = dict( |
69 |
... owner=no_priv, |
|
70 |
... title='Unable to boot installer', |
|
71 |
... description="I've tried installing Ubuntu on a Mac. " |
|
72 |
... "But the installer never boots.", |
|
73 |
... datecreated=now, |
|
74 |
... ) |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
75 |
>>> question = ubuntu.newQuestion(**new_question_args) |
76 |
>>> print question.status.title |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
77 |
Open |
78 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
79 |
The following scenarios are now possible. |
80 |
||
81 |
||
82 |
1) Another user helps the submitter with his question |
|
83 |
===================================================== |
|
84 |
||
85 |
The most common scenario is where another user comes to help the submitter and |
|
86 |
answers his question. This may involve exchanging information with the |
|
87 |
submitter to clarify the question. |
|
88 |
||
89 |
The requestInfo() method is used to ask the user for more information. This |
|
90 |
method takes two mandatory parameters: the user asking the question and his |
|
91 |
question. It can also takes a 'datecreated' parameter specifying the creation |
|
92 |
date of the question (which defaults to 'now'). |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
93 |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
94 |
>>> question = ubuntu.newQuestion(**new_question_args) |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
95 |
>>> now_plus_one_hour = now + timedelta(hours=1) |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
96 |
>>> request_message = question.requestInfo( |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
97 |
... sample_person, 'What is your Mac model?', |
98 |
... datecreated=now_plus_one_hour) |
|
99 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
100 |
We now have the IQuestionMessage that was added to the question messages |
101 |
history. |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
102 |
|
4682.1.6
by Christian Reis
Use webapp.testing's verifyObject in all doctests, which copes with security-proxied objects, and remove the crack I added to the bug and bugtask uses of it. |
103 |
>>> from canonical.launchpad.webapp.testing import verifyObject |
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
104 |
>>> from lp.answers.interfaces.questionmessage import IQuestionMessage |
3691.398.18
by Francis J. Lacoste
Rename interfaces. |
105 |
>>> verifyObject(IQuestionMessage, request_message) |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
106 |
True |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
107 |
>>> request_message == question.messages[-1] |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
108 |
True |
109 |
>>> request_message.datecreated == now_plus_one_hour |
|
110 |
True |
|
111 |
>>> print request_message.owner.displayname |
|
112 |
Sample Person |
|
113 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
114 |
The question message contains the action that was executed and the status of |
115 |
the question after the action was executed. |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
116 |
|
117 |
>>> print request_message.action.name |
|
118 |
REQUESTINFO |
|
3691.197.55
by Francis J. Lacoste
Rename newstatus to new_status as per new naming convention. Renamed foreign key to ticket__answer__fk as requested by stub. |
119 |
>>> print request_message.new_status.name |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
120 |
NEEDSINFO |
121 |
||
122 |
>>> print request_message.text_contents |
|
123 |
What is your Mac model? |
|
124 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
125 |
The subject of the message was generated automatically. |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
126 |
|
127 |
>>> print request_message.subject |
|
128 |
Re: Unable to boot installer |
|
129 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
130 |
The question is moved to the NEEDSINFO state and the last response date is |
131 |
updated to the message's timestamp. |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
132 |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
133 |
>>> print question.status.name |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
134 |
NEEDSINFO |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
135 |
>>> question.datelastresponse == now_plus_one_hour |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
136 |
True |
137 |
||
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
138 |
The question owner can reply to this information by using the giveInfo() |
3691.398.18
by Francis J. Lacoste
Rename interfaces. |
139 |
method which adds an IQuestionMessage with action GIVEINFO. |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
140 |
|
3691.197.109
by Francis J. Lacoste
- Add launchpad.Owner permission. |
141 |
>>> login('no-priv@canonical.com') |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
142 |
>>> now_plus_two_hours = now + timedelta(hours=2) |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
143 |
>>> reply_message = question.giveInfo( |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
144 |
... "I have a PowerMac 7200.", datecreated=now_plus_two_hours) |
145 |
||
146 |
>>> print reply_message.action.name |
|
147 |
GIVEINFO |
|
3691.197.55
by Francis J. Lacoste
Rename newstatus to new_status as per new naming convention. Renamed foreign key to ticket__answer__fk as requested by stub. |
148 |
>>> print reply_message.new_status.name |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
149 |
OPEN |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
150 |
>>> reply_message == question.messages[-1] |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
151 |
True |
152 |
>>> print reply_message.owner.displayname |
|
153 |
No Privileges Person |
|
154 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
155 |
The question is moved back to the OPEN state and the last query date is |
156 |
updated to the message's creation date. |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
157 |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
158 |
>>> print question.status.name |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
159 |
OPEN |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
160 |
>>> question.datelastquery == now_plus_two_hours |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
161 |
True |
162 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
163 |
Now, the other user has enough information to give an answer to the question. |
164 |
The giveAnswer() method is used for that purpose. Like the requestInfo() |
|
165 |
method, it takes two mandatory parameters: the user providing the answer and |
|
166 |
the answer itself. |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
167 |
|
3691.197.109
by Francis J. Lacoste
- Add launchpad.Owner permission. |
168 |
>>> login('test@canonical.com') |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
169 |
>>> now_plus_three_hours = now + timedelta(hours=3) |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
170 |
>>> answer_message = question.giveAnswer( |
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
171 |
... sample_person, |
172 |
... "You need some configuration on the Mac side " |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
173 |
... "to boot the installer on that model. Consult " |
174 |
... "https://help.ubuntu.com/community/Installation/OldWorldMacs " |
|
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
175 |
... "for all the details.", |
176 |
... datecreated=now_plus_three_hours) |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
177 |
>>> print answer_message.action.name |
178 |
ANSWER |
|
3691.197.55
by Francis J. Lacoste
Rename newstatus to new_status as per new naming convention. Renamed foreign key to ticket__answer__fk as requested by stub. |
179 |
>>> print answer_message.new_status.name |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
180 |
ANSWERED |
181 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
182 |
The question's status is changed to ANSWERED and the last response date is |
183 |
updated to contain the date of the message. |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
184 |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
185 |
>>> print question.status.name |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
186 |
ANSWERED |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
187 |
>>> question.datelastresponse == now_plus_three_hours |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
188 |
True |
189 |
||
3881.1.1
by Francis J. Lacoste
Renamed reference to support tracker in doctests. |
190 |
At that point, the question is considered answered, but we don't have |
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
191 |
feedback from the user on whether it solved his problem or not. If it |
192 |
doesn't, the user can reopen the question. |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
193 |
|
3691.197.109
by Francis J. Lacoste
- Add launchpad.Owner permission. |
194 |
>>> login('no-priv@canonical.com') |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
195 |
>>> tomorrow = now + timedelta(days=1) |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
196 |
>>> reopen_message = question.reopen( |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
197 |
... "I installed BootX and I've progressed somewhat. I now get the " |
198 |
... "boot screen. But soon after the Ubuntu progress bar appears, I " |
|
199 |
... "get a OOM Killer message appearing on the screen.", |
|
200 |
... datecreated=tomorrow) |
|
201 |
>>> print reopen_message.action.name |
|
202 |
REOPEN |
|
3691.197.55
by Francis J. Lacoste
Rename newstatus to new_status as per new naming convention. Renamed foreign key to ticket__answer__fk as requested by stub. |
203 |
>>> print reopen_message.new_status.name |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
204 |
OPEN |
205 |
>>> print reopen_message.owner.displayname |
|
206 |
No Privileges Person |
|
207 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
208 |
This moves back the question to the OPEN state and the last query date is |
209 |
updated to the message's creation date. |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
210 |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
211 |
>>> print question.status.name |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
212 |
OPEN |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
213 |
>>> question.datelastquery == tomorrow |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
214 |
True |
215 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
216 |
Once again, an answer is given. |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
217 |
|
3691.197.109
by Francis J. Lacoste
- Add launchpad.Owner permission. |
218 |
>>> login('test@canonical.com') |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
219 |
>>> tomorrow_plus_one_hour = tomorrow + timedelta(hours=1) |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
220 |
>>> answer2_message = question.giveAnswer( |
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
221 |
... marilize, |
222 |
... "You probably do not have enough RAM to use the " |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
223 |
... "graphical installer. You can try the alternate CD with the " |
224 |
... "text installer.") |
|
225 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
226 |
The question is moved back to the ANSWERED state. |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
227 |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
228 |
>>> print question.status.name |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
229 |
ANSWERED |
230 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
231 |
The question owner will hopefully come back to confirm that his problem is |
232 |
solved. He can specify which answer message helped him solved his problem. |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
233 |
|
3691.197.109
by Francis J. Lacoste
- Add launchpad.Owner permission. |
234 |
>>> login('no-priv@canonical.com') |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
235 |
>>> two_weeks_from_now = now + timedelta(days=14) |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
236 |
>>> confirm_message = question.confirmAnswer( |
11235.5.4
by Curtis Hovey
hush lint. |
237 |
... "I upgraded to 512M of RAM (found on eBay) and I've successfully " |
238 |
... "managed to install Ubuntu. Thanks for all the help.", |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
239 |
... datecreated=two_weeks_from_now, answer=answer_message) |
240 |
>>> print confirm_message.action.name |
|
241 |
CONFIRM |
|
3691.197.55
by Francis J. Lacoste
Rename newstatus to new_status as per new naming convention. Renamed foreign key to ticket__answer__fk as requested by stub. |
242 |
>>> print confirm_message.new_status.name |
3691.197.22
by Francis J. Lacoste
Rename ANSWERED_CONFIRMED to SOLVED |
243 |
SOLVED |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
244 |
>>> print confirm_message.owner.displayname |
245 |
No Privileges Person |
|
246 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
247 |
The question is moved to the SOLVED state, and the message that solved the |
248 |
question is saved. The date the question was solved and answerer are also |
|
249 |
updated. |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
250 |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
251 |
>>> print question.status.name |
3691.197.22
by Francis J. Lacoste
Rename ANSWERED_CONFIRMED to SOLVED |
252 |
SOLVED |
4664.2.4
by Curtis Hovey
Renamed attribute from datesolved to date_solved. Doh. This was |
253 |
>>> question.date_solved == two_weeks_from_now |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
254 |
True |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
255 |
>>> print question.answerer.displayname |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
256 |
Sample Person |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
257 |
>>> question.answer == answer_message |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
258 |
True |
259 |
||
4471.5.8
by Curtis Hovey
Revision per review. More work is needed in test_question_workflow.py. |
260 |
|
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
261 |
2) Self-answering |
262 |
================= |
|
263 |
||
264 |
In this scenario the user comes back to give the solution to the question |
|
265 |
himself. The question owner can choose a best answer message later on. The |
|
266 |
workflow permits the question owner to choose an answer before or after the |
|
267 |
question status is set to SOLVED. |
|
268 |
||
269 |
A new question is posed. |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
270 |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
271 |
>>> question = ubuntu.newQuestion(**new_question_args) |
4471.5.1
by Curtis Hovey
Revised workflow to allow the question own to set the question status to Solved without selecting an answser first. An Answer can be confirmed while in the solved state. |
272 |
|
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
273 |
The answer provides some useful information to the questioner. |
4471.5.8
by Curtis Hovey
Revision per review. More work is needed in test_question_workflow.py. |
274 |
|
4471.5.1
by Curtis Hovey
Revised workflow to allow the question own to set the question status to Solved without selecting an answser first. An Answer can be confirmed while in the solved state. |
275 |
>>> login('test@canonical.com') |
276 |
>>> tomorrow_plus_one_hour = tomorrow + timedelta(hours=1) |
|
277 |
>>> alt_answer_message = question.giveAnswer( |
|
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
278 |
... marilize, |
279 |
... "Are you using a pre-G3 Mac? They are very difficult " |
|
4471.5.1
by Curtis Hovey
Revised workflow to allow the question own to set the question status to Solved without selecting an answser first. An Answer can be confirmed while in the solved state. |
280 |
... "to install to. You must mess with the hardware to trick " |
281 |
... "the core chips to let it install. You may not want to do this.") |
|
282 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
283 |
The question has researched the problem, and has comes to a solution himself. |
4471.5.8
by Curtis Hovey
Revision per review. More work is needed in test_question_workflow.py. |
284 |
|
4471.5.1
by Curtis Hovey
Revised workflow to allow the question own to set the question status to Solved without selecting an answser first. An Answer can be confirmed while in the solved state. |
285 |
>>> login('no-priv@canonical.com') |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
286 |
>>> self_answer_message = question.giveAnswer( |
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
287 |
... no_priv, |
288 |
... "I found some instructions on the Wiki on how to " |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
289 |
... "install BootX to boot the installation CD on OldWorld Mac: " |
290 |
... "https://help.ubuntu.com/community/Installation/OldWorldMacs " |
|
291 |
... "This is complicated and since it's a very old machine, not " |
|
292 |
... "worth the trouble.", |
|
293 |
... datecreated=now_plus_one_hour) |
|
294 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
295 |
The question owner is considered to have given information that the problem is |
296 |
solved and the question is moved to the SOLVED state. The 'answerer' |
|
297 |
will be the question owner. |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
298 |
|
299 |
>>> print self_answer_message.action.name |
|
300 |
CONFIRM |
|
3691.197.55
by Francis J. Lacoste
Rename newstatus to new_status as per new naming convention. Renamed foreign key to ticket__answer__fk as requested by stub. |
301 |
>>> print self_answer_message.new_status.name |
3691.197.22
by Francis J. Lacoste
Rename ANSWERED_CONFIRMED to SOLVED |
302 |
SOLVED |
4471.5.8
by Curtis Hovey
Revision per review. More work is needed in test_question_workflow.py. |
303 |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
304 |
>>> print question.status.name |
3691.197.22
by Francis J. Lacoste
Rename ANSWERED_CONFIRMED to SOLVED |
305 |
SOLVED |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
306 |
>>> print question.answerer.displayname |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
307 |
No Privileges Person |
4664.2.4
by Curtis Hovey
Renamed attribute from datesolved to date_solved. Doh. This was |
308 |
>>> question.date_solved == now_plus_one_hour |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
309 |
True |
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
310 |
>>> print question.answer |
311 |
None |
|
4471.5.1
by Curtis Hovey
Revised workflow to allow the question own to set the question status to Solved without selecting an answser first. An Answer can be confirmed while in the solved state. |
312 |
|
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
313 |
The question owner can still specify which message helped him solved his |
314 |
problem. The confirmAnswer() method is used when the question owner chooses |
|
315 |
another user's answer as a best answer. The status will remain SOLVED. The |
|
316 |
'answerer' will be the message owner, and the 'answer' will be the message. |
|
317 |
The question's solution date will be the date of the answer message. |
|
4471.5.1
by Curtis Hovey
Revised workflow to allow the question own to set the question status to Solved without selecting an answser first. An Answer can be confirmed while in the solved state. |
318 |
|
319 |
>>> confirm_message = question.confirmAnswer( |
|
320 |
... "Thanks Marilize for your help. I don't think I'll put Ubuntu " |
|
321 |
... "Ubuntu on my Mac.", |
|
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
322 |
... datecreated=now_plus_one_hour, |
323 |
... answer=alt_answer_message) |
|
4471.5.1
by Curtis Hovey
Revised workflow to allow the question own to set the question status to Solved without selecting an answser first. An Answer can be confirmed while in the solved state. |
324 |
>>> print confirm_message.action.name |
325 |
CONFIRM |
|
326 |
>>> print confirm_message.new_status.name |
|
327 |
SOLVED |
|
328 |
>>> print confirm_message.owner.displayname |
|
329 |
No Privileges Person |
|
330 |
||
4471.5.8
by Curtis Hovey
Revision per review. More work is needed in test_question_workflow.py. |
331 |
>>> print question.status.name |
332 |
SOLVED |
|
333 |
>>> print question.answerer.displayname |
|
334 |
Marilize Coetzee |
|
335 |
>>> question.answer == alt_answer_message |
|
336 |
True |
|
4664.2.4
by Curtis Hovey
Renamed attribute from datesolved to date_solved. Doh. This was |
337 |
>>> question.date_solved == now_plus_one_hour |
4471.5.8
by Curtis Hovey
Revision per review. More work is needed in test_question_workflow.py. |
338 |
True |
339 |
||
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
340 |
|
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
341 |
3) The question expires |
342 |
======================= |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
343 |
|
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
344 |
It is also possible that nobody will answer the question, either because the |
345 |
question is too complex or too vague. These questions are expired by using |
|
346 |
the expireQuestion() method. |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
347 |
|
3691.197.109
by Francis J. Lacoste
- Add launchpad.Owner permission. |
348 |
>>> login('no-priv@canonical.com') |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
349 |
>>> question = ubuntu.newQuestion(**new_question_args) |
350 |
>>> expire_message = question.expireQuestion( |
|
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
351 |
... sample_person, |
352 |
... "There was no activity on this question for two " |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
353 |
... "weeks and this question was expired. If you are still having " |
3881.1.1
by Francis J. Lacoste
Renamed reference to support tracker in doctests. |
354 |
... "this problem you should reopen the question and provide more " |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
355 |
... "information about your problem.", |
356 |
... datecreated=two_weeks_from_now) |
|
357 |
>>> print expire_message.action.name |
|
358 |
EXPIRE |
|
3691.197.55
by Francis J. Lacoste
Rename newstatus to new_status as per new naming convention. Renamed foreign key to ticket__answer__fk as requested by stub. |
359 |
>>> print expire_message.new_status.name |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
360 |
EXPIRED |
361 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
362 |
The question is moved to the EXPIRED state and the last response date is |
363 |
updated to the message creation date. |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
364 |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
365 |
>>> print question.status.name |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
366 |
EXPIRED |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
367 |
>>> question.datelastresponse == two_weeks_from_now |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
368 |
True |
369 |
||
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
370 |
If the user comes back and provide more information, the question will be |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
371 |
reopened. |
372 |
||
373 |
>>> much_later = now + timedelta(days=30) |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
374 |
>>> reopen_message = question.reopen( |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
375 |
... "I'm installing on PowerMac 7200/120 with 32 Megs of RAM. After " |
376 |
... "I insert the CD and restart the computer, it boots straight " |
|
377 |
... "into Mac OS/9 instead of booting the installer.", |
|
378 |
... datecreated=much_later) |
|
379 |
>>> print reopen_message.action.name |
|
380 |
REOPEN |
|
381 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
382 |
The question status is changed back to OPEN and the last query date is |
383 |
updated. |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
384 |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
385 |
>>> print question.status.name |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
386 |
OPEN |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
387 |
>>> question.datelastquery == much_later |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
388 |
True |
389 |
||
390 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
391 |
4) The question is invalid |
392 |
========================== |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
393 |
|
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
394 |
In this scenario the user posts an inappropriate message, such as a spam |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
395 |
message or a request for Ubuntu CDs. |
396 |
||
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
397 |
>>> spam_question = ubuntu.newQuestion( |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
398 |
... no_priv, 'CDs', 'Please send 10 Ubuntu Dapper CDs.', |
399 |
... datecreated=now) |
|
400 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
401 |
Such questions can be rejected by an answer contact, a product or distribution |
402 |
owner, or a Launchpad administrator. |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
403 |
|
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
404 |
The canReject() method can be used to test if a user is allowed to reject the |
405 |
question. While neither No Privileges Person nor Marilize are able to reject |
|
406 |
questions, Sample Person and the Ubuntu owner can. |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
407 |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
408 |
>>> spam_question.canReject(no_priv) |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
409 |
False |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
410 |
>>> spam_question.canReject(marilize) |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
411 |
False |
412 |
||
3881.1.1
by Francis J. Lacoste
Renamed reference to support tracker in doctests. |
413 |
# Answer contact |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
414 |
>>> spam_question.canReject(sample_person) |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
415 |
True |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
416 |
>>> spam_question.canReject(ubuntu.owner) |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
417 |
True |
418 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
419 |
As a Launchpad administrator, so can Stub. |
420 |
||
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
421 |
>>> spam_question.canReject(stub) |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
422 |
True |
423 |
||
3691.197.108
by Francis J. Lacoste
Remove Unauthorized from database code. |
424 |
>>> login(marilize.preferredemail.email) |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
425 |
>>> spam_question.reject( |
12756.3.17
by William Grant
Destroy more references. |
426 |
... marilize, "We don't send free CDs any more.") |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
427 |
Traceback (most recent call last): |
428 |
... |
|
3691.197.63
by Francis J. Lacoste
Raise Unauthorized instead of AssertionError when user cannot reject a request. |
429 |
Unauthorized: ... |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
430 |
|
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
431 |
When rejecting a question, a comment explaining the reason is given. |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
432 |
|
3691.197.108
by Francis J. Lacoste
Remove Unauthorized from database code. |
433 |
>>> login('test@canonical.com') |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
434 |
>>> reject_message = spam_question.reject( |
12756.3.17
by William Grant
Destroy more references. |
435 |
... sample_person, "We don't send free CDs any more.", |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
436 |
... datecreated=now_plus_one_hour) |
437 |
>>> print reject_message.action.name |
|
438 |
REJECT |
|
3691.197.55
by Francis J. Lacoste
Rename newstatus to new_status as per new naming convention. Renamed foreign key to ticket__answer__fk as requested by stub. |
439 |
>>> print reject_message.new_status.name |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
440 |
INVALID |
441 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
442 |
After rejection, the question is marked as invalid and the last response date |
443 |
is updated. |
|
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
444 |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
445 |
>>> print spam_question.status.name |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
446 |
INVALID |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
447 |
>>> spam_question.datelastresponse == now_plus_one_hour |
3691.197.12
by Francis J. Lacoste
- Removed can_be_rejected attribute from ITicket. |
448 |
True |
449 |
||
3691.197.33
by Francis J. Lacoste
Consider a rejection message as answering the ticket. |
450 |
The rejection message is also considered as answering the message, so the |
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
451 |
solution date, answerer, and answer are also updated. |
3691.197.33
by Francis J. Lacoste
Consider a rejection message as answering the ticket. |
452 |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
453 |
>>> spam_question.answer == reject_message |
3691.197.33
by Francis J. Lacoste
Consider a rejection message as answering the ticket. |
454 |
True |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
455 |
>>> print spam_question.answerer.displayname |
3691.197.33
by Francis J. Lacoste
Consider a rejection message as answering the ticket. |
456 |
Sample Person |
4664.2.4
by Curtis Hovey
Renamed attribute from datesolved to date_solved. Doh. This was |
457 |
>>> spam_question.date_solved == now_plus_one_hour |
3691.197.33
by Francis J. Lacoste
Consider a rejection message as answering the ticket. |
458 |
True |
459 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
460 |
|
461 |
Other scenarios |
|
462 |
=============== |
|
463 |
||
464 |
Many other scenarios are possible and some are likely more common than others. |
|
465 |
For example, it is likely that a user will directly answer a question without |
|
466 |
asking for other information first. Sometimes, the original questioner won't |
|
467 |
come back to confirm that an answer solved his problem. |
|
468 |
||
469 |
Another likely scenario is where the question will expire in the NEEDSINFO |
|
470 |
state because the question owner doesn't reply to the request for more |
|
471 |
information. All of these scenarios are covered by this API, though it is not |
|
472 |
necessary to cover all these various possibilities here. (The |
|
473 |
../tests/test_question_workflow.py functional test exercises all the various |
|
474 |
possible transitions.) |
|
475 |
||
476 |
||
477 |
Changing the question status |
|
478 |
============================ |
|
479 |
||
480 |
It is not possible to change the status attribute directly. |
|
3691.197.16
by Francis J. Lacoste
- Add setStatus() and addComment() methods. |
481 |
|
3691.197.62
by Francis J. Lacoste
Explicitely login as admin user to clarify that nobody can set the status directly |
482 |
>>> login('foo.bar@canonical.com') |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
483 |
>>> question = ubuntu.newQuestion(**new_question_args) |
484 |
>>> question.status = QuestionStatus.INVALID |
|
3691.197.16
by Francis J. Lacoste
- Add setStatus() and addComment() methods. |
485 |
Traceback (most recent call last): |
486 |
... |
|
487 |
ForbiddenAttribute... |
|
488 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
489 |
A user having launchpad.Admin permission on the question can set the question |
490 |
status to an arbitrary value, by giving the new status and a comment |
|
491 |
explaining the status change. |
|
3691.197.16
by Francis J. Lacoste
- Add setStatus() and addComment() methods. |
492 |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
493 |
>>> old_datelastquery = question.datelastquery |
3691.197.104
by Francis J. Lacoste
- Protect setStatus by launchpad.Admin. |
494 |
>>> login(stub.preferredemail.email) |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
495 |
>>> status_change_message = question.setStatus( |
3691.398.17
by Francis J. Lacoste
Rename dbschemas. |
496 |
... stub, QuestionStatus.INVALID, 'Changed status to INVALID', |
3691.197.16
by Francis J. Lacoste
- Add setStatus() and addComment() methods. |
497 |
... datecreated=now_plus_one_hour) |
498 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
499 |
The method returns the IQuestionMessage recording the change. |
3691.197.16
by Francis J. Lacoste
- Add setStatus() and addComment() methods. |
500 |
|
501 |
>>> print status_change_message.action.name |
|
502 |
SETSTATUS |
|
3691.197.55
by Francis J. Lacoste
Rename newstatus to new_status as per new naming convention. Renamed foreign key to ticket__answer__fk as requested by stub. |
503 |
>>> print status_change_message.new_status.name |
3691.197.16
by Francis J. Lacoste
- Add setStatus() and addComment() methods. |
504 |
INVALID |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
505 |
>>> print question.status.name |
3691.197.16
by Francis J. Lacoste
- Add setStatus() and addComment() methods. |
506 |
INVALID |
507 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
508 |
The status change updates the last response date. |
3691.197.16
by Francis J. Lacoste
- Add setStatus() and addComment() methods. |
509 |
|
4213.1.2
by Francis J. Lacoste
Update datelastresponse on setStatus. |
510 |
>>> question.datelastresponse == now_plus_one_hour |
3691.197.16
by Francis J. Lacoste
- Add setStatus() and addComment() methods. |
511 |
True |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
512 |
>>> question.datelastquery == old_datelastquery |
3691.197.16
by Francis J. Lacoste
- Add setStatus() and addComment() methods. |
513 |
True |
514 |
||
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
515 |
If an answer was present on the question, the status change also clears |
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
516 |
the answer and solution date. |
3691.197.16
by Francis J. Lacoste
- Add setStatus() and addComment() methods. |
517 |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
518 |
>>> msg = question.setStatus(stub, QuestionStatus.OPEN, 'Status change.') |
519 |
>>> answer_message = question.giveAnswer(sample_person, 'Install BootX.') |
|
3691.197.109
by Francis J. Lacoste
- Add launchpad.Owner permission. |
520 |
|
521 |
>>> login('no-priv@canonical.com') |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
522 |
>>> msg = question.confirmAnswer('This worked.', answer=answer_message) |
4664.2.4
by Curtis Hovey
Renamed attribute from datesolved to date_solved. Doh. This was |
523 |
>>> question.date_solved is not None |
3691.197.92
by Francis J. Lacoste
Remove write access to all internally-managed attributes |
524 |
True |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
525 |
>>> question.answer == answer_message |
3691.197.92
by Francis J. Lacoste
Remove write access to all internally-managed attributes |
526 |
True |
3691.197.109
by Francis J. Lacoste
- Add launchpad.Owner permission. |
527 |
|
528 |
>>> login(stub.preferredemail.email) |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
529 |
>>> status_change_message = question.setStatus( |
3881.1.1
by Francis J. Lacoste
Renamed reference to support tracker in doctests. |
530 |
... stub, QuestionStatus.OPEN, 'Reopen the question', |
3691.197.92
by Francis J. Lacoste
Remove write access to all internally-managed attributes |
531 |
... datecreated=now_plus_one_hour) |
3691.197.16
by Francis J. Lacoste
- Add setStatus() and addComment() methods. |
532 |
|
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
533 |
>>> print question.date_solved |
534 |
None |
|
535 |
>>> print question.answer |
|
536 |
None |
|
3691.197.16
by Francis J. Lacoste
- Add setStatus() and addComment() methods. |
537 |
|
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
538 |
When the status is changed by a user who doesn't have the launchpad.Admin |
539 |
permission, an Unauthorized exception is thrown. |
|
3691.197.16
by Francis J. Lacoste
- Add setStatus() and addComment() methods. |
540 |
|
3691.197.108
by Francis J. Lacoste
Remove Unauthorized from database code. |
541 |
>>> login('test@canonical.com') |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
542 |
>>> question.setStatus(sample_person, QuestionStatus.EXPIRED, 'Expire.') |
3691.197.16
by Francis J. Lacoste
- Add setStatus() and addComment() methods. |
543 |
Traceback (most recent call last): |
544 |
... |
|
545 |
Unauthorized... |
|
546 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
547 |
|
548 |
Adding Comments Without Changing the Status |
|
549 |
=========================================== |
|
550 |
||
551 |
Comments can be added to questions without changing the question's status. |
|
3691.197.16
by Francis J. Lacoste
- Add setStatus() and addComment() methods. |
552 |
|
3691.197.104
by Francis J. Lacoste
- Protect setStatus by launchpad.Admin. |
553 |
>>> login('no-priv@canonical.com') |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
554 |
>>> old_status = question.status |
555 |
>>> old_datelastresponse = question.datelastresponse |
|
556 |
>>> old_datelastquery = question.datelastquery |
|
557 |
>>> comment = question.addComment( |
|
3691.197.16
by Francis J. Lacoste
- Add setStatus() and addComment() methods. |
558 |
... no_priv, 'This is a comment.', |
559 |
... datecreated=now_plus_two_hours) |
|
560 |
||
561 |
>>> print comment.action.name |
|
562 |
COMMENT |
|
3691.197.55
by Francis J. Lacoste
Rename newstatus to new_status as per new naming convention. Renamed foreign key to ticket__answer__fk as requested by stub. |
563 |
>>> comment.new_status == old_status |
3691.197.16
by Francis J. Lacoste
- Add setStatus() and addComment() methods. |
564 |
True |
565 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
566 |
This method does not update the last response date or last query date. |
3691.197.16
by Francis J. Lacoste
- Add setStatus() and addComment() methods. |
567 |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
568 |
>>> question.datelastresponse == old_datelastresponse |
3691.197.16
by Francis J. Lacoste
- Add setStatus() and addComment() methods. |
569 |
True |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
570 |
>>> question.datelastquery == old_datelastquery |
3691.197.16
by Francis J. Lacoste
- Add setStatus() and addComment() methods. |
571 |
True |
3691.197.31
by Francis J. Lacoste
All workflow methods now triggers an ISQLObjectModifiedEvent. |
572 |
|
8848.2.1
by Curtis Hovey
Allow answer contacts to assign questions. |
573 |
|
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
574 |
Setting the question assignee |
575 |
============================= |
|
8848.2.1
by Curtis Hovey
Allow answer contacts to assign questions. |
576 |
|
577 |
Users with launchpad.Moderator privileges, which are answer contacts, |
|
578 |
question target owners, and admins, can assign someone to answer a question. |
|
579 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
580 |
Sample Person is an answer contact for ubuntu, so he can set the assignee. |
8848.2.1
by Curtis Hovey
Allow answer contacts to assign questions. |
581 |
|
582 |
>>> login('test@canonical.com') |
|
583 |
>>> question.assignee = stub |
|
584 |
>>> print question.assignee.displayname |
|
585 |
Stuart Bishop |
|
586 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
587 |
Users without launchpad.Moderator privileges cannot set the assignee. |
8848.2.1
by Curtis Hovey
Allow answer contacts to assign questions. |
588 |
|
589 |
>>> login('no-priv@canonical.com') |
|
590 |
>>> question.assignee = sample_person |
|
591 |
Traceback (most recent call last): |
|
592 |
... |
|
11326.2.11
by Brad Crittenden
Updated permissions for distro, FAQ, and questions. |
593 |
Unauthorized: (<Question ...>, 'assignee', 'launchpad.Append') |
8848.2.1
by Curtis Hovey
Allow answer contacts to assign questions. |
594 |
|
595 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
596 |
Events |
597 |
====== |
|
3691.197.31
by Francis J. Lacoste
All workflow methods now triggers an ISQLObjectModifiedEvent. |
598 |
|
7876.3.6
by Francis J. Lacoste
Used ISQLObject from lazr.lifecycle |
599 |
Each of the workflow methods will trigger a ObjectCreatedEvent for |
600 |
the message they create and a ObjectModifiedEvent for the question. |
|
3691.197.31
by Francis J. Lacoste
All workflow methods now triggers an ISQLObjectModifiedEvent. |
601 |
|
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
602 |
# Register an event listener that will print events it receives. |
7876.3.6
by Francis J. Lacoste
Used ISQLObject from lazr.lifecycle |
603 |
>>> from lazr.lifecycle.interfaces import ( |
604 |
... IObjectCreatedEvent, IObjectModifiedEvent) |
|
11716.1.12
by Curtis Hovey
Sorted imports in doctests. |
605 |
>>> from canonical.lazr.testing.event import TestEventListener |
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
606 |
>>> from lp.answers.interfaces.question import IQuestion |
607 |
||
3691.197.31
by Francis J. Lacoste
All workflow methods now triggers an ISQLObjectModifiedEvent. |
608 |
>>> def print_event(object, event): |
609 |
... print "Received %s on %s" % ( |
|
610 |
... event.__class__.__name__.split('.')[-1], |
|
611 |
... object.__class__.__name__.split('.')[-1]) |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
612 |
>>> questionmessage_event_listener = TestEventListener( |
7876.3.6
by Francis J. Lacoste
Used ISQLObject from lazr.lifecycle |
613 |
... IQuestionMessage, IObjectCreatedEvent, print_event) |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
614 |
>>> question_event_listener = TestEventListener( |
7876.3.6
by Francis J. Lacoste
Used ISQLObject from lazr.lifecycle |
615 |
... IQuestion, IObjectModifiedEvent, print_event) |
3691.197.31
by Francis J. Lacoste
All workflow methods now triggers an ISQLObjectModifiedEvent. |
616 |
|
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
617 |
Changing the status triggers the event. |
3691.197.31
by Francis J. Lacoste
All workflow methods now triggers an ISQLObjectModifiedEvent. |
618 |
|
3691.197.104
by Francis J. Lacoste
- Protect setStatus by launchpad.Admin. |
619 |
>>> login(stub.preferredemail.email) |
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
620 |
>>> msg = question.setStatus( |
621 |
... stub, QuestionStatus.EXPIRED, 'Status change.') |
|
7876.3.6
by Francis J. Lacoste
Used ISQLObject from lazr.lifecycle |
622 |
Received ObjectCreatedEvent on QuestionMessage |
623 |
Received ObjectModifiedEvent on Question |
|
3691.197.31
by Francis J. Lacoste
All workflow methods now triggers an ISQLObjectModifiedEvent. |
624 |
|
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
625 |
Rejecting the question triggers the events. |
3691.197.31
by Francis J. Lacoste
All workflow methods now triggers an ISQLObjectModifiedEvent. |
626 |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
627 |
>>> msg = question.reject(stub, 'Close this question.') |
7876.3.6
by Francis J. Lacoste
Used ISQLObject from lazr.lifecycle |
628 |
Received ObjectCreatedEvent on QuestionMessage |
629 |
Received ObjectModifiedEvent on Question |
|
3691.197.31
by Francis J. Lacoste
All workflow methods now triggers an ISQLObjectModifiedEvent. |
630 |
|
631 |
Even only adding a comment without changing the status will send |
|
632 |
these events. |
|
633 |
||
3691.197.104
by Francis J. Lacoste
- Protect setStatus by launchpad.Admin. |
634 |
>>> login('test@canonical.com') |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
635 |
>>> msg = question.addComment(sample_person, 'A comment') |
7876.3.6
by Francis J. Lacoste
Used ISQLObject from lazr.lifecycle |
636 |
Received ObjectCreatedEvent on QuestionMessage |
637 |
Received ObjectModifiedEvent on Question |
|
3691.197.31
by Francis J. Lacoste
All workflow methods now triggers an ISQLObjectModifiedEvent. |
638 |
|
3691.259.2
by Francis J. Lacoste
Convert to Moin-style headers, convert () comments to regular python comments. |
639 |
# Cleanup |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
640 |
>>> questionmessage_event_listener.unregister() |
641 |
>>> question_event_listener.unregister() |
|
3691.197.34
by Francis J. Lacoste
Create TicketReopening using an event subscriber |
642 |
|
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
643 |
|
644 |
Reopening the question |
|
645 |
====================== |
|
3691.197.34
by Francis J. Lacoste
Create TicketReopening using an event subscriber |
646 |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
647 |
Whenever a question considered answered (in the SOLVED or INVALID state) |
3691.398.19
by Francis J. Lacoste
Rename most remaining classes (views, database, authorizations, notifications, scripts.) |
648 |
is reopened, a QuestionReopening is created. |
3691.197.34
by Francis J. Lacoste
Create TicketReopening using an event subscriber |
649 |
|
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
650 |
# Register an event listener to notify us whenever a QuestionReopening is |
651 |
# created. |
|
652 |
>>> from lp.answers.interfaces.questionreopening import IQuestionReopening |
|
3691.197.34
by Francis J. Lacoste
Create TicketReopening using an event subscriber |
653 |
>>> reopening_event_listener = TestEventListener( |
7876.3.6
by Francis J. Lacoste
Used ISQLObject from lazr.lifecycle |
654 |
... IQuestionReopening, IObjectCreatedEvent, print_event) |
3691.197.34
by Francis J. Lacoste
Create TicketReopening using an event subscriber |
655 |
|
656 |
The most common use case is when a user confirms a solution, and then |
|
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
657 |
comes back to say that it doesn't, in fact, work. |
3691.197.34
by Francis J. Lacoste
Create TicketReopening using an event subscriber |
658 |
|
3691.197.109
by Francis J. Lacoste
- Add launchpad.Owner permission. |
659 |
>>> login('no-priv@canonical.com') |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
660 |
>>> question = ubuntu.newQuestion(**new_question_args) |
661 |
>>> answer_message = question.giveAnswer( |
|
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
662 |
... sample_person, |
663 |
... "You need some setup on the Mac side. " |
|
664 |
... "Follow the instructions at " |
|
3691.197.34
by Francis J. Lacoste
Create TicketReopening using an event subscriber |
665 |
... "https://help.ubuntu.com/community/Installation/OldWorldMacs", |
666 |
... datecreated=now_plus_one_hour) |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
667 |
>>> confirm_message = question.confirmAnswer( |
3691.197.34
by Francis J. Lacoste
Create TicketReopening using an event subscriber |
668 |
... "I've installed BootX and the installer now boot properly.", |
669 |
... answer=answer_message, datecreated=now_plus_two_hours) |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
670 |
>>> reopen_message = question.reopen( |
3691.197.34
by Francis J. Lacoste
Create TicketReopening using an event subscriber |
671 |
... "Actually, altough the installer boots properly. I'm not able " |
672 |
... "to pass beyond the partitioning.", |
|
673 |
... datecreated=now_plus_three_hours) |
|
7876.3.6
by Francis J. Lacoste
Used ISQLObject from lazr.lifecycle |
674 |
Received ObjectCreatedEvent on QuestionReopening |
3691.197.34
by Francis J. Lacoste
Create TicketReopening using an event subscriber |
675 |
|
676 |
The reopening record is available through the reopenings attribute. |
|
677 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
678 |
>>> reopenings = list(question.reopenings) |
679 |
>>> len(reopenings) |
|
680 |
1 |
|
681 |
>>> reopening = reopenings[0] |
|
3691.398.18
by Francis J. Lacoste
Rename interfaces. |
682 |
>>> verifyObject(IQuestionReopening, reopening) |
3691.197.34
by Francis J. Lacoste
Create TicketReopening using an event subscriber |
683 |
True |
684 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
685 |
The reopening contain the date of the reopening, and the person who cause the |
686 |
reopening to happen. |
|
3691.197.34
by Francis J. Lacoste
Create TicketReopening using an event subscriber |
687 |
|
688 |
>>> reopening.datecreated == now_plus_three_hours |
|
689 |
True |
|
690 |
>>> print reopening.reopener.displayname |
|
691 |
No Privileges Person |
|
692 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
693 |
It also contains the question's prior answerer, the date created, and the |
694 |
prior status of the question. |
|
3691.197.34
by Francis J. Lacoste
Create TicketReopening using an event subscriber |
695 |
|
696 |
>>> print reopening.answerer.displayname |
|
697 |
Sample Person |
|
4664.2.4
by Curtis Hovey
Renamed attribute from datesolved to date_solved. Doh. This was |
698 |
>>> reopening.date_solved == now_plus_two_hours |
3691.197.34
by Francis J. Lacoste
Create TicketReopening using an event subscriber |
699 |
True |
700 |
>>> print reopening.priorstate.name |
|
701 |
SOLVED |
|
702 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
703 |
A reopening also occurs when the question status is set back to OPEN after |
704 |
having been rejected. |
|
3691.197.34
by Francis J. Lacoste
Create TicketReopening using an event subscriber |
705 |
|
3691.197.104
by Francis J. Lacoste
- Protect setStatus by launchpad.Admin. |
706 |
>>> login('test@canonical.com') |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
707 |
>>> question = ubuntu.newQuestion(**new_question_args) |
708 |
>>> reject_message = question.reject( |
|
3881.1.1
by Francis J. Lacoste
Renamed reference to support tracker in doctests. |
709 |
... sample_person, 'This is a frivoulous question.', |
3691.197.34
by Francis J. Lacoste
Create TicketReopening using an event subscriber |
710 |
... datecreated=now_plus_one_hour) |
3691.197.104
by Francis J. Lacoste
- Protect setStatus by launchpad.Admin. |
711 |
|
712 |
>>> login(stub.preferredemail.email) |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
713 |
>>> status_change_message = question.setStatus( |
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
714 |
... stub, QuestionStatus.OPEN, |
715 |
... 'Disregard previous rejection. ' |
|
3691.197.34
by Francis J. Lacoste
Create TicketReopening using an event subscriber |
716 |
... 'Sample Person was having a bad day.', |
717 |
... datecreated=now_plus_two_hours) |
|
7876.3.6
by Francis J. Lacoste
Used ISQLObject from lazr.lifecycle |
718 |
Received ObjectCreatedEvent on QuestionReopening |
3691.197.34
by Francis J. Lacoste
Create TicketReopening using an event subscriber |
719 |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
720 |
>>> reopening = question.reopenings[0] |
3691.197.34
by Francis J. Lacoste
Create TicketReopening using an event subscriber |
721 |
>>> print reopening.reopener.name |
722 |
stub |
|
723 |
>>> reopening.datecreated == now_plus_two_hours |
|
724 |
True |
|
725 |
>>> print reopening.answerer.displayname |
|
726 |
Sample Person |
|
4664.2.4
by Curtis Hovey
Renamed attribute from datesolved to date_solved. Doh. This was |
727 |
>>> reopening.date_solved == now_plus_one_hour |
3691.197.34
by Francis J. Lacoste
Create TicketReopening using an event subscriber |
728 |
True |
729 |
>>> print reopening.priorstate.name |
|
730 |
INVALID |
|
731 |
||
3691.259.2
by Francis J. Lacoste
Convert to Moin-style headers, convert () comments to regular python comments. |
732 |
# Cleanup |
3691.197.34
by Francis J. Lacoste
Create TicketReopening using an event subscriber |
733 |
>>> reopening_event_listener.unregister() |
3691.197.41
by Francis J. Lacoste
Added the possibility to use an IMessage as content in the workflow methods |
734 |
|
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
735 |
|
736 |
Using an IMessage as an explanation |
|
737 |
=================================== |
|
3691.197.41
by Francis J. Lacoste
Added the possibility to use an IMessage as content in the workflow methods |
738 |
|
739 |
In all the workflow methods, it is possible to pass an IMessage instead of |
|
740 |
a string. |
|
741 |
||
12929.9.7
by j.c.sackett
Caught more imports. |
742 |
>>> from lp.services.messages.interfaces.message import IMessageSet |
3691.197.104
by Francis J. Lacoste
- Protect setStatus by launchpad.Admin. |
743 |
>>> login('test@canonical.com') |
3691.197.41
by Francis J. Lacoste
Added the possibility to use an IMessage as content in the workflow methods |
744 |
>>> messageset = getUtility(IMessageSet) |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
745 |
>>> question = ubuntu.newQuestion(**new_question_args) |
3691.197.41
by Francis J. Lacoste
Added the possibility to use an IMessage as content in the workflow methods |
746 |
>>> reject_message = messageset.fromText( |
747 |
... 'Reject', 'Because I feel like it.', sample_person) |
|
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
748 |
>>> question_message = question.reject(sample_person, reject_message) |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
749 |
>>> print question_message.subject |
3691.197.41
by Francis J. Lacoste
Added the possibility to use an IMessage as content in the workflow methods |
750 |
Reject |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
751 |
>>> print question_message.text_contents |
3691.197.41
by Francis J. Lacoste
Added the possibility to use an IMessage as content in the workflow methods |
752 |
Because I feel like it. |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
753 |
>>> question_message.rfc822msgid == reject_message.rfc822msgid |
3691.197.41
by Francis J. Lacoste
Added the possibility to use an IMessage as content in the workflow methods |
754 |
True |
755 |
||
7675.518.3
by Barry Warsaw
Reformat workflow.txt to today's doctest standards. |
756 |
The IMessage owner must be the same as the person passed to the workflow |
3691.197.41
by Francis J. Lacoste
Added the possibility to use an IMessage as content in the workflow methods |
757 |
method. |
758 |
||
3691.197.104
by Francis J. Lacoste
- Protect setStatus by launchpad.Admin. |
759 |
>>> login(stub.preferredemail.email) |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
760 |
>>> question.setStatus(stub, QuestionStatus.OPEN, reject_message) |
3691.197.41
by Francis J. Lacoste
Added the possibility to use an IMessage as content in the workflow methods |
761 |
Traceback (most recent call last): |
762 |
... |
|
13099.1.13
by Curtis Hovey
Updated tests to verify the specific errors. |
763 |
NotMessageOwnerError... |