1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
= Rejecting Questions =
Answer contacts and administrators can reject a question.
This should be done when the question isn't an actual pertinent question
for the product. For example, if the question is a duplicate or spam.
No Privileges Person isn't an answer contact or administrator, so he
doesn't have access to that feature.
>>> user_browser.open('http://launchpad.dev/firefox/+question/2')
>>> user_browser.getLink('Reject question')
Traceback (most recent call last):
...
LinkNotFoundError...
Even when trying to access the page directly, he will get an unauthorized
error.
>>> user_browser.open(
... 'http://launchpad.dev/firefox/+question/2/+reject')
Traceback (most recent call last):
...
Unauthorized: ...
To reject the question, the user clicks on the 'Reject Question' link.
>>> admin_browser.open('http://answers.launchpad.dev/firefox/+question/2')
>>> admin_browser.getLink('Reject question').click()
>>> admin_browser.getControl('Reject').click()
He needs to enter a message explaining the rejection:
>>> for message in find_tags_by_class(admin_browser.contents, 'message'):
... print message.renderContents()
There is 1 error.
You must provide an explanation message.
At this point the user might decide this is a bad idea, so there is a
cancel link to take him back to the question:
>>> print admin_browser.getLink('Cancel').url
http://answers.launchpad.dev/firefox/+question/2
Entering an explanation message and clicking the 'Reject' button,
will reject the question.
>>> admin_browser.getControl('Message').value = (
... """Rejecting because it's a duplicate of bug #1.""")
>>> admin_browser.getControl('Reject').click()
Once the question is rejected, a confirmation message is shown;
>>> for message in find_tags_by_class(admin_browser.contents, 'message'):
... print message.renderContents()
You have rejected this question.
its status is changed to 'Invalid';
>>> def print_question_status(browser):
... print extract_text(
... find_tag_by_id(browser.contents, 'question-status'))
>>> print_question_status(admin_browser)
Status: Invalid ...
and the rejection message is added to the question board.
>>> content = find_main_content(admin_browser.contents)
>>> print content.findAll('div', 'boardCommentBody')[-1].renderContents()
<p>Rejecting because it's a duplicate of <a...>bug #1</a>.</p>
The call to help with this problem is not displayed.
>>> print content.find(id='can-you-help-with-this-problem')
None
Selecting the 'Reject' action again, will simply display a message
stating that the question is already rejected:
>>> admin_browser.getLink('Reject question').click()
>>> print admin_browser.url
http://answers.launchpad.dev/firefox/+question/2
>>> for message in find_tags_by_class(admin_browser.contents, 'message'):
... print message.renderContents()
The question is already rejected.
= Changing the Question Status =
In the previous example, that rejection was clearly a mistake: you
shouldn't reject a question because it is related to a bug, for these
case, you should link the question to the bug!
Users who have administrative privileges on the question (product or
distribution registrant and Launchpad admins) can correct errors like
these by using the 'Change status' action. This page enables a user to
set the question status to an arbitrary value without workflow constraint.
That action isn't available to a non-privileged user:
>>> browser.open('http://launchpad.dev/firefox/+question/2')
>>> browser.getLink('Change status')
Traceback (most recent call last):
...
LinkNotFoundError...
The change status form is available to an administrator through the
'Change status' link.
>>> admin_browser.open('http://launchpad.dev/firefox/+question/2')
>>> admin_browser.getLink('Change status').click()
The form has a select widget displaying the current status.
>>> admin_browser.getControl('Status', index=0).displayValue
['Invalid']
There is also a cancel link should the user decide otherwise:
>>> print admin_browser.getLink('Cancel').url
http://answers.launchpad.dev/firefox/+question/2
The user needs to select a status and enter a message explaining the
status change:
>>> admin_browser.getControl('Change Status').click()
>>> for error in find_tags_by_class(admin_browser.contents, 'message'):
... print error.renderContents()
There are 2 errors.
You didn't change the status.
You must provide an explanation message.
To correct the mistake of the previous example, the administrator would
select back the 'Open' status and provide an appropriate message:
>>> admin_browser.getControl('Status', index=0).displayValue = ['Open']
>>> admin_browser.getControl('Message').value = (
... "Setting status back to 'Open'. Questions similar to a bug "
... "report should be linked to it, not rejected.")
>>> admin_browser.getControl('Change Status').click()
Once the operation is completed, a confirmation message is displayed;
>>> for message in find_tags_by_class(admin_browser.contents, 'message'):
... print message.renderContents()
Question status updated.
its status is updated;
>>> print_question_status(admin_browser)
Status: Open ...
and the explanation message is added to the question discussion:
>>> content = find_main_content(admin_browser.contents)
>>> print content.findAll('div', 'boardCommentBody')[-1].renderContents()
<p>Setting status back to 'Open'. Questions similar to a bug report
should be linked to it, not rejected.</p>
|