9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
1 |
================== |
2 |
Team Mailing Lists |
|
3 |
================== |
|
4419.6.1
by Barry Warsaw
Fleshed out the interface for IMailingList and IMailingListRegistry. Added |
4 |
|
4543.2.12
by Barry Warsaw
A round of changes in response to BradC's review: |
5 |
Teams may have at most one team mailing list. Creating a team mailing list |
4419.6.1
by Barry Warsaw
Fleshed out the interface for IMailingList and IMailingListRegistry. Added |
6 |
requires several steps, starting with registration of the list by the owner of |
4543.2.14
by Barry Warsaw
Last round of response to Kiko's review. |
7 |
an existing team. This is done through an IMailingListSet utility. |
4419.6.1
by Barry Warsaw
Fleshed out the interface for IMailingList and IMailingListRegistry. Added |
8 |
|
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. |
9 |
>>> from canonical.launchpad.webapp.testing import verifyObject |
11716.1.15
by Curtis Hovey
Fixed multiline import statements in doctests. |
10 |
>>> from lp.registry.interfaces.mailinglist import ( |
11716.1.12
by Curtis Hovey
Sorted imports in doctests. |
11 |
... IMailingList, |
12 |
... IMailingListSet, |
|
13 |
... ) |
|
4543.2.14
by Barry Warsaw
Last round of response to Kiko's review. |
14 |
>>> list_set = getUtility(IMailingListSet) |
15 |
>>> verifyObject(IMailingListSet, list_set) |
|
4419.6.1
by Barry Warsaw
Fleshed out the interface for IMailingList and IMailingListRegistry. Added |
16 |
True |
17 |
||
18 |
In the following description of how to use team mailing lists, we will need |
|
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
19 |
several some teams. |
4419.6.1
by Barry Warsaw
Fleshed out the interface for IMailingList and IMailingListRegistry. Added |
20 |
|
7675.110.3
by Curtis Hovey
Ran the migration script to move registry code to lp.registry. |
21 |
>>> from lp.registry.tests.mailinglists_helper import new_team |
4543.2.14
by Barry Warsaw
Last round of response to Kiko's review. |
22 |
>>> team_one = new_team('team-one') |
23 |
>>> team_two = new_team('team-two') |
|
4419.6.1
by Barry Warsaw
Fleshed out the interface for IMailingList and IMailingListRegistry. Added |
24 |
|
4897.4.11
by Barry Warsaw
By generalizing the mailing lists test helper module away from just XMLRPC, we |
25 |
# Define a helper function that sorts mailing lists alphabetically based |
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
26 |
# on their team's name. We can't use operator.attrgetter() because until |
27 |
# Python 2.6, that traverses only one level of attribute. |
|
4419.6.3
by Barry Warsaw
More fleshing out of the mailing list database classes and doctest. |
28 |
>>> def sorted_lists(lists): |
29 |
... return sorted(lists, key=lambda L: L.team.name) |
|
30 |
||
4419.6.1
by Barry Warsaw
Fleshed out the interface for IMailingList and IMailingListRegistry. Added |
31 |
None of these teams have mailing lists yet. |
32 |
||
4543.2.14
by Barry Warsaw
Last round of response to Kiko's review. |
33 |
>>> sorted_lists(list_set.approved_lists) |
34 |
[] |
|
4897.2.1
by Barry Warsaw
Mailing list subscriptions. |
35 |
>>> sorted_lists(list_set.active_lists) |
36 |
[] |
|
4543.2.14
by Barry Warsaw
Last round of response to Kiko's review. |
37 |
>>> print list_set.get(team_one.name) |
38 |
None |
|
39 |
>>> print list_set.get(team_two.name) |
|
40 |
None |
|
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
41 |
|
42 |
||
43 |
Creating a team mailing list |
|
44 |
============================ |
|
45 |
||
46 |
When a mailing list is created, it is automatically set to the APPROVED state, |
|
47 |
meaning that list requests are automatically approved. This doesn't actually |
|
48 |
create the list until Mailman acts on the mailing list creation request. |
|
49 |
||
4543.2.14
by Barry Warsaw
Last round of response to Kiko's review. |
50 |
>>> list_one = list_set.new(team_one) |
4419.6.6
by Barry Warsaw
One typo fix and one additional small test. |
51 |
>>> verifyObject(IMailingList, list_one) |
52 |
True |
|
4419.6.1
by Barry Warsaw
Fleshed out the interface for IMailingList and IMailingListRegistry. Added |
53 |
>>> list_one |
12043.6.3
by Curtis Hovey
Add address to mailing list repr. |
54 |
<MailingList for team "team-one"; status=APPROVED; |
55 |
address=team-one@lists.launchpad.dev at 0x...> |
|
4419.6.3
by Barry Warsaw
More fleshing out of the mailing list database classes and doctest. |
56 |
|
5256.1.2
by Barry Warsaw
Changes in response to jml's review: |
57 |
You can always access the mailing list through its team, if the team has a |
58 |
mailing list. |
|
59 |
||
60 |
>>> team_one.mailing_list |
|
12043.6.3
by Curtis Hovey
Add address to mailing list repr. |
61 |
<MailingList for team "team-one"; status=APPROVED; ...> |
5256.1.2
by Barry Warsaw
Changes in response to jml's review: |
62 |
>>> print team_two.mailing_list |
63 |
None |
|
64 |
||
4419.6.3
by Barry Warsaw
More fleshing out of the mailing list database classes and doctest. |
65 |
You may not register a mailing list for a person. |
66 |
||
6130.6.3
by Maris Fogels
Rewrote the team join pages and the mailing list doctests to take the new behaviour into account. |
67 |
>>> login('foo.bar@canonical.com') |
7315.6.1
by Barry Warsaw
Refactor by moving mailinglists_helper.new_person -> |
68 |
>>> anne = factory.makePersonByName('Anne') |
6130.6.3
by Maris Fogels
Rewrote the team join pages and the mailing list doctests to take the new behaviour into account. |
69 |
>>> login(ANONYMOUS) |
4897.4.11
by Barry Warsaw
By generalizing the mailing lists test helper module away from just XMLRPC, we |
70 |
>>> list_set.new(anne, anne) |
4419.6.3
by Barry Warsaw
More fleshing out of the mailing list database classes and doctest. |
71 |
Traceback (most recent call last): |
72 |
... |
|
73 |
AssertionError: Cannot register a list for a person who is not a team |
|
4419.6.1
by Barry Warsaw
Fleshed out the interface for IMailingList and IMailingListRegistry. Added |
74 |
|
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
75 |
The mailing list registrant must be a team owner or administrator. Anne is |
4543.2.14
by Barry Warsaw
Last round of response to Kiko's review. |
76 |
neither and thus may not create a list for team_two. |
77 |
||
4897.4.11
by Barry Warsaw
By generalizing the mailing lists test helper module away from just XMLRPC, we |
78 |
>>> list_set.new(team_two, anne) |
4543.2.14
by Barry Warsaw
Last round of response to Kiko's review. |
79 |
Traceback (most recent call last): |
80 |
... |
|
81 |
AssertionError: registrant is not a team owner or administrator |
|
82 |
||
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
83 |
However, if we make Anne a team owner, she can create the mailing list. |
4543.2.14
by Barry Warsaw
Last round of response to Kiko's review. |
84 |
|
11692.6.2
by Curtis Hovey
Use deglober to fixing simple glob imports in doctests. |
85 |
>>> from lp.registry.interfaces.teammembership import TeamMembershipStatus |
6130.6.3
by Maris Fogels
Rewrote the team join pages and the mailing list doctests to take the new behaviour into account. |
86 |
>>> login('foo.bar@canonical.com') |
7315.6.1
by Barry Warsaw
Refactor by moving mailinglists_helper.new_person -> |
87 |
>>> bart = factory.makePersonByName('Bart') |
10002.2.27
by Edwin Grubbs
Simplistic changes to ignore new return values for addMember() and setStatus(). |
88 |
>>> ignored = team_two.addMember( |
89 |
... anne, bart, status=TeamMembershipStatus.ADMIN) |
|
5126.3.25
by Edwin Grubbs
Fixed test failures |
90 |
>>> login(ANONYMOUS) |
4897.4.11
by Barry Warsaw
By generalizing the mailing lists test helper module away from just XMLRPC, we |
91 |
>>> list_two = list_set.new(team_two, anne) |
4543.2.14
by Barry Warsaw
Last round of response to Kiko's review. |
92 |
>>> list_two |
12043.6.3
by Curtis Hovey
Add address to mailing list repr. |
93 |
<MailingList for team "team-two"; status=APPROVED; ...> |
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
94 |
>>> print list_two.address |
95 |
team-two@lists.launchpad.dev |
|
4543.2.14
by Barry Warsaw
Last round of response to Kiko's review. |
96 |
|
4419.6.1
by Barry Warsaw
Fleshed out the interface for IMailingList and IMailingListRegistry. Added |
97 |
The newly registered mailing list is linked to its team, and the list's |
98 |
registrant is the team owner at the time the list was registered. The list's |
|
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
99 |
status is set to APPROVED. |
100 |
||
101 |
>>> print list_one.team.displayname |
|
102 |
Team One |
|
103 |
>>> print list_one.registrant.name |
|
104 |
no-priv |
|
105 |
>>> print list_one.status.name |
|
106 |
APPROVED |
|
107 |
||
108 |
The mailing list has no activation date or welcome message text yet. |
|
109 |
||
4419.6.3
by Barry Warsaw
More fleshing out of the mailing list database classes and doctest. |
110 |
>>> print list_one.date_activated |
111 |
None |
|
4419.6.7
by Barry Warsaw
Resolve the XXX about communicating welcome message changes to Mailman thusly: |
112 |
>>> print list_one.welcome_message |
4419.6.3
by Barry Warsaw
More fleshing out of the mailing list database classes and doctest. |
113 |
None |
4419.6.1
by Barry Warsaw
Fleshed out the interface for IMailingList and IMailingListRegistry. Added |
114 |
|
115 |
A mailing list cannot be registered more than once. |
|
116 |
||
4543.2.14
by Barry Warsaw
Last round of response to Kiko's review. |
117 |
>>> list_set.new(team_one) |
4419.6.3
by Barry Warsaw
More fleshing out of the mailing list database classes and doctest. |
118 |
Traceback (most recent call last): |
119 |
... |
|
120 |
AssertionError: Mailing list for team "team-one" already exists |
|
4419.6.1
by Barry Warsaw
Fleshed out the interface for IMailingList and IMailingListRegistry. Added |
121 |
|
122 |
||
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
123 |
Constructing mailing lists |
124 |
========================== |
|
4419.6.1
by Barry Warsaw
Fleshed out the interface for IMailingList and IMailingListRegistry. Added |
125 |
|
126 |
Once a team mailing list has been approved, it can be constructed by Mailman. |
|
127 |
This happens by returning the set of approved mailing lists through the XMLRPC |
|
128 |
interface used by Mailman (not shown here). When Mailman retrieves the set of |
|
129 |
mailing lists to construct, the list's statuses are set to the CONSTRUCTING |
|
130 |
state. |
|
131 |
||
4543.2.14
by Barry Warsaw
Last round of response to Kiko's review. |
132 |
>>> sorted_lists(list_set.approved_lists) |
12043.6.3
by Curtis Hovey
Add address to mailing list repr. |
133 |
[<MailingList for team "team-one"; status=APPROVED; ...>, |
134 |
<MailingList for team "team-two"; status=APPROVED; ...>] |
|
4419.6.3
by Barry Warsaw
More fleshing out of the mailing list database classes and doctest. |
135 |
|
4543.2.14
by Barry Warsaw
Last round of response to Kiko's review. |
136 |
>>> list_one.startConstructing() |
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
137 |
>>> print list_one.status.name |
138 |
CONSTRUCTING |
|
4419.6.1
by Barry Warsaw
Fleshed out the interface for IMailingList and IMailingListRegistry. Added |
139 |
|
140 |
Once in the construction phase, a list is no longer in the approval state. |
|
141 |
||
4543.2.14
by Barry Warsaw
Last round of response to Kiko's review. |
142 |
>>> sorted_lists(list_set.approved_lists) |
12043.6.3
by Curtis Hovey
Add address to mailing list repr. |
143 |
[<MailingList for team "team-two"; status=APPROVED; ...>] |
4419.6.1
by Barry Warsaw
Fleshed out the interface for IMailingList and IMailingListRegistry. Added |
144 |
|
145 |
Lists should never be constructed more than once. |
|
146 |
||
4543.2.14
by Barry Warsaw
Last round of response to Kiko's review. |
147 |
>>> list_one.startConstructing() |
4419.6.3
by Barry Warsaw
More fleshing out of the mailing list database classes and doctest. |
148 |
Traceback (most recent call last): |
149 |
... |
|
150 |
AssertionError: Only approved mailing lists may be constructed |
|
4419.6.1
by Barry Warsaw
Fleshed out the interface for IMailingList and IMailingListRegistry. Added |
151 |
|
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
152 |
Construct another list for later. |
153 |
||
154 |
>>> list_two.startConstructing() |
|
155 |
||
156 |
||
157 |
Reporting the results of construction |
|
158 |
===================================== |
|
4419.6.1
by Barry Warsaw
Fleshed out the interface for IMailingList and IMailingListRegistry. Added |
159 |
|
160 |
After Mailman has worked at constructing lists for a while, it reports (again |
|
161 |
through XMLRPC not shown here) on the status of each list construction. Most, |
|
4813.11.8
by Guilherme Salgado
Rewrite lots of things to be in accordance with mpt's design |
162 |
if not all will succeed, thus activating the team's mailing list. Also, once |
163 |
a mailing list is made active, its email address is registered in Launchpad |
|
164 |
and associated with the team's mailing list, so that it can be used as the |
|
165 |
team's contact address. |
|
4419.6.1
by Barry Warsaw
Fleshed out the interface for IMailingList and IMailingListRegistry. Added |
166 |
|
14538.1.2
by Curtis Hovey
Moved account and email address to lp.services.identity. |
167 |
>>> from lp.services.identity.interfaces.emailaddress import ( |
12043.6.3
by Curtis Hovey
Add address to mailing list repr. |
168 |
... IEmailAddressSet) |
4813.11.8
by Guilherme Salgado
Rewrite lots of things to be in accordance with mpt's design |
169 |
>>> email_set = getUtility(IEmailAddressSet) |
170 |
>>> print email_set.getByEmail(list_one.address) |
|
171 |
None |
|
5711.1.22
by Maris Fogels
Doctest style cleanup. |
172 |
>>> print list_one.date_activated |
173 |
None |
|
5711.1.12
by Maris Fogels
Added missing tests and functionality for the date_reviewed and date_activated attributes of MailingList. |
174 |
|
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
175 |
>>> from lp.registry.interfaces.mailinglist import MailingListStatus |
4543.2.16
by Barry Warsaw
On Kiko's suggestion, transitionState() -> transitionToStatus() for |
176 |
>>> list_one.transitionToStatus(MailingListStatus.ACTIVE) |
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
177 |
>>> print list_one.status.name |
178 |
ACTIVE |
|
179 |
>>> print email_set.getByEmail(list_one.address).status.name |
|
180 |
VALIDATED |
|
181 |
>>> from canonical.database.sqlbase import get_transaction_timestamp |
|
182 |
>>> transaction_timestamp = get_transaction_timestamp() |
|
5821.6.28
by James Henstridge
Fix some tests that depended on UTC_NOW not being converted to a real |
183 |
>>> list_one.date_activated == transaction_timestamp |
184 |
True |
|
5711.1.12
by Maris Fogels
Added missing tests and functionality for the date_reviewed and date_activated attributes of MailingList. |
185 |
|
4419.6.1
by Barry Warsaw
Fleshed out the interface for IMailingList and IMailingListRegistry. Added |
186 |
Some list constructions may fail. |
187 |
||
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
188 |
>>> list_two.transitionToStatus(MailingListStatus.FAILED) |
189 |
>>> print list_two.status.name |
|
190 |
FAILED |
|
4419.6.1
by Barry Warsaw
Fleshed out the interface for IMailingList and IMailingListRegistry. Added |
191 |
|
4419.6.11
by Barry Warsaw
Change getTeamMailingList() to now take a team name instead of an IPerson |
192 |
You can then get the mailing list for a team, given the team name. |
193 |
||
4543.2.14
by Barry Warsaw
Last round of response to Kiko's review. |
194 |
>>> list_set.get(team_one.name) |
12043.6.3
by Curtis Hovey
Add address to mailing list repr. |
195 |
<MailingList for team "team-one"; status=ACTIVE; ...> |
4543.2.14
by Barry Warsaw
Last round of response to Kiko's review. |
196 |
>>> list_set.get(team_two.name) |
12043.6.3
by Curtis Hovey
Add address to mailing list repr. |
197 |
<MailingList for team "team-two"; status=FAILED; ...> |
4419.6.11
by Barry Warsaw
Change getTeamMailingList() to now take a team name instead of an IPerson |
198 |
|
199 |
This method will return None for missing teams or non-team people. |
|
200 |
||
4543.2.14
by Barry Warsaw
Last round of response to Kiko's review. |
201 |
>>> print list_set.get('not an existing team') |
4419.6.11
by Barry Warsaw
Change getTeamMailingList() to now take a team name instead of an IPerson |
202 |
None |
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
203 |
>>> print list_set.get('salgado') |
4419.6.11
by Barry Warsaw
Change getTeamMailingList() to now take a team name instead of an IPerson |
204 |
None |
205 |
||
4419.6.1
by Barry Warsaw
Fleshed out the interface for IMailingList and IMailingListRegistry. Added |
206 |
|
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
207 |
Deactivating lists |
208 |
================== |
|
4419.6.1
by Barry Warsaw
Fleshed out the interface for IMailingList and IMailingListRegistry. Added |
209 |
|
210 |
A list which is active may be deactivated. |
|
211 |
||
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
212 |
>>> team_three = new_team('team-three') |
213 |
>>> list_three = list_set.new(team_three) |
|
214 |
>>> list_three.startConstructing() |
|
215 |
>>> list_three.transitionToStatus(MailingListStatus.ACTIVE) |
|
216 |
>>> transaction.commit() |
|
217 |
||
218 |
>>> login_person(team_three.teamowner) |
|
4419.6.3
by Barry Warsaw
More fleshing out of the mailing list database classes and doctest. |
219 |
>>> list_three.deactivate() |
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
220 |
>>> print list_three.status.name |
221 |
DEACTIVATING |
|
4419.6.9
by Barry Warsaw
Handle the situation where a list has been requested for deactivation, and |
222 |
|
223 |
This doesn't immediately deactivate the mailing list though. Mailman still |
|
224 |
needs to query for the requested deactivations, take the necessary actions, |
|
225 |
and report the deactivation results. |
|
226 |
||
4543.2.14
by Barry Warsaw
Last round of response to Kiko's review. |
227 |
>>> sorted_lists(list_set.deactivated_lists) |
12043.6.3
by Curtis Hovey
Add address to mailing list repr. |
228 |
[<MailingList for team "team-three"; status=DEACTIVATING; ...>] |
4543.2.16
by Barry Warsaw
On Kiko's suggestion, transitionState() -> transitionToStatus() for |
229 |
>>> list_three.transitionToStatus(MailingListStatus.INACTIVE) |
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
230 |
>>> print list_three.status.name |
231 |
INACTIVE |
|
232 |
||
233 |
Once a list's deactivation is complete, the status of its email address is set |
|
234 |
to NEW. |
|
235 |
||
236 |
>>> print email_set.getByEmail(list_three.address).status.name |
|
237 |
NEW |
|
4813.11.16
by Guilherme Salgado
Some final changes suggested by Barry |
238 |
|
4419.6.1
by Barry Warsaw
Fleshed out the interface for IMailingList and IMailingListRegistry. Added |
239 |
But lists which are not active may not be deactivated. |
240 |
||
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
241 |
>>> list_three.deactivate() |
242 |
Traceback (most recent call last): |
|
243 |
... |
|
244 |
AssertionError: Only active mailing lists may be deactivated |
|
4419.6.1
by Barry Warsaw
Fleshed out the interface for IMailingList and IMailingListRegistry. Added |
245 |
>>> list_two.deactivate() |
4419.6.3
by Barry Warsaw
More fleshing out of the mailing list database classes and doctest. |
246 |
Traceback (most recent call last): |
247 |
... |
|
248 |
AssertionError: Only active mailing lists may be deactivated |
|
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
249 |
|
250 |
||
251 |
Reactivating lists |
|
252 |
================== |
|
4927.1.1
by Guilherme Salgado
Add a reactivate() method to IMailingList to allow inactive MLs to be reactivated. |
253 |
|
254 |
A list which is inactive may be reactivated. |
|
255 |
||
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
256 |
>>> print list_three.status.name |
257 |
INACTIVE |
|
4927.1.1
by Guilherme Salgado
Add a reactivate() method to IMailingList to allow inactive MLs to be reactivated. |
258 |
>>> list_three.reactivate() |
259 |
||
260 |
This doesn't immediately reactivate the mailing list though. Mailman still |
|
261 |
needs to query for the requested reactivations, take the necessary actions, |
|
262 |
and report the reactivation results. |
|
263 |
||
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
264 |
>>> print list_three.status.name |
265 |
APPROVED |
|
4927.1.1
by Guilherme Salgado
Add a reactivate() method to IMailingList to allow inactive MLs to be reactivated. |
266 |
|
267 |
But lists which are not inactive may not be reactivated. |
|
268 |
||
269 |
>>> list_three.reactivate() |
|
270 |
Traceback (most recent call last): |
|
271 |
... |
|
272 |
AssertionError: Only inactive mailing lists may be reactivated |
|
273 |
||
274 |
||
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
275 |
Mailing list permissions |
276 |
======================== |
|
5084.12.9
by Leonard Richardson
Added a test for the new security check on mailing lists. |
277 |
|
5127.3.5
by Leonard Richardson
Simplified form, permissions, and field-building code. |
278 |
Permissions on a team's mailing list are not tracked separately from |
279 |
permissions on the team. |
|
5084.12.13
by Leonard Richardson
Still more miscellaneous cleanup. |
280 |
|
11118.2.2
by Brad Crittenden
Fixed failing tests due to removal of PMTs |
281 |
You cannot turn a team with a mailing list into a private team. |
6514.1.1
by Barry Warsaw
Allow private teams to have mailing lists. |
282 |
|
283 |
>>> from zope.component import queryAdapter |
|
284 |
>>> from canonical.lazr.interfaces.objectprivacy import IObjectPrivacy |
|
7675.110.3
by Curtis Hovey
Ran the migration script to move registry code to lp.registry. |
285 |
>>> from lp.registry.interfaces.person import PersonVisibility |
6514.1.1
by Barry Warsaw
Allow private teams to have mailing lists. |
286 |
>>> queryAdapter(team_one, IObjectPrivacy).is_private |
287 |
False |
|
288 |
>>> login('foo.bar@canonical.com') |
|
11118.2.2
by Brad Crittenden
Fixed failing tests due to removal of PMTs |
289 |
>>> team_one.visibility = PersonVisibility.PRIVATE |
6514.1.1
by Barry Warsaw
Allow private teams to have mailing lists. |
290 |
Traceback (most recent call last): |
291 |
... |
|
8620.2.7
by Brad Crittenden
Fixed test errors. |
292 |
ImmutableVisibilityError: This team cannot be converted to |
11118.2.2
by Brad Crittenden
Fixed failing tests due to removal of PMTs |
293 |
Private since it is referenced by a mailing list. |
6514.1.1
by Barry Warsaw
Allow private teams to have mailing lists. |
294 |
|
11118.2.2
by Brad Crittenden
Fixed failing tests due to removal of PMTs |
295 |
However, you can give a private team a mailing list. |
6514.1.1
by Barry Warsaw
Allow private teams to have mailing lists. |
296 |
|
297 |
>>> thereminists = new_team('thereminists') |
|
298 |
>>> queryAdapter(thereminists, IObjectPrivacy).is_private |
|
299 |
False |
|
11118.2.2
by Brad Crittenden
Fixed failing tests due to removal of PMTs |
300 |
>>> thereminists.visibility = PersonVisibility.PRIVATE |
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
301 |
|
6514.1.1
by Barry Warsaw
Allow private teams to have mailing lists. |
302 |
>>> queryAdapter(thereminists, IObjectPrivacy).is_private |
303 |
True |
|
7675.110.3
by Curtis Hovey
Ran the migration script to move registry code to lp.registry. |
304 |
>>> from lp.registry.tests.mailinglists_helper import ( |
6514.1.1
by Barry Warsaw
Allow private teams to have mailing lists. |
305 |
... new_list_for_team) |
306 |
>>> thereminists_list = new_list_for_team(thereminists) |
|
307 |
>>> thereminists_list |
|
12043.6.3
by Curtis Hovey
Add address to mailing list repr. |
308 |
<MailingList for team "thereminists"; status=ACTIVE; ...> |
6514.1.1
by Barry Warsaw
Allow private teams to have mailing lists. |
309 |
|
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
310 |
Welcome messages |
311 |
================ |
|
4419.6.1
by Barry Warsaw
Fleshed out the interface for IMailingList and IMailingListRegistry. Added |
312 |
|
313 |
Mailing lists have a welcome message text which is sent to new members when |
|
4419.6.7
by Barry Warsaw
Resolve the XXX about communicating welcome message changes to Mailman thusly: |
314 |
they subscribe to a list. The welcome message can contain any text. |
4419.6.1
by Barry Warsaw
Fleshed out the interface for IMailingList and IMailingListRegistry. Added |
315 |
|
4419.6.7
by Barry Warsaw
Resolve the XXX about communicating welcome message changes to Mailman thusly: |
316 |
>>> print list_one.welcome_message |
317 |
None |
|
318 |
>>> list_one.welcome_message = """\ |
|
4419.6.1
by Barry Warsaw
Fleshed out the interface for IMailingList and IMailingListRegistry. Added |
319 |
... Welcome to the Team One mailing list.""" |
5127.3.8
by Leonard Richardson
Perform mailing list tasks when logged in as an authorized user. |
320 |
>>> login(ANONYMOUS) |
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
321 |
>>> print list_one.welcome_message |
322 |
Welcome to the Team One mailing list. |
|
4419.6.7
by Barry Warsaw
Resolve the XXX about communicating welcome message changes to Mailman thusly: |
323 |
|
324 |
After changing the welcome message, the list's status should be MODIFIED. |
|
325 |
||
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
326 |
>>> print list_one.status.name |
327 |
MODIFIED |
|
4543.2.14
by Barry Warsaw
Last round of response to Kiko's review. |
328 |
>>> sorted_lists(list_set.modified_lists) |
12043.6.3
by Curtis Hovey
Add address to mailing list repr. |
329 |
[<MailingList for team "team-one"; status=MODIFIED; ...>] |
4419.6.7
by Barry Warsaw
Resolve the XXX about communicating welcome message changes to Mailman thusly: |
330 |
|
4483.4.20
by Barry Warsaw
Addressed BjornT's review comments. |
331 |
Eventually, Mailman will get around to acting on this modification. When it |
332 |
does so, the list's state transitions first to UPDATING so as to avoid |
|
333 |
multiple modifications. Transitioning to the ACTIVE state while still |
|
334 |
MODIFIED is not allowed. |
|
335 |
||
336 |
>>> list_one.transitionToStatus(MailingListStatus.ACTIVE) |
|
337 |
Traceback (most recent call last): |
|
338 |
... |
|
4813.11.8
by Guilherme Salgado
Rewrite lots of things to be in accordance with mpt's design |
339 |
AssertionError: Not a valid state transition: Modified -> Active |
4483.4.20
by Barry Warsaw
Addressed BjornT's review comments. |
340 |
|
341 |
What really happens is that the list's state is first transitioned to |
|
342 |
UPDATING, and then to ACTIVE or FAILED. |
|
343 |
||
344 |
>>> list_one.startUpdating() |
|
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
345 |
>>> print list_one.status.name |
346 |
UPDATING |
|
4543.2.16
by Barry Warsaw
On Kiko's suggestion, transitionState() -> transitionToStatus() for |
347 |
>>> list_one.transitionToStatus(MailingListStatus.ACTIVE) |
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
348 |
>>> print list_one.status.name |
349 |
ACTIVE |
|
4419.6.10
by Barry Warsaw
Allow REGISTERED mailing lists to have their welcome_message text modified. |
350 |
|
4419.6.7
by Barry Warsaw
Resolve the XXX about communicating welcome message changes to Mailman thusly: |
351 |
You cannot change the welcome message text for a mailing list in anything but |
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
352 |
the ACTIVE status. |
4419.6.7
by Barry Warsaw
Resolve the XXX about communicating welcome message changes to Mailman thusly: |
353 |
|
5127.3.8
by Leonard Richardson
Perform mailing list tasks when logged in as an authorized user. |
354 |
>>> login('foo.bar@canonical.com') |
4419.6.7
by Barry Warsaw
Resolve the XXX about communicating welcome message changes to Mailman thusly: |
355 |
>>> list_two.welcome_message = """\ |
356 |
... This list has been declined.""" |
|
357 |
Traceback (most recent call last): |
|
358 |
... |
|
9965.7.4
by Barry Warsaw
More test repair. |
359 |
AssertionError: Only usable mailing lists may be modified |
4419.6.7
by Barry Warsaw
Resolve the XXX about communicating welcome message changes to Mailman thusly: |
360 |
|
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
361 |
>>> list_three.welcome_message = """\ |
4419.6.7
by Barry Warsaw
Resolve the XXX about communicating welcome message changes to Mailman thusly: |
362 |
... This list has been deactivated.""" |
363 |
Traceback (most recent call last): |
|
364 |
... |
|
9965.7.4
by Barry Warsaw
More test repair. |
365 |
AssertionError: Only usable mailing lists may be modified |
5138.8.1
by Barry Warsaw
Implementation of blueprint team-mailing-lists-restrict-team-rename. |
366 |
|
367 |
||
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
368 |
Renaming teams with mailing lists |
369 |
================================= |
|
5138.8.1
by Barry Warsaw
Implementation of blueprint team-mailing-lists-restrict-team-rename. |
370 |
|
371 |
A team that has a mailing list may not be renamed. |
|
372 |
||
373 |
>>> login('no-priv@canonical.com') |
|
374 |
>>> team_one.name = 'team-canonical' |
|
375 |
Traceback (most recent call last): |
|
376 |
... |
|
377 |
AssertionError: Cannot rename teams with mailing lists |
|
378 |
||
379 |
But a team with no mailing list (yet) can still be renamed. |
|
380 |
||
381 |
>>> team_six = new_team('team-six') |
|
382 |
>>> team_six.name = 'team-canonical' |
|
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
383 |
>>> print team_six.name |
384 |
team-canonical |
|
385 |
||
386 |
||
387 |
Team archive links |
|
388 |
================== |
|
5256.1.1
by Barry Warsaw
Implementation and tests for team-mailing-lists-archiving blueprint: |
389 |
|
5256.1.2
by Barry Warsaw
Changes in response to jml's review: |
390 |
Mailing lists have archives, accessible through a list-specific url. However, |
391 |
if a mailing list has never be activated, it won't have an archive url. |
|
392 |
||
393 |
>>> print list_two.archive_url |
|
394 |
None |
|
395 |
||
396 |
An active mailing list has an archive url. |
|
5256.1.1
by Barry Warsaw
Implementation and tests for team-mailing-lists-archiving blueprint: |
397 |
|
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
398 |
>>> print list_one.status.name |
399 |
ACTIVE |
|
400 |
>>> print list_one.archive_url |
|
401 |
http://lists.launchpad.dev/team-one |
|
5256.1.2
by Barry Warsaw
Changes in response to jml's review: |
402 |
|
403 |
Inactive mailing lists also have an archive url, because once activated, a |
|
404 |
mailing list could have an archive and archives are never deleted. |
|
405 |
||
5256.1.1
by Barry Warsaw
Implementation and tests for team-mailing-lists-archiving blueprint: |
406 |
>>> list_one.deactivate() |
407 |
>>> list_one.transitionToStatus(MailingListStatus.INACTIVE) |
|
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
408 |
>>> print list_one.status.name |
409 |
INACTIVE |
|
410 |
>>> print list_one.archive_url |
|
411 |
http://lists.launchpad.dev/team-one |
|
412 |
||
413 |
||
414 |
Events |
|
415 |
====== |
|
5711.1.1
by Maris Fogels
Added a failing doctest for the mailing list availability event. |
416 |
|
5711.1.19
by Maris Fogels
Clarified some doctest narratives. |
417 |
Activating the mailing list (changing it's status to 'available for |
7876.3.6
by Francis J. Lacoste
Used ISQLObject from lazr.lifecycle |
418 |
subscription') will fire an instance of the ObjectModifiedEvent. |
5711.1.1
by Maris Fogels
Added a failing doctest for the mailing list availability event. |
419 |
|
420 |
# Register an event listener that will print event it receives. |
|
14560.2.10
by Curtis Hovey
Removed shim. |
421 |
>>> from canonical.lazr.testing.event import TestEventListener |
7876.3.14
by Francis J. Lacoste
Review comments. |
422 |
>>> from lazr.lifecycle.interfaces import IObjectModifiedEvent |
11692.6.2
by Curtis Hovey
Use deglober to fixing simple glob imports in doctests. |
423 |
>>> from lp.registry.interfaces.mailinglist import IMailingList |
5711.1.1
by Maris Fogels
Added a failing doctest for the mailing list availability event. |
424 |
>>> def print_event(object, event): |
425 |
... print "Received %s on %s" % ( |
|
426 |
... event.__class__.__name__.split('.')[-1], |
|
427 |
... object.__class__.__name__.split('.')[-1]) |
|
428 |
>>> mailinglist_event_listener = TestEventListener( |
|
7876.3.6
by Francis J. Lacoste
Used ISQLObject from lazr.lifecycle |
429 |
... IMailingList, IObjectModifiedEvent, print_event) |
5711.1.1
by Maris Fogels
Added a failing doctest for the mailing list availability event. |
430 |
|
431 |
||
432 |
# We need to build a new mailing list to use in our tests |
|
433 |
>>> list_six = list_set.new(team_six) |
|
434 |
>>> list_six.startConstructing() |
|
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
435 |
>>> print list_six.status.name |
436 |
CONSTRUCTING |
|
5711.1.1
by Maris Fogels
Added a failing doctest for the mailing list availability event. |
437 |
|
438 |
>>> list_six.transitionToStatus(MailingListStatus.ACTIVE) |
|
7876.3.6
by Francis J. Lacoste
Used ISQLObject from lazr.lifecycle |
439 |
Received ObjectModifiedEvent on MailingList |
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
440 |
>>> print list_six.status.name |
441 |
ACTIVE |
|
5711.1.1
by Maris Fogels
Added a failing doctest for the mailing list availability event. |
442 |
|
443 |
# Cleanup |
|
444 |
>>> mailinglist_event_listener.unregister() |
|
6815.1.1
by Barry Warsaw
Add IMailingList.purge() which, while not deleting the mailing list, makes it |
445 |
|
446 |
||
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
447 |
Purging |
448 |
======= |
|
6815.1.1
by Barry Warsaw
Add IMailingList.purge() which, while not deleting the mailing list, makes it |
449 |
|
450 |
There are times when we want to perform certain actions that normally are |
|
451 |
unsafe to do when a team has a mailing list. For example, we might want to |
|
452 |
merge a team with a mailing list into another team, or we might want to allow |
|
453 |
a team owner to re-request a mailing list that was incorrectly declined. |
|
454 |
||
455 |
In order to support this, mailing lists have a PURGED state. Purging a |
|
456 |
mailing list on the Launchpad side performs no communication with Mailman; the |
|
457 |
Launchpad administrator must ensure that all associated state is purged from |
|
458 |
Mailman (which is aided by the use of a script to be run on that server). On |
|
459 |
Launchpad, only a Launchpad administrator or mailing list expert may purge a |
|
460 |
list, and then only if the list is already in one of the safe-to-purge states. |
|
461 |
||
462 |
A list in the active state is not safe to purge. |
|
463 |
||
464 |
>>> print list_six.status.name |
|
465 |
ACTIVE |
|
466 |
>>> list_six.purge() |
|
467 |
Traceback (most recent call last): |
|
468 |
UnsafeToPurge: Cannot purge mailing list in ACTIVE state: team-canonical |
|
469 |
||
470 |
By deactivating the mailing list, we make it safe to purge. |
|
471 |
||
7675.85.2
by Jonathan Lange
Undo revision generated by step 2 of process. |
472 |
>>> # Need to commit, or security checks fail because team isn't yet |
473 |
>>> # available via the auth Store yet. |
|
474 |
>>> import transaction |
|
475 |
>>> transaction.commit() |
|
6815.1.1
by Barry Warsaw
Add IMailingList.purge() which, while not deleting the mailing list, makes it |
476 |
>>> list_six.deactivate() |
477 |
>>> list_six.transitionToStatus(MailingListStatus.INACTIVE) |
|
478 |
>>> print list_six.status.name |
|
479 |
INACTIVE |
|
480 |
>>> list_six.purge() |
|
481 |
>>> print list_six.status.name |
|
482 |
PURGED |
|
483 |
||
484 |
It's as if the mailing list never existed, so we can re-request that the list |
|
485 |
be created. |
|
486 |
||
487 |
>>> list_six = list_set.new(team_six) |
|
488 |
>>> print list_six.team.name |
|
489 |
team-canonical |
|
490 |
>>> print list_six.date_activated |
|
491 |
None |
|
492 |
>>> print list_six.status.name |
|
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
493 |
APPROVED |
6815.1.1
by Barry Warsaw
Add IMailingList.purge() which, while not deleting the mailing list, makes it |
494 |
>>> print list_six.welcome_message |
495 |
None |
|
496 |
||
9965.7.2
by Barry Warsaw
Get rid of the top-level +mailinglists url and fix the test failure fallout. |
497 |
A list that has been approved, or is being constructed cannot be purged. |
6815.1.1
by Barry Warsaw
Add IMailingList.purge() which, while not deleting the mailing list, makes it |
498 |
|
6821.6.7
by Barry Warsaw
Fixes in response to celso's review. |
499 |
>>> import transaction |
6815.1.1
by Barry Warsaw
Add IMailingList.purge() which, while not deleting the mailing list, makes it |
500 |
>>> from zope.security.proxy import removeSecurityProxy |
6821.6.7
by Barry Warsaw
Fixes in response to celso's review. |
501 |
>>> naked_list = removeSecurityProxy(list_six) |
502 |
>>> naked_list.status = MailingListStatus.APPROVED |
|
6815.1.1
by Barry Warsaw
Add IMailingList.purge() which, while not deleting the mailing list, makes it |
503 |
>>> transaction.commit() |
12651.1.14
by Curtis Hovey
No not try to delete the mailing list address if it does not exist. |
504 |
>>> login(ANONYMOUS) |
6815.1.1
by Barry Warsaw
Add IMailingList.purge() which, while not deleting the mailing list, makes it |
505 |
>>> print list_six.status.name |
506 |
APPROVED |
|
507 |
>>> list_six.purge() |
|
508 |
Traceback (most recent call last): |
|
509 |
... |
|
510 |
UnsafeToPurge: Cannot purge mailing list in APPROVED state: team-canonical |
|
511 |
||
6821.6.7
by Barry Warsaw
Fixes in response to celso's review. |
512 |
>>> naked_list.status = MailingListStatus.CONSTRUCTING |
6815.1.1
by Barry Warsaw
Add IMailingList.purge() which, while not deleting the mailing list, makes it |
513 |
>>> transaction.commit() |
514 |
>>> print list_six.status.name |
|
515 |
CONSTRUCTING |
|
516 |
>>> list_six.purge() |
|
517 |
Traceback (most recent call last): |
|
518 |
... |
|
519 |
UnsafeToPurge: Cannot purge mailing list in CONSTRUCTING state: ... |
|
520 |
||
521 |
A list in the FAILED state can be purged, but a list in the MOD_FAILED state |
|
522 |
cannot. This is because the latter still means that a mailing list is active |
|
523 |
for the team. |
|
524 |
||
6821.6.7
by Barry Warsaw
Fixes in response to celso's review. |
525 |
>>> naked_list.status = MailingListStatus.FAILED |
6815.1.1
by Barry Warsaw
Add IMailingList.purge() which, while not deleting the mailing list, makes it |
526 |
>>> transaction.commit() |
527 |
>>> print list_six.status.name |
|
528 |
FAILED |
|
529 |
>>> list_six.purge() |
|
530 |
>>> print list_six.status.name |
|
531 |
PURGED |
|
532 |
||
6821.6.7
by Barry Warsaw
Fixes in response to celso's review. |
533 |
>>> naked_list.status = MailingListStatus.MOD_FAILED |
6815.1.1
by Barry Warsaw
Add IMailingList.purge() which, while not deleting the mailing list, makes it |
534 |
>>> transaction.commit() |
535 |
>>> print list_six.status.name |
|
536 |
MOD_FAILED |
|
537 |
>>> list_six.purge() |
|
538 |
Traceback (most recent call last): |
|
539 |
... |
|
540 |
UnsafeToPurge: Cannot purge mailing list in MOD_FAILED state: ... |
|
541 |
||
542 |
Modified, updating, and deactivating mailing lists are also unsafe to purge. |
|
543 |
||
6821.6.7
by Barry Warsaw
Fixes in response to celso's review. |
544 |
>>> naked_list.status = MailingListStatus.MODIFIED |
6815.1.1
by Barry Warsaw
Add IMailingList.purge() which, while not deleting the mailing list, makes it |
545 |
>>> transaction.commit() |
546 |
>>> print list_six.status.name |
|
547 |
MODIFIED |
|
548 |
>>> list_six.purge() |
|
549 |
Traceback (most recent call last): |
|
550 |
... |
|
551 |
UnsafeToPurge: Cannot purge mailing list in MODIFIED state: team-canonical |
|
552 |
||
6821.6.7
by Barry Warsaw
Fixes in response to celso's review. |
553 |
>>> naked_list.status = MailingListStatus.UPDATING |
6815.1.1
by Barry Warsaw
Add IMailingList.purge() which, while not deleting the mailing list, makes it |
554 |
>>> transaction.commit() |
555 |
>>> print list_six.status.name |
|
556 |
UPDATING |
|
557 |
>>> list_six.purge() |
|
558 |
Traceback (most recent call last): |
|
559 |
... |
|
560 |
UnsafeToPurge: Cannot purge mailing list in UPDATING state: team-canonical |
|
561 |
||
6821.6.7
by Barry Warsaw
Fixes in response to celso's review. |
562 |
>>> naked_list.status = MailingListStatus.DEACTIVATING |
6815.1.1
by Barry Warsaw
Add IMailingList.purge() which, while not deleting the mailing list, makes it |
563 |
>>> transaction.commit() |
564 |
>>> print list_six.status.name |
|
565 |
DEACTIVATING |
|
566 |
>>> list_six.purge() |
|
567 |
Traceback (most recent call last): |
|
568 |
... |
|
569 |
UnsafeToPurge: Cannot purge mailing list in DEACTIVATING state: ... |
|
570 |
||
571 |
You should never be able to purge an already purged mailing list. |
|
572 |
||
6821.6.7
by Barry Warsaw
Fixes in response to celso's review. |
573 |
>>> naked_list.status = MailingListStatus.PURGED |
6815.1.1
by Barry Warsaw
Add IMailingList.purge() which, while not deleting the mailing list, makes it |
574 |
>>> transaction.commit() |
575 |
>>> print list_six.status.name |
|
576 |
PURGED |
|
577 |
>>> list_six.purge() |
|
578 |
Traceback (most recent call last): |
|
579 |
... |
|
580 |
AssertionError: Already purged |